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