summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-08-04 09:27:10 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-08-04 09:27:10 +0000
commit34e3f7e16647a0a203b6090019a1d0c069b7c372 (patch)
tree93ed002ecfd564602118dad6583c3f1e936c6c3b
parent837f8d6ddb3da1947fda7dad5d5cb32fb0ba057d (diff)
Implement smbios support on arm64.
ok deraadt@, jsg@
-rw-r--r--sys/arch/arm64/conf/GENERIC3
-rw-r--r--sys/arch/arm64/conf/files.arm648
-rw-r--r--sys/arch/arm64/dev/efi.c17
-rw-r--r--sys/arch/arm64/dev/smbios.c392
-rw-r--r--sys/arch/arm64/include/smbiosvar.h278
-rw-r--r--sys/dev/acpi/efi.h12
6 files changed, 704 insertions, 6 deletions
diff --git a/sys/arch/arm64/conf/GENERIC b/sys/arch/arm64/conf/GENERIC
index c8de0337af1..15e3468d6db 100644
--- a/sys/arch/arm64/conf/GENERIC
+++ b/sys/arch/arm64/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.105 2019/08/03 23:27:34 deraadt Exp $
+# $OpenBSD: GENERIC,v 1.106 2019/08/04 09:27:09 kettenis Exp $
#
# GENERIC machine description file
#
@@ -38,6 +38,7 @@ mainbus0 at root
cpu0 at mainbus?
apm0 at mainbus?
efi0 at mainbus?
+smbios0 at efi?
acpi0 at mainbus?
acpibtn* at acpi?
acpiec* at acpi?
diff --git a/sys/arch/arm64/conf/files.arm64 b/sys/arch/arm64/conf/files.arm64
index 71a5de7a841..6d63b75a75f 100644
--- a/sys/arch/arm64/conf/files.arm64
+++ b/sys/arch/arm64/conf/files.arm64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.arm64,v 1.29 2019/08/03 23:29:46 deraadt Exp $
+# $OpenBSD: files.arm64,v 1.30 2019/08/04 09:27:09 kettenis Exp $
maxpartitions 16
maxusers 2 8 128
@@ -59,10 +59,14 @@ device simplebus: fdt
attach simplebus at fdt
file arch/arm64/dev/simplebus.c simplebus
-device efi
+device efi {}
attach efi at fdt
file arch/arm64/dev/efi.c efi
+device smbios
+attach smbios at efi
+file arch/arm64/dev/smbios.c smbios
+
# FDT support
include "dev/ofw/files.ofw"
diff --git a/sys/arch/arm64/dev/efi.c b/sys/arch/arm64/dev/efi.c
index ad735492cbb..6553a12cd82 100644
--- a/sys/arch/arm64/dev/efi.c
+++ b/sys/arch/arm64/dev/efi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efi.c,v 1.6 2018/07/02 07:25:29 kettenis Exp $ */
+/* $OpenBSD: efi.c,v 1.7 2019/08/04 09:27:09 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org>
@@ -43,6 +43,7 @@ extern uint32_t mmap_desc_ver;
extern EFI_MEMORY_DESCRIPTOR *mmap;
uint64_t efi_acpi_table;
+uint64_t efi_smbios_table;
struct efi_softc {
struct device sc_dev;
@@ -185,12 +186,26 @@ efi_attach(struct device *parent, struct device *self, void *aux)
for (i = 0; i < st->NumberOfTableEntries; i++) {
EFI_CONFIGURATION_TABLE *ct = &st->ConfigurationTable[i];
static EFI_GUID acpi_guid = EFI_ACPI_20_TABLE_GUID;
+ static EFI_GUID smbios_guid = SMBIOS3_TABLE_GUID;
if (efi_guidcmp(&acpi_guid, &ct->VendorGuid) == 0)
efi_acpi_table = (uint64_t)ct->VendorTable;
+ if (efi_guidcmp(&smbios_guid, &ct->VendorGuid) == 0)
+ efi_smbios_table = (uint64_t)ct->VendorTable;
}
efi_leave(sc);
+ if (efi_smbios_table != 0) {
+ struct fdt_reg reg = { .addr = efi_smbios_table };
+ struct fdt_attach_args fa;
+
+ fa.fa_name = "smbios";
+ fa.fa_iot = faa->fa_iot;
+ fa.fa_reg = &reg;
+ fa.fa_nreg = 1;
+ config_found(self, &fa, NULL);
+ }
+
if (rs == NULL)
return;
diff --git a/sys/arch/arm64/dev/smbios.c b/sys/arch/arm64/dev/smbios.c
new file mode 100644
index 00000000000..7c2135a6764
--- /dev/null
+++ b/sys/arch/arm64/dev/smbios.c
@@ -0,0 +1,392 @@
+/* $OpenBSD: smbios.c,v 1.1 2019/08/04 09:27:09 kettenis Exp $ */
+/*
+ * Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca>
+ * Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/fdt.h>
+#include <machine/smbiosvar.h>
+
+#include <dev/ofw/fdt.h>
+#include <dev/rndvar.h>
+
+struct smbios_entry smbios_entry;
+/*
+ * used by hw_sysctl
+ */
+extern char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
+
+const char *smbios_uninfo[] = {
+ "System",
+ "Not ",
+ "To be",
+ "SYS-"
+};
+
+char smbios_bios_date[64];
+
+void smbios_info(char *);
+char *fixstring(char *);
+
+struct smbios_softc {
+ struct device sc_dev;
+ bus_space_tag_t sc_iot;
+};
+
+int smbios_match(struct device *, void *, void *);
+void smbios_attach(struct device *, struct device *, void *);
+
+struct cfattach smbios_ca = {
+ sizeof(struct device), smbios_match, smbios_attach
+};
+
+struct cfdriver smbios_cd = {
+ NULL, "smbios", DV_DULL
+};
+
+int
+smbios_match(struct device *parent, void *match, void *aux)
+{
+ struct fdt_attach_args *faa = aux;
+
+ return (strcmp(faa->fa_name, "smbios") == 0);
+}
+
+void
+smbios_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct smbios_softc *sc = (struct smbios_softc *)self;
+ struct fdt_attach_args *faa = aux;
+ struct smbios_struct_bios *sb;
+ struct smbtable bios;
+ char scratch[64];
+ char *sminfop;
+ bus_addr_t addr;
+ bus_size_t size;
+ bus_space_handle_t ioh;
+ struct smb3hdr *hdr;
+ uint8_t *p, checksum = 0;
+ int i;
+
+ sc->sc_iot = faa->fa_iot;
+ if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, sizeof(*hdr),
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &ioh)) {
+ printf(": can't map SMBIOS entry point structure\n");
+ return;
+ }
+
+ hdr = bus_space_vaddr(sc->sc_iot, ioh);
+ if (strncmp(hdr->sig, "_SM3_", sizeof(hdr->sig)) != 0)
+ return;
+ if (hdr->len != sizeof(*hdr) || hdr->epr != 0x01)
+ return;
+ for (i = 0, p = (uint8_t *)hdr; i < hdr->len; i++)
+ checksum += p[i];
+ if (checksum != 0)
+ return;
+
+ printf(": SMBIOS %d.%d.%d", hdr->majrev, hdr->minrev, hdr->docrev);
+
+ smbios_entry.len = hdr->size;
+ smbios_entry.mjr = hdr->majrev;
+ smbios_entry.min = hdr->minrev;
+ smbios_entry.count = -1;
+
+ addr = hdr->addr;
+ size = hdr->size;
+
+ bus_space_unmap(sc->sc_iot, ioh, sizeof(*hdr));
+
+ if (bus_space_map(sc->sc_iot, addr, size,
+ BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &ioh)) {
+ printf(": can't map SMBIOS structure table\n");
+ return;
+ }
+ smbios_entry.addr = bus_space_vaddr(sc->sc_iot, ioh);
+
+ bios.cookie = 0;
+ if (smbios_find_table(SMBIOS_TYPE_BIOS, &bios)) {
+ sb = bios.tblhdr;
+ printf("\n%s:", sc->sc_dev.dv_xname);
+ if ((smbios_get_string(&bios, sb->vendor,
+ scratch, sizeof(scratch))) != NULL)
+ printf(" vendor %s",
+ fixstring(scratch));
+ if ((smbios_get_string(&bios, sb->version,
+ scratch, sizeof(scratch))) != NULL)
+ printf(" version \"%s\"",
+ fixstring(scratch));
+ if ((smbios_get_string(&bios, sb->release,
+ scratch, sizeof(scratch))) != NULL) {
+ sminfop = fixstring(scratch);
+ if (sminfop != NULL) {
+ strlcpy(smbios_bios_date,
+ sminfop,
+ sizeof(smbios_bios_date));
+ printf(" date %s", sminfop);
+ }
+ }
+
+ smbios_info(sc->sc_dev.dv_xname);
+ }
+
+ printf("\n");
+}
+
+/*
+ * smbios_find_table() takes a caller supplied smbios struct type and
+ * a pointer to a handle (struct smbtable) returning one if the structure
+ * is successfully located and zero otherwise. Callers should take care
+ * to initialize the cookie field of the smbtable structure to zero before
+ * the first invocation of this function.
+ * Multiple tables of the same type can be located by repeatedly calling
+ * smbios_find_table with the same arguments.
+ */
+int
+smbios_find_table(u_int8_t type, struct smbtable *st)
+{
+ u_int8_t *va, *end;
+ struct smbtblhdr *hdr;
+ int ret = 0, tcount = 1;
+
+ va = smbios_entry.addr;
+ end = va + smbios_entry.len;
+
+ /*
+ * The cookie field of the smtable structure is used to locate
+ * multiple instances of a table of an arbitrary type. Following the
+ * successful location of a table, the type is encoded as bits 0:7 of
+ * the cookie value, the offset in terms of the number of structures
+ * preceding that referenced by the handle is encoded in bits 15:31.
+ */
+ if ((st->cookie & 0xfff) == type && st->cookie >> 16) {
+ if ((u_int8_t *)st->hdr >= va && (u_int8_t *)st->hdr < end) {
+ hdr = st->hdr;
+ if (hdr->type == type) {
+ va = (u_int8_t *)hdr + hdr->size;
+ for (; va + 1 < end; va++)
+ if (*va == 0 && *(va + 1) == 0)
+ break;
+ va+= 2;
+ tcount = st->cookie >> 16;
+ }
+ }
+ }
+ for (; va + sizeof(struct smbtblhdr) < end && tcount <=
+ smbios_entry.count; tcount++) {
+ hdr = (struct smbtblhdr *)va;
+ if (hdr->type == type) {
+ ret = 1;
+ st->hdr = hdr;
+ st->tblhdr = va + sizeof(struct smbtblhdr);
+ st->cookie = (tcount + 1) << 16 | type;
+ break;
+ }
+ if (hdr->type == SMBIOS_TYPE_EOT)
+ break;
+ va+= hdr->size;
+ for (; va + 1 < end; va++)
+ if (*va == 0 && *(va + 1) == 0)
+ break;
+ va+=2;
+ }
+ return ret;
+}
+
+char *
+smbios_get_string(struct smbtable *st, u_int8_t indx, char *dest, size_t len)
+{
+ u_int8_t *va, *end;
+ char *ret = NULL;
+ int i;
+
+ va = (u_int8_t *)st->hdr + st->hdr->size;
+ end = smbios_entry.addr + smbios_entry.len;
+ for (i = 1; va < end && i < indx && *va; i++)
+ while (*va++)
+ ;
+ if (i == indx) {
+ if (va + len < end) {
+ ret = dest;
+ memcpy(ret, va, len);
+ ret[len-1] = '\0';
+ }
+ }
+
+ return ret;
+}
+
+char *
+fixstring(char *s)
+{
+ char *p, *e;
+ int i;
+
+ for (i = 0; i < nitems(smbios_uninfo); i++)
+ if ((strncasecmp(s, smbios_uninfo[i],
+ strlen(smbios_uninfo[i])))==0)
+ return NULL;
+ /*
+ * Remove leading and trailing whitespace
+ */
+ for (p = s; *p == ' '; p++)
+ ;
+ /*
+ * Special case entire string is whitespace
+ */
+ if (p == s + strlen(s))
+ return NULL;
+ for (e = s + strlen(s) - 1; e > s && *e == ' '; e--)
+ ;
+ if (p > s || e < s + strlen(s) - 1) {
+ memmove(s, p, e - p + 1);
+ s[e - p + 1] = '\0';
+ }
+
+ return s;
+}
+
+void
+smbios_info(char * str)
+{
+ char *sminfop, sminfo[64];
+ struct smbtable stbl, btbl;
+ struct smbios_sys *sys;
+ struct smbios_board *board;
+ int i, infolen, uuidf, havebb;
+ char *p;
+
+ if (smbios_entry.mjr < 2)
+ return;
+ /*
+ * According to the spec the system table among others is required,
+ * if it is not we do not bother with this smbios implementation.
+ */
+ stbl.cookie = btbl.cookie = 0;
+ if (!smbios_find_table(SMBIOS_TYPE_SYSTEM, &stbl))
+ return;
+ havebb = smbios_find_table(SMBIOS_TYPE_BASEBOARD, &btbl);
+
+ sys = (struct smbios_sys *)stbl.tblhdr;
+ if (havebb)
+ board = (struct smbios_board *)btbl.tblhdr;
+ /*
+ * Some smbios implementations have no system vendor or product strings,
+ * some have very uninformative data which is harder to work around
+ * and we must rely upon various heuristics to detect this. In both
+ * cases we attempt to fall back on the base board information in the
+ * perhaps naive belief that motherboard vendors will supply this
+ * information.
+ */
+ sminfop = NULL;
+ if ((p = smbios_get_string(&stbl, sys->vendor, sminfo,
+ sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ if (sminfop == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->vendor,
+ sminfo, sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ }
+ }
+ if (sminfop) {
+ infolen = strlen(sminfop) + 1;
+ hw_vendor = malloc(infolen, M_DEVBUF, M_NOWAIT);
+ if (hw_vendor)
+ strlcpy(hw_vendor, sminfop, infolen);
+ sminfop = NULL;
+ }
+ if ((p = smbios_get_string(&stbl, sys->product, sminfo,
+ sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ if (sminfop == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->product,
+ sminfo, sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ }
+ }
+ if (sminfop) {
+ infolen = strlen(sminfop) + 1;
+ hw_prod = malloc(infolen, M_DEVBUF, M_NOWAIT);
+ if (hw_prod)
+ strlcpy(hw_prod, sminfop, infolen);
+ sminfop = NULL;
+ }
+ if (hw_vendor != NULL && hw_prod != NULL)
+ printf("\n%s: %s %s", str, hw_vendor, hw_prod);
+ if ((p = smbios_get_string(&stbl, sys->version, sminfo,
+ sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ if (sminfop) {
+ infolen = strlen(sminfop) + 1;
+ hw_ver = malloc(infolen, M_DEVBUF, M_NOWAIT);
+ if (hw_ver)
+ strlcpy(hw_ver, sminfop, infolen);
+ sminfop = NULL;
+ }
+ if ((p = smbios_get_string(&stbl, sys->serial, sminfo,
+ sizeof(sminfo))) != NULL)
+ sminfop = fixstring(p);
+ if (sminfop) {
+ infolen = strlen(sminfop) + 1;
+ for (i = 0; i < infolen - 1; i++)
+ enqueue_randomness(sminfop[i]);
+ hw_serial = malloc(infolen, M_DEVBUF, M_NOWAIT);
+ if (hw_serial)
+ strlcpy(hw_serial, sminfop, infolen);
+ }
+ if (smbios_entry.mjr > 2 || (smbios_entry.mjr == 2 &&
+ smbios_entry.min >= 1)) {
+ /*
+ * If the uuid value is all 0xff the uuid is present but not
+ * set, if its all 0 then the uuid isn't present at all.
+ */
+ uuidf = SMBIOS_UUID_NPRESENT|SMBIOS_UUID_NSET;
+ for (i = 0; i < sizeof(sys->uuid); i++) {
+ if (sys->uuid[i] != 0xff)
+ uuidf &= ~SMBIOS_UUID_NSET;
+ if (sys->uuid[i] != 0)
+ uuidf &= ~SMBIOS_UUID_NPRESENT;
+ }
+
+ if (uuidf & SMBIOS_UUID_NPRESENT)
+ hw_uuid = NULL;
+ else if (uuidf & SMBIOS_UUID_NSET)
+ hw_uuid = "Not Set";
+ else {
+ for (i = 0; i < sizeof(sys->uuid); i++)
+ enqueue_randomness(sys->uuid[i]);
+ hw_uuid = malloc(SMBIOS_UUID_REPLEN, M_DEVBUF,
+ M_NOWAIT);
+ if (hw_uuid) {
+ snprintf(hw_uuid, SMBIOS_UUID_REPLEN,
+ SMBIOS_UUID_REP,
+ sys->uuid[0], sys->uuid[1], sys->uuid[2],
+ sys->uuid[3], sys->uuid[4], sys->uuid[5],
+ sys->uuid[6], sys->uuid[7], sys->uuid[8],
+ sys->uuid[9], sys->uuid[10], sys->uuid[11],
+ sys->uuid[12], sys->uuid[13], sys->uuid[14],
+ sys->uuid[15]);
+ }
+ }
+ }
+}
diff --git a/sys/arch/arm64/include/smbiosvar.h b/sys/arch/arm64/include/smbiosvar.h
new file mode 100644
index 00000000000..8e4b59e3fea
--- /dev/null
+++ b/sys/arch/arm64/include/smbiosvar.h
@@ -0,0 +1,278 @@
+/* $OpenBSD: smbiosvar.h,v 1.1 2019/08/04 09:27:09 kettenis Exp $ */
+/*
+ * Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca>
+ * Copyright (c) 2005 Jordan Hargrave
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _MACHINE_SMBIOSVAR_
+#define _MACHINE_SMBIOSVAR_
+
+#define SMBIOS_UUID_NPRESENT 0x1
+#define SMBIOS_UUID_NSET 0x2
+
+/*
+ * Section 3.5 of "UUIDs and GUIDs" found at
+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
+ * specifies the string repersentation of a UUID.
+ */
+#define SMBIOS_UUID_REP "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
+#define SMBIOS_UUID_REPLEN 37 /* 16 zero padded values, 4 hyphens, 1 null */
+
+struct smbios_entry {
+ u_int8_t mjr;
+ u_int8_t min;
+ u_int8_t *addr;
+ u_int16_t len;
+ u_int16_t count;
+};
+
+struct smbhdr {
+ u_int32_t sig; /* "_SM_" */
+ u_int8_t checksum; /* Entry point checksum */
+ u_int8_t len; /* Entry point structure length */
+ u_int8_t majrev; /* Specification major revision */
+ u_int8_t minrev; /* Specification minor revision */
+ u_int16_t mss; /* Maximum Structure Size */
+ u_int8_t epr; /* Entry Point Revision */
+ u_int8_t fa[5]; /* value determined by EPR */
+ u_int8_t sasig[5]; /* Secondary Anchor "_DMI_" */
+ u_int8_t sachecksum; /* Secondary Checksum */
+ u_int16_t size; /* Length of structure table in bytes */
+ u_int32_t addr; /* Structure table address */
+ u_int16_t count; /* Number of SMBIOS structures */
+ u_int8_t rev; /* BCD revision */
+} __packed;
+
+struct smb3hdr {
+ u_int8_t sig[5]; /* "_SM3_" */
+ u_int8_t checksum; /* Entry point structure checksum */
+ u_int8_t len; /* Entry point length */
+ u_int8_t majrev; /* SMBIOS major version */
+ u_int8_t minrev; /* SMBIOS minor version */
+ u_int8_t docrev; /* SMBIOS docrev */
+ u_int8_t epr; /* Entry point revision */
+ u_int8_t reserved; /* Reserved */
+ u_int32_t size; /* Structure table maximum size */
+ u_int64_t addr; /* Structure table address */
+} __packed;
+
+struct smbtblhdr {
+ u_int8_t type;
+ u_int8_t size;
+ u_int16_t handle;
+} __packed;
+
+struct smbtable {
+ struct smbtblhdr *hdr;
+ void *tblhdr;
+ u_int32_t cookie;
+};
+
+#define SMBIOS_TYPE_BIOS 0
+#define SMBIOS_TYPE_SYSTEM 1
+#define SMBIOS_TYPE_BASEBOARD 2
+#define SMBIOS_TYPE_ENCLOSURE 3
+#define SMBIOS_TYPE_PROCESSOR 4
+#define SMBIOS_TYPE_MEMCTRL 5
+#define SMBIOS_TYPE_MEMMOD 6
+#define SMBIOS_TYPE_CACHE 7
+#define SMBIOS_TYPE_PORT 8
+#define SMBIOS_TYPE_SLOTS 9
+#define SMBIOS_TYPE_OBD 10
+#define SMBIOS_TYPE_OEM 11
+#define SMBIOS_TYPE_SYSCONFOPT 12
+#define SMBIOS_TYPE_BIOSLANG 13
+#define SMBIOS_TYPE_GROUPASSOC 14
+#define SMBIOS_TYPE_SYSEVENTLOG 15
+#define SMBIOS_TYPE_PHYMEM 16
+#define SMBIOS_TYPE_MEMDEV 17
+#define SMBIOS_TYPE_ECCINFO32 18
+#define SMBIOS_TYPE_MEMMAPARRAYADDR 19
+#define SMBIOS_TYPE_MEMMAPDEVADDR 20
+#define SMBIOS_TYPE_INBUILTPOINT 21
+#define SMBIOS_TYPE_PORTBATT 22
+#define SMBIOS_TYPE_SYSRESET 23
+#define SMBIOS_TYPE_HWSECUIRTY 24
+#define SMBIOS_TYPE_PWRCTRL 25
+#define SMBIOS_TYPE_VOLTPROBE 26
+#define SMBIOS_TYPE_COOLING 27
+#define SMBIOS_TYPE_TEMPPROBE 28
+#define SMBIOS_TYPE_CURRENTPROBE 29
+#define SMBIOS_TYPE_OOB_REMOTEACCESS 30
+#define SMBIOS_TYPE_BIS 31
+#define SMBIOS_TYPE_SBI 32
+#define SMBIOS_TYPE_ECCINFO64 33
+#define SMBIOS_TYPE_MGMTDEV 34
+#define SMBIOS_TYPE_MGTDEVCOMP 35
+#define SMBIOS_TYPE_MGTDEVTHRESH 36
+#define SMBIOS_TYPE_MEMCHANNEL 37
+#define SMBIOS_TYPE_IPMIDEV 38
+#define SMBIOS_TYPE_SPS 39
+#define SMBIOS_TYPE_INACTIVE 126
+#define SMBIOS_TYPE_EOT 127
+
+/*
+ * SMBIOS Structure Type 0 "BIOS Information"
+ * DMTF Specification DSP0134 Section: 3.3.1 p.g. 34
+ */
+struct smbios_struct_bios {
+ u_int8_t vendor; /* string */
+ u_int8_t version; /* string */
+ u_int16_t startaddr;
+ u_int8_t release; /* string */
+ u_int8_t romsize;
+ u_int64_t characteristics;
+ u_int32_t charext;
+ u_int8_t major_rel;
+ u_int8_t minor_rel;
+ u_int8_t ecf_mjr_rel; /* embedded controler firmware */
+ u_int8_t ecf_min_rel; /* embedded controler firmware */
+} __packed;
+
+/*
+ * SMBIOS Structure Type 1 "System Information"
+ * DMTF Specification DSP0134 Section 3.3.2 p.g. 35
+ */
+
+struct smbios_sys {
+/* SMBIOS spec 2.0+ */
+ u_int8_t vendor; /* string */
+ u_int8_t product; /* string */
+ u_int8_t version; /* string */
+ u_int8_t serial; /* string */
+/* SMBIOS spec 2.1+ */
+ u_int8_t uuid[16];
+ u_int8_t wakeup;
+/* SMBIOS spec 2.4+ */
+ u_int8_t sku; /* string */
+ u_int8_t family; /* string */
+} __packed;
+
+/*
+ * SMBIOS Structure Type 2 "Base Board (Module) Information"
+ * DMTF Specification DSP0134 Section 3.3.3 p.g. 37
+ */
+struct smbios_board {
+ u_int8_t vendor; /* string */
+ u_int8_t product; /* string */
+ u_int8_t version; /* string */
+ u_int8_t serial; /* string */
+ u_int8_t asset; /* stirng */
+ u_int8_t feature; /* feature flags */
+ u_int8_t location; /* location in chassis */
+ u_int16_t handle; /* chassis handle */
+ u_int8_t type; /* board type */
+ u_int8_t noc; /* number of contained objects */
+} __packed;
+
+/*
+ * SMBIOS Structure Type 3 "System Wnclosure or Chassis"
+ * DMTF Specification DSP0134
+ */
+struct smbios_enclosure {
+ /* SMBIOS spec 2.0+ */
+ u_int8_t vendor; /* string */
+ u_int8_t type;
+ u_int8_t version; /* string */
+ u_int8_t serial; /* string */
+ u_int8_t asset_tag; /* string */
+ /* SMBIOS spec 2.1+ */
+ u_int8_t boot_state;
+ u_int8_t psu_state;
+ u_int8_t thermal_state;
+ u_int8_t security_status;
+ /* SMBIOS spec 2.3+ */
+ u_int16_t oem_defined;
+ u_int8_t height;
+ u_int8_t no_power_cords;
+ u_int8_t no_contained_element;
+ u_int8_t reclen_contained_element;
+ u_int8_t contained_elements;
+ /* SMBIOS spec 2.7+ */
+ u_int8_t sku; /* string */
+} __packed;
+
+/*
+ * SMBIOS Structure Type 4 "processor Information"
+ * DMTF Specification DSP0134 v2.5 Section 3.3.5 p.g. 24
+ */
+struct smbios_cpu {
+ u_int8_t cpu_socket_designation; /* string */
+ u_int8_t cpu_type;
+ u_int8_t cpu_family;
+ u_int8_t cpu_mfg; /* string */
+ u_int32_t cpu_id_eax;
+ u_int32_t cpu_id_edx;
+ u_int8_t cpu_version; /* string */
+ u_int8_t cpu_voltage;
+ u_int16_t cpu_clock;
+ u_int16_t cpu_max_speed;
+ u_int16_t cpu_current_speed;
+ u_int8_t cpu_status;
+#define SMBIOS_CPUST_POPULATED (1<<6)
+#define SMBIOS_CPUST_STATUSMASK (0x07)
+ u_int8_t cpu_upgrade;
+ u_int16_t cpu_l1_handle;
+ u_int16_t cpu_l2_handle;
+ u_int16_t cpu_l3_handle;
+ u_int8_t cpu_serial; /* string */
+ u_int8_t cpu_asset_tag; /* string */
+ u_int8_t cpu_part_nr; /* string */
+ /* following fields were added in smbios 2.5 */
+ u_int8_t cpu_core_count;
+ u_int8_t cpu_core_enabled;
+ u_int8_t cpu_thread_count;
+ u_int16_t cpu_characteristics;
+} __packed;
+
+/*
+ * SMBIOS Structure Type 38 "IPMI Information"
+ * DMTF Specification DSP0134 Section 3.3.39 p.g. 91
+ */
+struct smbios_ipmi {
+ u_int8_t smipmi_if_type; /* IPMI Interface Type */
+ u_int8_t smipmi_if_rev; /* BCD IPMI Revision */
+ u_int8_t smipmi_i2c_address; /* I2C address of BMC */
+ u_int8_t smipmi_nvram_address; /* I2C address of NVRAM
+ * storage */
+ u_int64_t smipmi_base_address; /* Base address of BMC (BAR
+ * format */
+ u_int8_t smipmi_base_flags; /* Flags field:
+ * bit 7:6 : register spacing
+ * 00 = byte
+ * 01 = dword
+ * 02 = word
+ * bit 4 : Lower bit BAR
+ * bit 3 : IRQ valid
+ * bit 2 : N/A
+ * bit 1 : Interrupt polarity
+ * bit 0 : Interrupt trigger */
+ u_int8_t smipmi_irq; /* IRQ if applicable */
+} __packed;
+
+int smbios_find_table(u_int8_t, struct smbtable *);
+char *smbios_get_string(struct smbtable *, u_int8_t, char *, size_t);
+
+#endif
diff --git a/sys/dev/acpi/efi.h b/sys/dev/acpi/efi.h
index d747a2f4315..d15fa4c5626 100644
--- a/sys/dev/acpi/efi.h
+++ b/sys/dev/acpi/efi.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efi.h,v 1.3 2018/06/24 10:38:44 kettenis Exp $ */
+/* $OpenBSD: efi.h,v 1.4 2019/08/04 09:27:09 kettenis Exp $ */
/* Public Domain */
@@ -31,7 +31,15 @@ typedef struct {
#define EFI_ACPI_20_TABLE_GUID \
{ 0x8868e871, 0xe4f1, 0x11d3, \
- { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+ { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 } }
+
+#define SMBIOS_TABLE_GUID \
+ { 0xeb9d2d31, 0x2d88, 0x11d3, \
+ { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } }
+
+#define SMBIOS3_TABLE_GUID \
+ { 0xf2fd1544, 0x9794, 0x4a2c, \
+ { 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } }
typedef enum {
EfiReservedMemoryType,