diff options
author | Michael Brown | 2013-12-05 04:15:53 +0100 |
---|---|---|
committer | Michael Brown | 2013-12-05 04:16:27 +0100 |
commit | 03957bcb472e5065a46bd56e9b8b1f902fac4b3b (patch) | |
tree | 8ebbdefe842454d573c1834d1bc5398369de9402 /src/interface/smbios | |
parent | [ipv6] Add support for resolving IPv6 addresses via the "nslookup" command (diff) | |
download | ipxe-03957bcb472e5065a46bd56e9b8b1f902fac4b3b.tar.gz ipxe-03957bcb472e5065a46bd56e9b8b1f902fac4b3b.tar.xz ipxe-03957bcb472e5065a46bd56e9b8b1f902fac4b3b.zip |
[linux] Provide access to SMBIOS via /dev/mem
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/smbios')
-rw-r--r-- | src/interface/smbios/smbios.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/interface/smbios/smbios.c b/src/interface/smbios/smbios.c index 90907e18..85694342 100644 --- a/src/interface/smbios/smbios.c +++ b/src/interface/smbios/smbios.c @@ -38,6 +38,54 @@ static struct smbios smbios = { }; /** + * Scan for SMBIOS entry point structure + * + * @v start Start address of region to scan + * @v len Length of region to scan + * @v entry SMBIOS entry point structure to fill in + * @ret rc Return status code + */ +int find_smbios_entry ( userptr_t start, size_t len, + struct smbios_entry *entry ) { + uint8_t buf[256]; /* 256 is maximum length possible */ + static size_t offset = 0; /* Avoid repeated attempts to locate SMBIOS */ + size_t entry_len; + unsigned int i; + uint8_t sum; + + /* Try to find SMBIOS */ + for ( ; offset < len ; offset += 0x10 ) { + + /* Read start of header and verify signature */ + copy_from_user ( entry, start, offset, sizeof ( *entry ) ); + if ( entry->signature != SMBIOS_SIGNATURE ) + continue; + + /* Read whole header and verify checksum */ + entry_len = entry->len; + assert ( entry_len <= sizeof ( buf ) ); + copy_from_user ( buf, start, offset, entry_len ); + for ( i = 0, sum = 0 ; i < entry_len ; i++ ) { + sum += buf[i]; + } + if ( sum != 0 ) { + DBG ( "SMBIOS at %08lx has bad checksum %02x\n", + user_to_phys ( start, offset ), sum ); + continue; + } + + /* Fill result structure */ + DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n", + entry->major, entry->minor, + user_to_phys ( start, offset ) ); + return 0; + } + + DBG ( "No SMBIOS found\n" ); + return -ENODEV; +} + +/** * Find SMBIOS strings terminator * * @v offset Offset to start of strings |