summaryrefslogtreecommitdiffstats
path: root/src/interface/smbios
diff options
context:
space:
mode:
authorMichael Brown2013-12-05 04:15:53 +0100
committerMichael Brown2013-12-05 04:16:27 +0100
commit03957bcb472e5065a46bd56e9b8b1f902fac4b3b (patch)
tree8ebbdefe842454d573c1834d1bc5398369de9402 /src/interface/smbios
parent[ipv6] Add support for resolving IPv6 addresses via the "nslookup" command (diff)
downloadipxe-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.c48
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