/* * Mainboard and BIOS identification * * (c) 2002 Bernhard "Bero" Rosenkraenzer * (c) 2003 Sergei Haller. * * $Id: bios.c 858 2006-07-09 06:59:27Z bistr-o-math $ * * Released under the terms of the GPL version 2 or if, and only if, * the GPL version 2 is ruled invalid in a court of law, any later * version of the GPL. */ #include #include #include #include #include #include #include #include #include "nvram-wakeup.h" struct header { __uint8_t type; __uint8_t size; __uint16_t handle; }; static char const *__bios_vendor = NULL; static char const *__bios_version = NULL; static char const *__bios_release = NULL; static char const *__board_vendor = NULL; static char const *__board_type = NULL; static char const *__board_version = NULL; static int __dmi_probed = 0; static int __have_bios = 0; static int __have_board = 0; static __uint8_t *data; char const * __dmi_string(struct header *dmi, int i); int __dmi_probe(void); #define EXPORT(x) char const * x(void) { \ if(!__dmi_probed) \ __dmi_probe(); \ return __##x; \ } EXPORT(bios_vendor) EXPORT(bios_version) EXPORT(bios_release) EXPORT(board_vendor) EXPORT(board_type) EXPORT(board_version) #define __PRINTDEBUG fprintf(stderr, " *** file: %s, line: %d\n", __FILE__, __LINE__); char const * __dmi_string(struct header *dmi, int i) { __uint8_t *bp = (__uint8_t *)dmi; __uint8_t s = bp[i]; if (!s) return NULL; bp += dmi->size; while(--s) { if ( (int)bp >= (int)data ) return NULL; /* broken DMI entry */ bp += strlen((char *)bp) + 1; } nvprintf(LOG_DEBUG, "found string \"%s\"\n", (char const * const)strip((char *)bp)); return (char const * const)strip((char *)bp); } int __dmi_probe(void) { __uint8_t buf[16]; off_t mem_offset=0; /* offset as number of 16 byte blocks */ int fd_mem; /* ... at least we tried ... */ __dmi_probed = 1; /* open the rtc device */ nvprintf(LOG_DEBUG, "Opening %s in O_RDONLY mode...\n", MEM_DEV); fd_mem = open(MEM_DEV, O_RDONLY); if (fd_mem < 0) { nvprintf(LOG_ERR, "%s: %m\n", MEM_DEV); return 0; } if (lseek(fd_mem, 0xE0000L, 0) < 0) { nvprintf(LOG_ERR, "%s: %m\n", MEM_DEV); return 0; } while (mem_offset < 0x1FFF) { mem_offset ++; if ( read(fd_mem, buf, 16) != 16) { nvprintf(LOG_ERR, "%s: %m\n", MEM_DEV); close(fd_mem); return 0; } if (memcmp(buf, "_DMI_", 5)==0) { __uint16_t count = buf[13]<<8 | buf[12]; __uint16_t size = buf[7] <<8 | buf[6]; __uint32_t base = buf[11]<<24 | buf[10]<<16 | buf[9]<<8 | buf[8]; char *entry = alloca(size); struct header *dm; int i = 0; nvprintf(LOG_DEBUG, "_DMI_ table found: base: 0x%X, size: 0x%X, count: %d\n", base, size, count); if (lseek(fd_mem, (long)base, SEEK_SET) < 0) { nvprintf(LOG_ERR, "%s: %m\n", MEM_DEV); close(fd_mem); return 0; } if (read(fd_mem, entry, size) != size) { nvprintf(LOG_ERR, "%s: %m\n", MEM_DEV); close(fd_mem); return 0; } data = (__uint8_t *)entry; while(i++= size-4 ) break; /* broken DMI euntry */ dm = (struct header *)data; nvprintf(LOG_DEBUG, "data block %3d at offset 0x%03X: type %3d, size 0x%03X (%3d)\n", i, (int)data - (int)entry, dm->type, dm->size, dm->size ); /* compute the address of the next data block */ data += dm->size; while(data[0] || data[1]) data++; data+=2; if((!__have_bios) && dm->type == 0 && dm->size >= 8) { /* BIOS info */ __bios_vendor =__dmi_string(dm, 4 ); __bios_version =__dmi_string(dm, 5 ); __bios_release =__dmi_string(dm, 8 ); __have_bios = 1; } else if((!__have_board) && dm->type == 2 && dm->size >= 6) { /* Mainboard info */ __board_vendor =__dmi_string(dm, 4 ); __board_type =__dmi_string(dm, 5 ); __board_version =__dmi_string(dm, 6 ); __have_board = 1; } } } } nvprintf(LOG_DEBUG, "Following DMI entries found:\n"); nvprintf(LOG_DEBUG, " - Mainboard vendor: %s%s%s\n", (board_vendor() == NULL) ? "" : "\"", (board_vendor() == NULL) ? "NULL" : board_vendor() , (board_vendor() == NULL) ? "" : "\"" ); nvprintf(LOG_DEBUG, " - Mainboard type: %s%s%s\n", (board_type() == NULL) ? "" : "\"", (board_type() == NULL) ? "NULL" : board_type() , (board_type() == NULL) ? "" : "\"" ); nvprintf(LOG_DEBUG, " - Mainboard revision: %s%s%s\n", (board_version()== NULL) ? "" : "\"", (board_version()== NULL) ? "NULL" : board_version(), (board_version()== NULL) ? "" : "\"" ); nvprintf(LOG_DEBUG, " - BIOS vendor: %s%s%s\n", (bios_vendor() == NULL) ? "" : "\"", (bios_vendor() == NULL) ? "NULL" : bios_vendor() , (bios_vendor() == NULL) ? "" : "\"" ); nvprintf(LOG_DEBUG, " - BIOS version: %s%s%s\n", (bios_version() == NULL) ? "" : "\"", (bios_version() == NULL) ? "NULL" : bios_version() , (bios_version() == NULL) ? "" : "\"" ); nvprintf(LOG_DEBUG, " - BIOS release: %s%s%s\n", (bios_release() == NULL) ? "" : "\"", (bios_release() == NULL) ? "NULL" : bios_release() , (bios_release() == NULL) ? "" : "\"" ); close(fd_mem); return 1; }