1/* Copyright (c) 2005 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 * 21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22 * contributors may be used to endorse or promote products derived from this 23 * software without specific prior written permission. 24 * */ 25 26/* 27 * File Contents: This file contains platform dependent functions 28 * which provide interface to that platform. 29 * 30 * SubModule: Geode FlatPanel library 31 * */ 32 33#define LINUX_ROM_SEGMENT 0x000F 34#define SEGMENT_LENGTH 0xFFFF 35#define PAGE_LENGTH 0x1000 36#define SYS_BOARD_NAME_LEN 24 37 38#define PLT_UNKNOWN 0xFFFF 39 40typedef struct { 41 char sys_board_name[SYS_BOARD_NAME_LEN]; 42 SYS_BOARD sys_board; 43} SYS_BOARD_INFO; 44 45static SYS_BOARD_INFO Sys_info; 46 47/* 48 * The names in the sys_board_name string must exactly match the names in the 49 * BIOS header. These names are used by FindStringInSeg() to find the names 50 * in the BIOS header space. The BIOS does not use OTHER; it is a dummy value 51 * for program useonly. 52 */ 53 54SYS_BOARD_INFO Sys_board_info_array[] = { 55 {"Marmot", MARMOT_PLATFORM}, 56 {"Unicorn", UNICORN_PLATFORM}, 57 {"Centaurus", CENTAURUS_PLATFORM}, 58 {"Aries", ARIES_PLATFORM}, 59 {"Carmel", CARMEL_PLATFORM}, 60 {"Hyrda", HYDRA_PLATFORM}, 61 {"Dorado", DORADO_PLATFORM}, 62 {"Redcloud", REDCLOUD_PLATFORM}, 63 {"Other", OTHER_PLATFORM} 64}; 65 66#define NUM_SYS_BOARD_TYPES \ 67 sizeof(Sys_board_info_array)/sizeof(SYS_BOARD_INFO) 68 69static int Num_sys_board_type = NUM_SYS_BOARD_TYPES; 70SYS_BOARD_INFO *Sys_board_array_base = Sys_board_info_array; 71int FindStringInSeg(unsigned int, char *); 72static unsigned char get_sys_board_type(SYS_BOARD_INFO *, SYS_BOARD_INFO *); 73 74/* Detect the Platform */ 75int 76Detect_Platform(void) 77{ 78 /* See if we can find the board name using Xpressrom */ 79 get_sys_board_type(&Sys_info, Sys_board_array_base); 80 return (Sys_info.sys_board); 81} 82 83static int 84Strncmp(char *str1, char *str2, int len) 85{ 86 int i; 87 88 if ((str1 == 0x0) || (str2 == 0x0) || (len == 0)) 89 return (1); 90 for (i = 0; i < len; i++) { 91 if (*(str1 + i) > *(str2 + i)) { 92 return 1; 93 } 94 else if (*(str1 + i) < *(str2 + i)) { 95 return -1; 96 } 97 } 98 return 0; 99} 100 101static char * 102Strcpy(char *dst, char *src) 103{ 104 int i; 105 106 if ((dst == 0x0) || (src == 0x0)) 107 return (0); 108 for (i = 0; src[i] != 0x0; i++) { 109 dst[i] = src[i]; 110 } 111 dst[i] = 0x0; /* NULL termination */ 112 return dst; 113} 114 115static int 116Strlen(char *str) 117{ 118 int i; 119 120 if (str == 0x0) 121 return 0; 122 for (i = 0; str[i] != 0x0; i++); 123 return i; 124} 125 126/* Platform Detection Code */ 127 128/************************************************************************ 129 * int FindStringInSeg( unsigned int segment_address, char *string_ptr ) 130 * 131 * Returns the offset where the NULL terminated string pointed to by 132 * string_ptr is located in the segment passed in segment_address. 133 * Segment_address must be of the form 0xXXXX (i.e 0xf000 for segment f). 134 * Returns NULL if the string is not found. 135 ************************************************************************ 136 */ 137int 138FindStringInSeg(unsigned int segment_address, char *string_ptr) 139{ 140 int string_length = Strlen(string_ptr); 141 char *psegment_buf; 142 unsigned long mem_ptr = (unsigned long) segment_address << 16; 143 unsigned int i; 144 145 /* silence compiler */ 146 (void) mem_ptr; 147 148 psegment_buf = (char *) XpressROMPtr; 149 150 /* Now search for the first character of the string_ptr */ 151 for (i = 0; i < SEGMENT_LENGTH + 1; i++) { 152 if (*(psegment_buf + i) == *string_ptr) { 153 154 /* If we match the first character, do a 155 * string compare. 156 */ 157 158 if (!Strncmp(string_ptr, (psegment_buf + i), string_length)) { 159 /* They match! */ 160 return (1); 161 } 162 } 163 } 164 /* if we got this far we didn't find anything. Return NULL. */ 165 return (0); 166 167} /* end FindStringInSeg() */ 168 169/********************************************************************** 170 171 * TRUE_FALSE get_sys_board_type( SYS_BOARD_INFO *sys_info, 172 * SYS_BOARD_INFO *sys_board_array_base) 173 * 174 * Checks the system BIOS area for Xpressrom information. If found, searches 175 * the BIOS area for one of names in the array pointed to by 176 * sys_board_array_ptr. 177 * If a match is found, sets the SYS_INFO system_board_name string 178 * and the system_board variable to the board name and returns TRUE. 179 * If Xpressrom or a board is not found, sets the variables to 180 * their default values and returns FALSE. 181 * Uses the global string pointer *xpress_rom_string_ptr. 182 *********************************************************************** 183 */ 184static unsigned char 185get_sys_board_type(SYS_BOARD_INFO * sys_info, 186 SYS_BOARD_INFO * sys_board_array_base) 187{ 188 int index; 189 char *xpress_rom_string_ptr = "XpressStart"; 190 unsigned int segment = LINUX_ROM_SEGMENT; 191 192 /* See if XpressStart is present in the BIOS area. 193 * If it is, search for a board string. If not, Xpressrom is 194 * not present, set system_board information to UNKNOWN and 195 * return FALSE. 196 */ 197 198 if (!FindStringInSeg(segment, xpress_rom_string_ptr)) { 199 sys_info->sys_board = PLT_UNKNOWN; 200 Strcpy(sys_info->sys_board_name, "Unknown"); 201 return (FALSE); 202 } 203 else { 204 205 /* we have Xpressrom, so look for a board */ 206 for (index = 0; index < Num_sys_board_type; index++) { 207 if (!FindStringInSeg(segment, (sys_board_array_base + 208 index)->sys_board_name)) { 209 continue; 210 } 211 else { 212 213 /* a match!! */ 214 sys_info->sys_board = (sys_board_array_base + index)->sys_board; 215 Strcpy(sys_info->sys_board_name, 216 (sys_board_array_base + index)->sys_board_name); 217 return (TRUE); 218 } 219 } /* end for() */ 220 } /* end else */ 221 222 /* if we are here we have failed */ 223 sys_info->sys_board = PLT_UNKNOWN; 224 Strcpy(sys_info->sys_board_name, "Unknown"); 225 return (FALSE); 226} /* end get_sys_board_type() */ 227