[SeaBIOS] [PATCH 1/2] Add an IPMI SMBIOS entry

minyard at acm.org minyard at acm.org
Tue Sep 18 22:45:52 CEST 2012


From: Corey Minyard <cminyard at mvista.com>

An IPMI device is being added to the qemu code, and it has an
SMBIOS entry to describe the interface characteristics.  So add
the SMBIOS entry to the BIOS so it can handle this.

Signed-off-by: Corey Minyard <cminyard at mvista.com>
---
 Makefile     |    2 +-
 src/ipmi.c   |   32 ++++++++++++++++++++++++++++++++
 src/ipmi.h   |   39 +++++++++++++++++++++++++++++++++++++++
 src/post.c   |    2 ++
 src/smbios.c |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/smbios.h |   12 ++++++++++++
 6 files changed, 141 insertions(+), 1 deletions(-)
 create mode 100644 src/ipmi.c
 create mode 100644 src/ipmi.h

diff --git a/Makefile b/Makefile
index 5486f88..4559e5c 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ SRCBOTH=misc.c stacks.c pmm.c output.c util.c block.c floppy.c ata.c mouse.c \
     pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \
     usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \
     virtio-ring.c virtio-pci.c virtio-blk.c virtio-scsi.c apm.c ahci.c \
-    usb-uas.c lsi-scsi.c esp-scsi.c
+    usb-uas.c lsi-scsi.c esp-scsi.c ipmi.c
 SRC16=$(SRCBOTH) system.c disk.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
     acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
diff --git a/src/ipmi.c b/src/ipmi.c
new file mode 100644
index 0000000..f4d29b1
--- /dev/null
+++ b/src/ipmi.c
@@ -0,0 +1,32 @@
+// IPMI setup information
+//
+// Copyright (C) 2012  Corey Minyard <cminyard at mvista.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "ipmi.h"
+#include "byteorder.h"
+#include "util.h"
+
+struct ipmi_info ipmi_info VAR16VISIBLE;
+
+void
+ipmi_setup(void)
+{
+    u8 *data;
+    int size;
+
+    data = romfile_loadfile("etc/ipmi", &size);
+    if (!data || (size < sizeof(ipmi_info))) {
+        ipmi_info.interface = 0; /* Disable */
+        return;
+    }
+
+    if (size > sizeof(ipmi_info))
+        size = sizeof(ipmi_info);
+
+    memcpy(&ipmi_info, data, size);
+    free(data);
+
+    ipmi_info.base_addr = le64_to_cpu(ipmi_info.base_addr);
+}
diff --git a/src/ipmi.h b/src/ipmi.h
new file mode 100644
index 0000000..72814ba
--- /dev/null
+++ b/src/ipmi.h
@@ -0,0 +1,39 @@
+// IPMI setup information
+//
+// Copyright (C) 2012  Corey Minyard <cminyard at mvista.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#ifndef __IPMI_H
+#define __IPMI_H
+
+#include "config.h"
+#include "types.h"
+
+#define IPMI_MEM_SPACE 0
+#define IPMI_IO_SPACE  1
+
+/* Specified in the SMBIOS spec. */
+#define IPMI_SMBIOS_KCS         0x01
+#define IPMI_SMBIOS_SMIC        0x02
+#define IPMI_SMBIOS_BT          0x03
+#define IPMI_SMBIOS_SSIF        0x04
+
+struct ipmi_info {
+    u8 str_version; /* Version of this structure */
+    u8 interface;
+    u8 reg_space;
+    u8 reg_spacing;
+    u8 slave_addr;
+    u8 irq;
+    u8 version;
+    u8 reserved1;
+    u64 base_addr;
+    u64 end_addr;
+} PACKED;
+
+extern struct ipmi_info ipmi_info;
+
+void ipmi_setup(void);
+
+#endif
diff --git a/src/post.c b/src/post.c
index 924b311..e3156b4 100644
--- a/src/post.c
+++ b/src/post.c
@@ -29,6 +29,7 @@
 #include "virtio-scsi.h" // virtio_scsi_setup
 #include "lsi-scsi.h" // lsi_scsi_setup
 #include "esp-scsi.h" // esp_scsi_setup
+#include "ipmi.h" // ipmi_setup
 
 
 /****************************************************************
@@ -257,6 +258,7 @@ maininit(void)
     pnp_setup();
     kbd_setup();
     mouse_setup();
+    ipmi_setup();
     init_bios_tables();
 
     // Run vga option rom
diff --git a/src/smbios.c b/src/smbios.c
index fc84aad..f480a8d 100644
--- a/src/smbios.c
+++ b/src/smbios.c
@@ -8,6 +8,7 @@
 #include "util.h" // dprintf
 #include "paravirt.h" // qemu_cfg_smbios_load_field
 #include "smbios.h" // struct smbios_entry_point
+#include "ipmi.h" // struct ipmi_info
 
 struct smbios_entry_point *SMBiosAddr;
 
@@ -422,6 +423,58 @@ smbios_init_type_32(void *start)
     return start+2;
 }
 
+/* Type 38 -- System Boot Information */
+static void *
+smbios_init_type_38(void *start, struct ipmi_info *info)
+{
+    struct smbios_type_38 *p = (struct smbios_type_38 *)start;
+
+    p->header.type = 38;
+    p->header.length = sizeof(struct smbios_type_38);
+    p->header.handle = 0x2100;
+
+    p->interface_type = info->interface;
+
+    p->base_addr = info->base_addr & ~1ULL;
+    /* Bit 0 goes into a special place */
+    p->base_addr_mod_and_irq_info = (info->base_addr & 1) << 4;
+
+    switch (info->reg_spacing) {
+    case 4:
+        p->base_addr_mod_and_irq_info |= (1 << 6);
+        break;
+    case 16:
+        p->base_addr_mod_and_irq_info |= (2 << 6);
+        break;
+    case 1:
+    default:
+        /* zero is the right value */
+        break;
+    }
+
+    if (info->reg_space)
+        p->base_addr |= 1; /* I/O space */
+
+    if (info->version)
+        p->ipmi_version = info->version;
+    else
+        p->ipmi_version = 0x15;
+
+    if (info->slave_addr)
+        p->i2c_slave_addr = info->slave_addr;
+    else
+        p->i2c_slave_addr = 0x20;
+
+    p->nv_storage_dev_addr = 0;
+
+    p->interrupt_number = info->irq;
+
+    start += sizeof(struct smbios_type_38);
+    *((u16 *)start) = 0;
+
+    return start+2;
+}
+
 /* Type 127 -- End of Table */
 static void *
 smbios_init_type_127(void *start)
@@ -510,6 +563,8 @@ smbios_init(void)
     }
 
     add_struct(32, p);
+    if (ipmi_info.interface)
+        add_struct(38, p, &ipmi_info);
     /* Add any remaining provided entries before the end marker */
     for (i = 0; i < 256; i++)
         qemu_cfg_smbios_load_external(i, &p, &nr_structs, &max_struct_size,
diff --git a/src/smbios.h b/src/smbios.h
index 9d54e80..1935335 100644
--- a/src/smbios.h
+++ b/src/smbios.h
@@ -160,6 +160,18 @@ struct smbios_type_32 {
     u8 boot_status;
 } PACKED;
 
+/* SMBIOS type 38 - IPMI Information */
+struct smbios_type_38 {
+    struct smbios_structure_header header;
+    u8 interface_type;
+    u8 ipmi_version;
+    u8 i2c_slave_addr;
+    u8 nv_storage_dev_addr;
+    u64 base_addr;
+    u8 base_addr_mod_and_irq_info;
+    u8 interrupt_number;
+} PACKED;
+
 /* SMBIOS type 127 -- End-of-table */
 struct smbios_type_127 {
     struct smbios_structure_header header;
-- 
1.7.4.1




More information about the SeaBIOS mailing list