/* Copyright (c) 2005 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* * File Contents: This file contains platform dependent functions * which provide interface to that platform. * * SubModule: Geode FlatPanel library * */ #define LINUX_ROM_SEGMENT 0x000F #define SEGMENT_LENGTH 0xFFFF #define PAGE_LENGTH 0x1000 #define SYS_BOARD_NAME_LEN 24 #define PLT_UNKNOWN 0xFFFF typedef struct { char sys_board_name[SYS_BOARD_NAME_LEN]; SYS_BOARD sys_board; } SYS_BOARD_INFO; static SYS_BOARD_INFO Sys_info; /* * The names in the sys_board_name string must exactly match the names in the * BIOS header. These names are used by FindStringInSeg() to find the names * in the BIOS header space. The BIOS does not use OTHER; it is a dummy value * for program useonly. */ SYS_BOARD_INFO Sys_board_info_array[] = { {"Marmot", MARMOT_PLATFORM}, {"Unicorn", UNICORN_PLATFORM}, {"Centaurus", CENTAURUS_PLATFORM}, {"Aries", ARIES_PLATFORM}, {"Carmel", CARMEL_PLATFORM}, {"Hyrda", HYDRA_PLATFORM}, {"Dorado", DORADO_PLATFORM}, {"Redcloud", REDCLOUD_PLATFORM}, {"Other", OTHER_PLATFORM} }; #define NUM_SYS_BOARD_TYPES \ sizeof(Sys_board_info_array)/sizeof(SYS_BOARD_INFO) static int Num_sys_board_type = NUM_SYS_BOARD_TYPES; SYS_BOARD_INFO *Sys_board_array_base = Sys_board_info_array; int FindStringInSeg(unsigned int, char *); static unsigned char get_sys_board_type(SYS_BOARD_INFO *, SYS_BOARD_INFO *); /* Detect the Platform */ int Detect_Platform(void) { /* See if we can find the board name using Xpressrom */ get_sys_board_type(&Sys_info, Sys_board_array_base); return (Sys_info.sys_board); } static int Strncmp(char *str1, char *str2, int len) { int i; if ((str1 == 0x0) || (str2 == 0x0) || (len == 0)) return (1); for (i = 0; i < len; i++) { if (*(str1 + i) > *(str2 + i)) { return 1; } else if (*(str1 + i) < *(str2 + i)) { return -1; } } return 0; } static char * Strcpy(char *dst, char *src) { int i; if ((dst == 0x0) || (src == 0x0)) return (0); for (i = 0; src[i] != 0x0; i++) { dst[i] = src[i]; } dst[i] = 0x0; /* NULL termination */ return dst; } static int Strlen(char *str) { int i; if (str == 0x0) return 0; for (i = 0; str[i] != 0x0; i++) ; return i; } /* Platform Detection Code */ /************************************************************************ * int FindStringInSeg( unsigned int segment_address, char *string_ptr ) * * Returns the offset where the NULL terminated string pointed to by * string_ptr is located in the segment passed in segment_address. * Segment_address must be of the form 0xXXXX (i.e 0xf000 for segment f). * Returns NULL if the string is not found. ************************************************************************ */ int FindStringInSeg(unsigned int segment_address, char *string_ptr) { int string_length = Strlen(string_ptr); char *psegment_buf; unsigned long mem_ptr = (unsigned long)segment_address << 16; unsigned int i; /* silence compiler */ (void)mem_ptr; psegment_buf = (char *)XpressROMPtr; /* Now search for the first character of the string_ptr */ for (i = 0; i < SEGMENT_LENGTH + 1; i++) { if (*(psegment_buf + i) == *string_ptr) { /* If we match the first character, do a * string compare. */ if (!Strncmp(string_ptr, (psegment_buf + i), string_length)) { /* They match! */ return (1); } } } /* if we got this far we didn't find anything. Return NULL. */ return (0); } /* end FindStringInSeg() */ /********************************************************************** * TRUE_FALSE get_sys_board_type( SYS_BOARD_INFO *sys_info, * SYS_BOARD_INFO *sys_board_array_base) * * Checks the system BIOS area for Xpressrom information. If found, searches * the BIOS area for one of names in the array pointed to by * sys_board_array_ptr. * If a match is found, sets the SYS_INFO system_board_name string * and the system_board variable to the board name and returns TRUE. * If Xpressrom or a board is not found, sets the variables to * their default values and returns FALSE. * Uses the global string pointer *xpress_rom_string_ptr. *********************************************************************** */ static unsigned char get_sys_board_type(SYS_BOARD_INFO * sys_info, SYS_BOARD_INFO * sys_board_array_base) { int index; char *xpress_rom_string_ptr = "XpressStart"; unsigned int segment = LINUX_ROM_SEGMENT; /* See if XpressStart is present in the BIOS area. * If it is, search for a board string. If not, Xpressrom is * not present, set system_board information to UNKNOWN and * return FALSE. */ if (!FindStringInSeg(segment, xpress_rom_string_ptr)) { sys_info->sys_board = PLT_UNKNOWN; Strcpy(sys_info->sys_board_name, "Unknown"); return (FALSE); } else { /* we have Xpressrom, so look for a board */ for (index = 0; index < Num_sys_board_type; index++) { if (!FindStringInSeg(segment, (sys_board_array_base + index)->sys_board_name)) { continue; } else { /* a match!! */ sys_info->sys_board = (sys_board_array_base + index)->sys_board; Strcpy(sys_info->sys_board_name, (sys_board_array_base + index)->sys_board_name); return (TRUE); } } /* end for() */ } /* end else */ /* if we are here we have failed */ sys_info->sys_board = PLT_UNKNOWN; Strcpy(sys_info->sys_board_name, "Unknown"); return (FALSE); } /* end get_sys_board_type() */