diff options
Diffstat (limited to 'com32')
-rw-r--r-- | com32/gplinclude/vpd/vpd.h | 33 | ||||
-rw-r--r-- | com32/gpllib/Makefile | 2 | ||||
-rw-r--r-- | com32/gpllib/vpd/vpd.c | 103 | ||||
-rw-r--r-- | com32/modules/Makefile | 3 | ||||
-rw-r--r-- | com32/modules/vpdtest.c | 68 |
5 files changed, 207 insertions, 2 deletions
diff --git a/com32/gplinclude/vpd/vpd.h b/com32/gplinclude/vpd/vpd.h new file mode 100644 index 00000000..4bb1afc9 --- /dev/null +++ b/com32/gplinclude/vpd/vpd.h @@ -0,0 +1,33 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006 Erwan Velu - All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, Inc., 53 Temple Place Ste 330, + * Boston MA 02111-1307, USA; either version 2 of the License, or + * (at your option) any later version; incorporated herein by reference. + * + * ----------------------------------------------------------------------- */ + +#ifndef VPD_H +#define VPD_H +#include <inttypes.h> +#include <stdbool.h> + +enum {VPD_TABLE_PRESENT = 100, ENOVPDTABLE}; + +typedef struct { + char bios_build_id[10]; + char box_serial_number[8]; + char motherboard_serial_number[12]; + char machine_type_model[8]; + char bios_release_date[9]; + char default_flash_filename[13]; + char bios_version[255]; + char base_address[6]; + bool filled; +} s_vpd; + +int vpd_decode(s_vpd *vpd); +#endif diff --git a/com32/gpllib/Makefile b/com32/gpllib/Makefile index 46ed42e3..8e47d93f 100644 --- a/com32/gpllib/Makefile +++ b/com32/gpllib/Makefile @@ -10,7 +10,7 @@ REQFLAGS += -I../gplinclude LIBOBJS = dmi/dmi_battery.o dmi/dmi_chassis.o dmi/dmi_memory.o \ dmi/dmi_processor.o dmi/dmi.o dmi/dmi_bios.o dmi/dmi_base_board.o \ - dmi/dmi_ipmi.o cpuid.o + dmi/dmi_ipmi.o cpuid.o vpd/vpd.o BINDIR = /usr/bin LIBDIR = /usr/lib diff --git a/com32/gpllib/vpd/vpd.c b/com32/gpllib/vpd/vpd.c new file mode 100644 index 00000000..ff04b8bf --- /dev/null +++ b/com32/gpllib/vpd/vpd.c @@ -0,0 +1,103 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2006 Erwan Velu - All Rights Reserved + * + * 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. + * + * ----------------------------------------------------------------------- +*/ + +#include <stdio.h> +#include <string.h> +#include "vpd/vpd.h" + +int vpd_checksum(char *buf, int len) +{ + uint8_t sum=0; + int a; + + for(a=0; a<len; a++) + sum+=buf[a]; + return (sum==0); +} + +int vpd_decode(s_vpd *vpd) { + uint8_t buf[16]; + char *p,*q; + + /* Cleaning structures */ + memset(&vpd->base_address,0,sizeof (vpd->base_address)); + memset(&vpd->bios_build_id,0,sizeof (vpd->bios_build_id)); + memset(&vpd->box_serial_number,0,sizeof (vpd->box_serial_number)); + memset(&vpd->motherboard_serial_number,0,sizeof (vpd->motherboard_serial_number)); + memset(&vpd->machine_type_model,0,sizeof (vpd->machine_type_model)); + memset(&vpd->bios_release_date,0,sizeof (vpd->bios_release_date)); + memset(&vpd->default_flash_filename,0,sizeof (vpd->default_flash_filename)); + memset(&vpd->bios_version,0,sizeof (vpd->bios_version)); + + /* Until we found elements in the vpdtable, we consider them as not filled */ + vpd->filled=false; + + p=(char *)0xF0000; /* The start address to look at the dmi table */ + for (q = p; q < p + 0x10000; q +=4) { + memcpy(buf, q, 5); + if(memcmp(buf, "\252\125VPD", 5)==0) { + snprintf(&vpd->base_address,5,"%X",q); + if (q[5] < 0x30) + return -ENOVPDTABLE; + + vpd->filled=true; + /* XSeries have longer records, exact length seems to vary. */ + if (!(q[5] >= 0x45 && vpd_checksum(q, q[5])) + /* Some Netvista seem to work with this. */ + && !(vpd_checksum(q, 0x30)) + /* The Thinkpad/Thinkcentre checksum does *not* include the first 13 bytes. */ + && !(vpd_checksum(q + 0x0D, 0x30 - 0x0D))) + { + /* A few systems have a bad checksum (xSeries 325, 330, 335 + and 345 with early BIOS) but the record is otherwise + valid. */ + printf("VPD: Bad checksum!\n"); + } + + strncpy(vpd->bios_build_id,q+0x0D, 9); + strncpy(vpd->box_serial_number,q+0x16, 7); + strncpy(vpd->motherboard_serial_number,q+0x1D, 11); + strncpy(vpd->machine_type_model,q+0x28, 7); + + if (q[5] < 0x44) + return VPD_TABLE_PRESENT; + + strncpy(vpd->bios_release_date,q+0x30, 8); + strncpy(vpd->default_flash_filename,q+0x38, 12); + + if (q[5] >= 0x46 && q[0x44] != 0x00) { + strncpy(vpd->bios_version,q+0x44, 255); + } + + return VPD_TABLE_PRESENT; + } + } + return -ENOVPDTABLE; +} + + diff --git a/com32/modules/Makefile b/com32/modules/Makefile index 5a8a88c4..305ea49f 100644 --- a/com32/modules/Makefile +++ b/com32/modules/Makefile @@ -20,7 +20,8 @@ include ../MCONFIG MODULES = chain.c32 config.c32 ethersel.c32 mboot.c32 dmitest.c32 \ cpuidtest.c32 \ pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 meminfo.c32 \ - sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 kbdmap.c32 cmd.c32 + sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 kbdmap.c32 cmd.c32 \ + vpdtest.c32 TESTFILES = diff --git a/com32/modules/vpdtest.c b/com32/modules/vpdtest.c new file mode 100644 index 00000000..81a9faeb --- /dev/null +++ b/com32/modules/vpdtest.c @@ -0,0 +1,68 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2009 Erwan Velu - All Rights Reserved + * + * 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. + * + * ----------------------------------------------------------------------- +*/ + +/* + * vpdtest.c + * + * VPD demo program using libcom32 + */ + +#include <string.h> +#include <stdio.h> +#include <console.h> +#include "vpd/vpd.h" + +int main(void) +{ + char buffer[1024]; + s_vpd vpd; + openconsole(&dev_stdcon_r, &dev_stdcon_w); + + if (vpd_decode(&vpd) == -ENOVPDTABLE) { + printf("No VPD Structure found\n"); + return -1; + } else { + printf("VPD present at address : 0x%s\n",vpd.base_address); + } + if (strlen(vpd.bios_build_id)>0) + printf("Bios Build ID : %s\n",vpd.bios_build_id); + if (strlen(vpd.bios_release_date)>0) + printf("Bios Release Date : %s\n",vpd.bios_release_date); + if (strlen(vpd.bios_version)>0) + printf("Bios Version : %s\n",vpd.bios_version); + if (strlen(vpd.default_flash_filename)>0) + printf("Default Flash Filename : %s\n",vpd.default_flash_filename); + if (strlen(vpd.box_serial_number)>0) + printf("Box Serial Number : %s\n",vpd.box_serial_number); + if (strlen(vpd.motherboard_serial_number)>0) + printf("Motherboard Serial Number : %s\n",vpd.motherboard_serial_number); + if (strlen(vpd.machine_type_model)>0) + printf("Machine Type/Model : %s\n",vpd.machine_type_model); + + return 0; +} |