platform.c revision f29dbc25
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 34#define LINUX_ROM_SEGMENT 0x000F 35#define SEGMENT_LENGTH 0xFFFF 36#define PAGE_LENGTH 0x1000 37#define SYS_BOARD_NAME_LEN 24 38 39#define PLT_UNKNOWN 0xFFFF 40 41typedef struct 42{ 43 char sys_board_name[SYS_BOARD_NAME_LEN]; 44 SYS_BOARD sys_board; 45} 46SYS_BOARD_INFO; 47 48static SYS_BOARD_INFO Sys_info; 49 50/* 51 * The names in the sys_board_name string must exactly match the names in the 52 * BIOS header. These names are used by FindStringInSeg() to find the names 53 * in the BIOS header space. The BIOS does not use OTHER; it is a dummy value 54 * for program useonly. 55 */ 56 57SYS_BOARD_INFO Sys_board_info_array[] = { 58 {"Marmot", MARMOT_PLATFORM}, 59 {"Unicorn", UNICORN_PLATFORM}, 60 {"Centaurus", CENTAURUS_PLATFORM}, 61 {"Aries", ARIES_PLATFORM}, 62 {"Carmel", CARMEL_PLATFORM}, 63 {"Hyrda", HYDRA_PLATFORM}, 64 {"Dorado", DORADO_PLATFORM}, 65 {"Redcloud", REDCLOUD_PLATFORM}, 66 {"Other", OTHER_PLATFORM} 67}; 68 69#define NUM_SYS_BOARD_TYPES \ 70 sizeof(Sys_board_info_array)/sizeof(SYS_BOARD_INFO) 71 72static int Num_sys_board_type = NUM_SYS_BOARD_TYPES; 73SYS_BOARD_INFO *Sys_board_array_base = Sys_board_info_array; 74int FindStringInSeg(unsigned int, char *); 75static unsigned char get_sys_board_type(SYS_BOARD_INFO *, SYS_BOARD_INFO *); 76 77/* Detect the Platform */ 78int 79Detect_Platform(void) 80{ 81 /* See if we can find the board name using Xpressrom */ 82 get_sys_board_type(&Sys_info, Sys_board_array_base); 83 return (Sys_info.sys_board); 84} 85 86static int 87Strncmp(char *str1, char *str2, int len) 88{ 89 int i; 90 91 if ((str1 == 0x0) || (str2 == 0x0) || (len == 0)) 92 return (1); 93 for (i = 0; i < len; i++) { 94 if (*(str1 + i) > *(str2 + i)) { 95 return 1; 96 } else if (*(str1 + i) < *(str2 + i)) { 97 return -1; 98 } 99 } 100 return 0; 101} 102 103static char * 104Strcpy(char *dst, char *src) 105{ 106 int i; 107 108 if ((dst == 0x0) || (src == 0x0)) 109 return (0); 110 for (i = 0; src[i] != 0x0; i++) { 111 dst[i] = src[i]; 112 } 113 dst[i] = 0x0; /* NULL termination */ 114 return dst; 115} 116 117static int 118Strlen(char *str) 119{ 120 int i; 121 122 if (str == 0x0) 123 return 0; 124 for (i = 0; str[i] != 0x0; i++) ; 125 return i; 126} 127 128/* Platform Detection Code */ 129 130/************************************************************************ 131 * int FindStringInSeg( unsigned int segment_address, char *string_ptr ) 132 * 133 * Returns the offset where the NULL terminated string pointed to by 134 * string_ptr is located in the segment passed in segment_address. 135 * Segment_address must be of the form 0xXXXX (i.e 0xf000 for segment f). 136 * Returns NULL if the string is not found. 137 ************************************************************************ 138 */ 139int 140FindStringInSeg(unsigned int segment_address, char *string_ptr) 141{ 142 int string_length = Strlen(string_ptr); 143 char *psegment_buf; 144 unsigned long mem_ptr = (unsigned long)segment_address << 16; 145 unsigned int i; 146 147 /* silence compiler */ 148 (void)mem_ptr; 149 150 psegment_buf = (char *)XpressROMPtr; 151 152 /* Now search for the first character of the string_ptr */ 153 for (i = 0; i < SEGMENT_LENGTH + 1; i++) { 154 if (*(psegment_buf + i) == *string_ptr) { 155 156 /* If we match the first character, do a 157 * string compare. 158 */ 159 160 if (!Strncmp(string_ptr, (psegment_buf + i), string_length)) { 161 /* They match! */ 162 return (1); 163 } 164 } 165 } 166 /* if we got this far we didn't find anything. Return NULL. */ 167 return (0); 168 169} /* end FindStringInSeg() */ 170 171/********************************************************************** 172 173 * TRUE_FALSE get_sys_board_type( SYS_BOARD_INFO *sys_info, 174 * SYS_BOARD_INFO *sys_board_array_base) 175 * 176 * Checks the system BIOS area for Xpressrom information. If found, searches 177 * the BIOS area for one of names in the array pointed to by 178 * sys_board_array_ptr. 179 * If a match is found, sets the SYS_INFO system_board_name string 180 * and the system_board variable to the board name and returns TRUE. 181 * If Xpressrom or a board is not found, sets the variables to 182 * their default values and returns FALSE. 183 * Uses the global string pointer *xpress_rom_string_ptr. 184 *********************************************************************** 185 */ 186static unsigned char 187get_sys_board_type(SYS_BOARD_INFO * sys_info, 188 SYS_BOARD_INFO * sys_board_array_base) 189{ 190 int index; 191 char *xpress_rom_string_ptr = "XpressStart"; 192 unsigned int segment = LINUX_ROM_SEGMENT; 193 194 /* See if XpressStart is present in the BIOS area. 195 * If it is, search for a board string. If not, Xpressrom is 196 * not present, set system_board information to UNKNOWN and 197 * return FALSE. 198 */ 199 200 if (!FindStringInSeg(segment, xpress_rom_string_ptr)) { 201 sys_info->sys_board = PLT_UNKNOWN; 202 Strcpy(sys_info->sys_board_name, "Unknown"); 203 return (FALSE); 204 } else { 205 206 /* we have Xpressrom, so look for a board */ 207 for (index = 0; index < Num_sys_board_type; index++) { 208 if (!FindStringInSeg(segment, (sys_board_array_base + 209 index)->sys_board_name)) { 210 continue; 211 } else { 212 213 /* a match!! */ 214 sys_info->sys_board = 215 (sys_board_array_base + index)->sys_board; 216 Strcpy(sys_info->sys_board_name, 217 (sys_board_array_base + index)->sys_board_name); 218 return (TRUE); 219 } 220 } /* end for() */ 221 } /* end else */ 222 223 /* if we are here we have failed */ 224 sys_info->sys_board = PLT_UNKNOWN; 225 Strcpy(sys_info->sys_board_name, "Unknown"); 226 return (FALSE); 227} /* end get_sys_board_type() */ 228