diff options
author | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2006-05-08 22:51:19 +0000 |
---|---|---|
committer | Gordon Willem Klok <gwk@cvs.openbsd.org> | 2006-05-08 22:51:19 +0000 |
commit | 43f20e0647ff9d1b9f6f333dca641dc01587e7ca (patch) | |
tree | 2749242ff1e683c88f4323fa995c1e5eeb99a750 | |
parent | b4b9ffec62bebe163253a5cefcea185cd4bbae23 (diff) |
Add smbios support for i386 and amd64, fix ipmi to use this new functionallity,
hook up some sysctls to add system vendor/product/version and UUID reporting.
"get it in" deraadt@
-rw-r--r-- | sys/arch/amd64/amd64/bios.c | 299 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/mainbus.c | 19 | ||||
-rw-r--r-- | sys/arch/amd64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 6 | ||||
-rw-r--r-- | sys/arch/amd64/include/biosvar.h | 4 | ||||
-rw-r--r-- | sys/arch/amd64/include/smbiosvar.h | 206 | ||||
-rw-r--r-- | sys/arch/i386/i386/bios.c | 40 | ||||
-rw-r--r-- | sys/arch/i386/include/biosvar.h | 4 | ||||
-rw-r--r-- | sys/arch/i386/include/smbiosvar.h | 206 | ||||
-rw-r--r-- | sys/dev/ipmi.c | 111 | ||||
-rw-r--r-- | sys/dev/ipmivar.h | 51 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 31 | ||||
-rw-r--r-- | sys/sys/sysctl.h | 14 |
13 files changed, 818 insertions, 176 deletions
diff --git a/sys/arch/amd64/amd64/bios.c b/sys/arch/amd64/amd64/bios.c new file mode 100644 index 00000000000..8d803aba448 --- /dev/null +++ b/sys/arch/amd64/amd64/bios.c @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca> + * + * 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/systm.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/errno.h> +#include <sys/malloc.h> + +#include <uvm/uvm_extern.h> +#include <sys/sysctl.h> + +#include <machine/conf.h> +#include <machine/biosvar.h> +#include <machine/smbiosvar.h> + +#include <dev/isa/isareg.h> +#include <amd64/include/isa_machdep.h> + +struct bios_softc { + struct device sc_dev; +}; + +void smbios_info(char *); +int bios_match(struct device *, void *, void *); +void bios_attach(struct device *, struct device *, void *); + +struct cfattach bios_ca = { + sizeof(struct bios_softc), bios_match, bios_attach +}; + +struct cfdriver bios_cd = { + NULL, "bios", DV_DULL +}; + +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 Specified" +}; + +int +bios_match(struct device *parent, void *match , void *aux) +{ + struct bios_attach_args *bia = aux; + /* only one */ + if (bios_cd.cd_ndevs || strcmp(bia->bios_dev, bios_cd.cd_name)) + return 0; + + return 1; +} + +void +bios_attach(struct device *parent, struct device *self, void *aux) +{ + struct bios_softc *sc = (struct bios_softc *)self; + vaddr_t va; + paddr_t pa, end; + u_int8_t *p; + + /* see if we have SMBIOS extentions */ + for (p = ISA_HOLE_VADDR(SMBIOS_START); + p < (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) { + struct smbhdr * hdr = (struct smbhdr *)p; + u_int8_t chksum; + int i; + + if (hdr->sig != SMBIOS_SIGNATURE) + continue; + i = hdr->len; + for (chksum = 0; i--; chksum += p[i]) + ; + if (chksum != 0) + continue; + p += 0x10; + if (p[0] != '_' && p[1] != 'D' && p[2] != 'M' && + p[3] != 'I' && p[4] != '_') + continue; + for (chksum = 0, i = 0xf; i--; chksum += p[i]); + ; + if (chksum != 0) + continue; + + pa = trunc_page(hdr->addr); + end = round_page(hdr->addr + hdr->size); + va = uvm_km_valloc(kernel_map, end-pa); + if (va == 0) + break; + + smbios_entry.addr = (u_int8_t *)(va + (hdr->addr & PGOFSET)); + smbios_entry.len = hdr->size; + smbios_entry.mjr = hdr->majrev; + smbios_entry.min = hdr->minrev; + smbios_entry.count = hdr->count; + + for(; pa < end; pa+= NBPG, va+= NBPG) + pmap_kenter_pa(va, pa, VM_PROT_READ); + + printf(": SMBIOS rev. %d.%d @ 0x%lx (%d entries)", + hdr->majrev, hdr->minrev, hdr->addr, hdr->count); + smbios_info(sc->sc_dev.dv_xname); + break; + } + + 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 sucessfully located and zero otherwise. Callers should take care + * to initilize 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 repeadtly 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 + * sucessful 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 == NULL && *(va + 1) == NULL) + 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 == NULL && *(va + 1) == NULL) + break; + va+=2; + } + + return ret; +} + +char * +smbios_get_string(struct smbtable *st, u_int8_t indx) +{ + 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) + ret = (char *) va; + + return ret; +} + +void +smbios_info(char * str) +{ + struct smbtable stbl, btbl; + struct smbios_sys *sys; + struct smbios_board *board; + int i, uuidf, havebb; + + if (smbios_entry.mjr < 2) + return; + /* + * According to the spec the system table among others are required to + * be present, if it is not we dont 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 naieve belief that motherboard vendors will supply this + * information. + */ + if ((hw_vendor = smbios_get_string(&stbl, sys->vendor)) != NULL) { + for (i = 0; i < sizeof(smbios_uninfo) / sizeof(smbios_uninfo[0]) + ; i++) { + if ((strncmp(hw_vendor, smbios_uninfo[i], + strlen(smbios_uninfo[i]))) == 0) { + if (havebb) + hw_vendor = smbios_get_string(&btbl, + board->vendor); + break; + } + } + } else + hw_vendor = smbios_get_string(&btbl, board->vendor); + if ((hw_prod = smbios_get_string(&stbl, sys->product)) != NULL) { + for (i = 0; i < sizeof(smbios_uninfo) / sizeof(smbios_uninfo[0]) + ; i++) { + if ((strncmp(hw_prod, smbios_uninfo[i], + strlen(smbios_uninfo[i]))) == 0) { + if (havebb) + hw_prod = smbios_get_string(&btbl, + board->product); + break; + } + } + } else + hw_prod = smbios_get_string(&btbl, board->product); + if (hw_vendor != NULL && hw_prod != NULL) + printf("\n%s: %s %s", str, hw_vendor, hw_prod); + hw_ver = smbios_get_string(&stbl, sys->version); + hw_serial = smbios_get_string(&stbl, sys->serial); + 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 isnt 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 { + 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/amd64/amd64/mainbus.c b/sys/arch/amd64/amd64/mainbus.c index 42a3f8e38df..804a7c0308c 100644 --- a/sys/arch/amd64/amd64/mainbus.c +++ b/sys/arch/amd64/amd64/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.7 2006/04/14 21:33:56 marco Exp $ */ +/* $OpenBSD: mainbus.c,v 1.8 2006/05/08 22:51:17 gwk Exp $ */ /* $NetBSD: mainbus.c,v 1.1 2003/04/26 18:39:29 fvdl Exp $ */ /* @@ -46,6 +46,7 @@ #include "isa.h" #include "acpi.h" #include "ipmi.h" +#include "bios.h" #include <machine/cpuvar.h> #include <machine/i82093var.h> @@ -60,6 +61,10 @@ #include <dev/ipmivar.h> #endif +#if NBIOS > 0 +#include <machine/biosvar.h> +#endif + int mainbus_match(struct device *, void *, void *); void mainbus_attach(struct device *, struct device *, void *); @@ -85,6 +90,9 @@ union mainbus_attach_args { #if NIPMI > 0 struct ipmi_attach_args mba_iaa; #endif +#if NBIOS > 0 + struct bios_attach_args mba_bios; +#endif }; /* @@ -149,6 +157,15 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) pci_mode = pci_mode_detect(); #endif +#if NBIOS > 0 + { + mba.mba_bios.bios_dev = "bios"; + mba.mba_bios.bios_iot = X86_BUS_SPACE_IO; + mba.mba_bios.bios_memt = X86_BUS_SPACE_MEM; + config_found(self, &mba.mba_bios, mainbus_print); + } +#endif + #if NACPI > 0 #if NPCI > 0 if (pci_mode != 0) diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index bab2525569c..800d51067c4 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.126 2006/05/08 04:15:02 brad Exp $ +# $OpenBSD: GENERIC,v 1.127 2006/05/08 22:51:18 gwk Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -37,6 +37,7 @@ config bsd swap generic mainbus0 at root +bios0 at mainbus? cpu0 at mainbus? isa0 at mainbus0 isa0 at pcib? diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 0b6cd58fa6a..ce1caf427b6 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.21 2006/03/22 21:16:00 kettenis Exp $ +# $OpenBSD: files.amd64,v 1.22 2006/05/08 22:51:18 gwk Exp $ maxpartitions 16 maxusers 2 16 128 @@ -73,6 +73,10 @@ device mainbus: isabus, pcibus, mainbus attach mainbus at root file arch/amd64/amd64/mainbus.c mainbus +device bios {} +attach bios at mainbus +file arch/amd64/amd64/bios.c bios needs-flag + define cpu {[apid = -1]} device cpu attach cpu at mainbus diff --git a/sys/arch/amd64/include/biosvar.h b/sys/arch/amd64/include/biosvar.h index b4bc59108bd..94a67ffad78 100644 --- a/sys/arch/amd64/include/biosvar.h +++ b/sys/arch/amd64/include/biosvar.h @@ -1,5 +1,5 @@ /* XXX - DSR */ -/* $OpenBSD: biosvar.h,v 1.5 2005/12/13 23:13:45 mickey Exp $ */ +/* $OpenBSD: biosvar.h,v 1.6 2006/05/08 22:51:18 gwk Exp $ */ /* * Copyright (c) 1997-1999 Michael Shalayeff @@ -42,6 +42,7 @@ #define BIOSF_BIOS32 0x0001 #define BIOSF_PCIBIOS 0x0002 #define BIOSF_PROMSCAN 0x0004 +#define BIOSF_SMBIOS 0x0006 /* BIOS media ID */ #define BIOSM_F320K 0xff /* floppy ds/sd 8 spt */ @@ -110,6 +111,7 @@ struct bios32_entry { ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) #define BIOS32_SIGNATURE BIOS32_MAKESIG('_', '3', '2', '_') #define PCIBIOS_SIGNATURE BIOS32_MAKESIG('$', 'P', 'C', 'I') +#define SMBIOS_SIGNATURE BIOS32_MAKESIG('_', 'S', 'M', '_') /* * CTL_BIOS definitions. diff --git a/sys/arch/amd64/include/smbiosvar.h b/sys/arch/amd64/include/smbiosvar.h new file mode 100644 index 00000000000..5c9392c642e --- /dev/null +++ b/sys/arch/amd64/include/smbiosvar.h @@ -0,0 +1,206 @@ +/* + * 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 _I386_SMBIOSVAR_ +#define _I386_SMBIOSVAR_ + +#define SMBIOS_START 0xf0000 +#define SMBIOS_END 0xfffff + +#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 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 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); + +#endif diff --git a/sys/arch/i386/i386/bios.c b/sys/arch/i386/i386/bios.c index e559d97caf7..95def0a01d5 100644 --- a/sys/arch/i386/i386/bios.c +++ b/sys/arch/i386/i386/bios.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bios.c,v 1.62 2006/05/08 21:13:03 gwk Exp $ */ +/* $OpenBSD: bios.c,v 1.59 2006/05/08 22:51:18 gwk Exp $ */ /* * Copyright (c) 1997-2001 Michael Shalayeff @@ -91,7 +91,7 @@ u_int32_t bios_cksumlen; struct bios32_entry bios32_entry; struct smbios_entry smbios_entry; #ifdef MULTIPROCESSOR -void *bios_smpinfo; +void *bios_smpinfo; #endif void smbios_info(char*); @@ -103,8 +103,8 @@ bios_diskinfo_t *bios_getdiskinfo(dev_t); */ extern char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver; const char * smbios_uninfo[] = { - "System", - "Not Specified" + "System", + "Not Specified" }; @@ -160,7 +160,7 @@ biosattach(struct device *parent, struct device *self, void *aux) /* see if we have BIOS32 extensions */ if (!(flags & BIOSF_BIOS32)) { for (va = ISA_HOLE_VADDR(BIOS32_START); - va < (u_int8_t *)ISA_HOLE_VADDR(BIOS32_END); va += 16) { + va < (u_int8_t *)ISA_HOLE_VADDR(BIOS32_END); va += 16) { bios32_header_t h = (bios32_header_t)va; u_int8_t cksum; int i; @@ -184,7 +184,7 @@ biosattach(struct device *parent, struct device *self, void *aux) } } - /* see if we have SMBIOS extentions */ + /* see if we have SMBIOS extentions */ if (!(flags & BIOSF_SMBIOS)) { for (va = ISA_HOLE_VADDR(SMBIOS_START); va < (u_int8_t *)ISA_HOLE_VADDR(SMBIOS_END); va+= 16) { @@ -210,13 +210,13 @@ biosattach(struct device *parent, struct device *self, void *aux) if (chksum != 0) continue; - pa = trunc_page(sh->addr); + pa = trunc_page(sh->addr); end = round_page(sh->addr + sh->size); eva = uvm_km_valloc(kernel_map, end-pa); if (eva == 0) break; - smbios_entry.addr = (u_int8_t *)(eva + + smbios_entry.addr = (u_int8_t *)(eva + (sh->addr & PGOFSET)); smbios_entry.len = sh->size; smbios_entry.mjr = sh->majrev; @@ -225,10 +225,10 @@ biosattach(struct device *parent, struct device *self, void *aux) for (; pa < end; pa+= NBPG, eva+= NBPG) pmap_kenter_pa(eva, pa, VM_PROT_READ); - - printf(", SMBIOS rev. %d.%d @ 0x%lx (%d entries)", + + printf(", SMBIOS rev. %d.%d @ 0x%lx (%d entries)", sh->majrev, sh->minrev, sh->addr, sh->count); - + smbios_info(sc->sc_dev.dv_xname); break; } @@ -274,8 +274,8 @@ biosattach(struct device *parent, struct device *self, void *aux) volatile u_int8_t *eva; for (str = NULL, va = ISA_HOLE_VADDR(0xc0000), - eva = ISA_HOLE_VADDR(0xf0000); - va < eva; va += 512) { + eva = ISA_HOLE_VADDR(0xf0000); + va < eva; va += 512) { extern struct extent *iomem_ex; bios_romheader_t romh = (bios_romheader_t)va; u_int32_t off, len; @@ -452,8 +452,8 @@ bios32_service(u_int32_t service, bios32_entry_t e, bios32_entry_info_t ei) setgdt(slot, (caddr_t)va, BIOS32_END, SDT_MEMERA, SEL_KPL, 1, 0); for (pa = trunc_page(BIOS32_START), - va += trunc_page(BIOS32_START); - pa < endpa; pa += NBPG, va += NBPG) { + va += trunc_page(BIOS32_START); + pa < endpa; pa += NBPG, va += NBPG) { pmap_enter(pmap_kernel(), va, pa, VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); @@ -628,7 +628,7 @@ bios_getdiskinfo(dev_t dev) * smbios_find_table with the same arguments. */ int -smbios_find_table(u_int8_t type, struct smbtable *st) +smbios_find_table(u_int8_t type, struct smbtable *st) { u_int8_t *va, *end; struct smbtblhdr *hdr; @@ -660,6 +660,7 @@ smbios_find_table(u_int8_t type, struct smbtable *st) for (; va + sizeof(struct smbtblhdr) < end && tcount <= smbios_entry.count; tcount++) { hdr = (struct smbtblhdr *) va; + printf("SMBIOS (%d)@%p type: %d", tcount, va, hdr->type); if (hdr->type == type) { ret = 1; st->hdr = hdr; @@ -670,12 +671,15 @@ smbios_find_table(u_int8_t type, struct smbtable *st) if (hdr->type == SMBIOS_TYPE_EOT) break; va+= hdr->size; + printf(" size: %d strings@%p", hdr->size, va); for (; va + 1 < end; va++) if (*va == NULL && *(va + 1) == NULL) break; va+=2; + printf(" end@%p\n", va); } + printf("\n"); return ret; } @@ -698,7 +702,7 @@ smbios_get_string(struct smbtable *st, u_int8_t indx) } void -smbios_info(char * str) +smbios_info(char * str) { struct smbtable stbl, btbl; struct smbios_sys *sys; @@ -720,7 +724,7 @@ smbios_info(char * str) 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 diff --git a/sys/arch/i386/include/biosvar.h b/sys/arch/i386/include/biosvar.h index dca4f99f7c5..fbf08a134f4 100644 --- a/sys/arch/i386/include/biosvar.h +++ b/sys/arch/i386/include/biosvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: biosvar.h,v 1.45 2005/11/22 12:51:01 mickey Exp $ */ +/* $OpenBSD: biosvar.h,v 1.46 2006/05/08 22:51:18 gwk Exp $ */ /* * Copyright (c) 1997-1999 Michael Shalayeff @@ -39,6 +39,7 @@ #define BIOSF_BIOS32 0x0001 #define BIOSF_PCIBIOS 0x0002 #define BIOSF_PROMSCAN 0x0004 +#define BIOSF_SMBIOS 0x0006 /* BIOS media ID */ #define BIOSM_F320K 0xff /* floppy ds/sd 8 spt */ @@ -107,6 +108,7 @@ struct bios32_entry { ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) #define BIOS32_SIGNATURE BIOS32_MAKESIG('_', '3', '2', '_') #define PCIBIOS_SIGNATURE BIOS32_MAKESIG('$', 'P', 'C', 'I') +#define SMBIOS_SIGNATURE BIOS32_MAKESIG('_', 'S', 'M', '_') /* * CTL_BIOS definitions. diff --git a/sys/arch/i386/include/smbiosvar.h b/sys/arch/i386/include/smbiosvar.h new file mode 100644 index 00000000000..5c9392c642e --- /dev/null +++ b/sys/arch/i386/include/smbiosvar.h @@ -0,0 +1,206 @@ +/* + * 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 _I386_SMBIOSVAR_ +#define _I386_SMBIOSVAR_ + +#define SMBIOS_START 0xf0000 +#define SMBIOS_END 0xfffff + +#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 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 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); + +#endif diff --git a/sys/dev/ipmi.c b/sys/dev/ipmi.c index b15bfd6483f..23bbcca9a84 100644 --- a/sys/dev/ipmi.c +++ b/sys/dev/ipmi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipmi.c,v 1.37 2006/05/06 15:04:38 wilfried Exp $ */ +/* $OpenBSD: ipmi.c,v 1.38 2006/05/08 22:51:18 gwk Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave @@ -39,6 +39,7 @@ #include <machine/bus.h> #include <machine/intr.h> +#include <machine/smbiosvar.h> #include <dev/isa/isareg.h> #include <dev/isa/isavar.h> @@ -137,7 +138,6 @@ struct ipmi_sensors_head ipmi_sensor_list = struct timeout ipmi_timeout; -void smbios_ipmi_probe(void *, void *); void dumpb(const char *, int, const u_int8_t *); int read_sensor(struct ipmi_softc *, struct ipmi_sensor *); @@ -173,21 +173,12 @@ void *cmn_buildmsg(struct ipmi_softc *, int, int, int, const void *, int *); int getbits(u_int8_t *, int, int); int ipmi_sensor_type(int, int, int); +void ipmi_smbios_probe(struct smbios_ipmi *, struct ipmi_attach_args *); void ipmi_refresh_sensors(struct ipmi_softc *sc); int ipmi_map_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia); void ipmi_unmap_regs(struct ipmi_softc *sc, struct ipmi_attach_args *ia); -struct smbios_mem_map { - vaddr_t baseva; - u_int8_t *va; - size_t vsize; - paddr_t pa; -}; - -void *smbios_map(paddr_t, size_t, struct smbios_mem_map *); -void smbios_unmap(struct smbios_mem_map *); void *scan_sig(long, long, int, int, const void *); -int scan_smbios(u_int8_t, void (*)(void *, void *), void *); int ipmi_test_threshold(u_int8_t, u_int8_t, u_int8_t, u_int8_t); int ipmi_sensor_status(struct ipmi_softc *, struct ipmi_sensor *, @@ -843,87 +834,6 @@ scan_sig(long start, long end, int skip, int len, const void *data) return (NULL); } -void * -smbios_map(paddr_t pa, size_t len, struct smbios_mem_map *handle) -{ - paddr_t pgstart = trunc_page(pa); - paddr_t pgend = round_page(pa + len); - vaddr_t va = uvm_km_valloc(kernel_map, pgend-pgstart); - - if (va == 0) - return NULL; - - handle->pa = pa; - handle->baseva = va; - handle->va = (u_int8_t *)(va + ((u_long)pa & PGOFSET)); - handle->vsize = pgend - pgstart; - - do { - pmap_kenter_pa(va, pgstart, VM_PROT_READ); - va += NBPG; - pgstart += NBPG; - } while (pgstart < pgend); - - return handle->va; -} - -void -smbios_unmap(struct smbios_mem_map *handle) -{ - pmap_kremove(handle->baseva, handle->vsize); - uvm_km_free(kernel_map, handle->baseva, handle->vsize); -} - -/* Scan SMBIOS for table type */ -int -scan_smbios(u_int8_t mtype, void (*smcb) (void *base, void *arg), void *arg) -{ - struct smbiosanchor *romhdr; - struct smhdr *smhdr; - u_int8_t *offset; - int nmatch, num; - struct smbios_mem_map smm; - - /* Scan for SMBIOS Table Signature */ - romhdr = (struct smbiosanchor *)scan_sig(0xF0000, 0xFFFFF, 16, 4, - "_SM_"); - if (romhdr == NULL) - return (0); - - dbg_printf(1, "SMBIOS Version %d.%d at 0x%lx, %d entries\n", - romhdr->smr_smbios_majver, romhdr->smr_smbios_minver, - romhdr->smr_table_address, romhdr->smr_count); - - /* Map SMBIOS Table start address */ - nmatch = 0; - offset = smbios_map(romhdr->smr_table_address, - romhdr->smr_count * romhdr->smr_maxsize, &smm); - if (offset == NULL) - return (0); - - for (num = 0; num < romhdr->smr_count; num++) { - smhdr = (struct smhdr *)offset; - if (smhdr->smh_type == SMBIOS_TYPE_END || - smhdr->smh_length == 0) - break; - - /* found a match here */ - if (smhdr->smh_type == mtype) { - smcb(&smhdr[1], arg); - nmatch++; - } - /* Search for end of string table, marked by '\0\0' */ - offset += smhdr->smh_length; - while (offset[0] || offset[1]) - offset++; - - offset += 2; - } - smbios_unmap(&smm); - - return (nmatch); -} - void dumpb(const char *lbl, int len, const u_int8_t *data) { @@ -937,10 +847,8 @@ dumpb(const char *lbl, int len, const u_int8_t *data) } void -smbios_ipmi_probe(void *ptr, void *arg) +ipmi_smbios_probe(struct smbios_ipmi *pipmi, struct ipmi_attach_args *ia) { - struct ipmi_attach_args *ia = arg; - struct smbios_ipmi *pipmi = (struct smbios_ipmi *)ptr; dbg_printf(1, "%02x %02x %02x %02x %08llx %02x %02x\n", pipmi->smipmi_if_type, @@ -1661,13 +1569,16 @@ int ipmi_probe(void *aux) { struct ipmi_attach_args *ia = aux; + struct dmd_ipmi *pipmi; + struct smbtable tbl; - if (scan_smbios(SMBIOS_TYPE_IPMI, smbios_ipmi_probe, ia) == 0) { - struct dmd_ipmi *pipmi; - - /* XXX hack to find Dell PowerEdge 8450 */ + tbl.cookie = 0; + if (smbios_find_table(SMBIOS_TYPE_IPMIDEV, &tbl)) + ipmi_smbios_probe(tbl.tblhdr, ia); + else { pipmi = (struct dmd_ipmi *)scan_sig(0xC0000L, 0xFFFFFL, 16, 4, "IPMI"); + /* XXX hack to find Dell PowerEdge 8450 */ if (pipmi == NULL) { /* no IPMI found */ return (0); diff --git a/sys/dev/ipmivar.h b/sys/dev/ipmivar.h index b51936d3ed6..8d893878283 100644 --- a/sys/dev/ipmivar.h +++ b/sys/dev/ipmivar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipmivar.h,v 1.11 2006/05/06 15:05:19 wilfried Exp $ */ +/* $OpenBSD: ipmivar.h,v 1.12 2006/05/08 22:51:18 gwk Exp $ */ /* * Copyright (c) 2005 Jordan Hargrave @@ -142,55 +142,6 @@ int smic_reset(struct ipmi_softc *); int smic_sendmsg(struct ipmi_softc *, int, const u_int8_t *); int smic_recvmsg(struct ipmi_softc *, int, int *, u_int8_t *); -#define SMBIOS_TYPE_IPMI 0x26 -#define SMBIOS_TYPE_END 0x7F - -struct smbiosanchor { - u_int8_t smr_smtag[4]; /* Signature '_SM_' */ - u_int8_t smr_ep_cksum; /* Chcksum Entry Point struct */ - u_int8_t smr_length; /* Length of Anchor structure */ - u_int8_t smr_smbios_majver; /* SMBIOS Major Version */ - u_int8_t smr_smbios_minver; /* SMBIOS Minor Version */ - u_int16_t smr_maxsize; /* Max size of SMHDR entry */ - u_int8_t smr_eprev; /* SMBIOS Entry Revision (00) */ - u_int8_t smr_format[5]; /* Should be Zero */ - u_int8_t smr_dmitag[5]; /* Signature '_DMI_' */ - u_int8_t smr_iep_cksum; /* Chcksum of Intermediate Entry - * Point * structure */ - u_int16_t smr_table_length; /* Length of SMBIOS Table */ - u_int32_t smr_table_address; /* Phys addr of SMBIOS Table */ - u_int16_t smr_count; /* # of entries in SMBIOS Tbl */ - u_int8_t smr_bcdrev; /* BCD SMBIOS Revision */ -} __packed; - -struct smhdr { - u_int8_t smh_type; /* SMBIOS Header Type */ - u_int8_t smh_length; /* SMBIOS Header Length */ - u_int16_t smh_handle; /* SMBIOS Header Handle */ -} __packed; - -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; - struct dmd_ipmi { u_int8_t dmd_sig[4]; /* Signature 'IPMI' */ u_int8_t dmd_i2c_address; /* Address of BMC */ diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 037afc29aed..6c521f2e00a 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.139 2006/03/15 21:02:09 deraadt Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.140 2006/05/08 22:51:18 gwk Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -557,6 +557,8 @@ kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, /* * hardware related system variables. */ +char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver; + int hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen, struct proc *p) @@ -628,6 +630,33 @@ hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, return (cpu_setperf(perflevel)); else return (0); + case HW_VENDOR: + if (hw_vendor) + return (sysctl_rdstring(oldp, oldlenp, newp, + hw_vendor)); + else + return (EOPNOTSUPP); + case HW_PRODUCT: + if (hw_prod) + return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod)); + else + return (EOPNOTSUPP); + case HW_VERSION: + if (hw_ver) + return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver)); + else + return (EOPNOTSUPP); + case HW_SERIALNO: + if (hw_serial) + return (sysctl_rdstring(oldp, oldlenp, newp, + hw_serial)); + else + return (EOPNOTSUPP); + case HW_UUID: + if (hw_uuid) + return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid)); + else + return (EOPNOTSUPP); default: return (EOPNOTSUPP); } diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index 12409ce7471..c01505da9d4 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sysctl.h,v 1.87 2006/03/15 21:02:04 deraadt Exp $ */ +/* $OpenBSD: sysctl.h,v 1.88 2006/05/08 22:51:18 gwk Exp $ */ /* $NetBSD: sysctl.h,v 1.16 1996/04/09 20:55:36 cgd Exp $ */ /* @@ -546,7 +546,12 @@ struct kinfo_proc2 { #define HW_SENSORS 11 /* node: hardware monitors */ #define HW_CPUSPEED 12 /* get CPU frequency */ #define HW_SETPERF 13 /* set CPU performance % */ -#define HW_MAXID 14 /* number of valid hw ids */ +#define HW_VENDOR 14 /* string: vendor name */ +#define HW_PRODUCT 15 /* string: product name */ +#define HW_VERSION 16 /* string: hardware version */ +#define HW_SERIALNO 17 /* string: hardware serial number */ +#define HW_UUID 18 /* string: universal unique id */ +#define HW_MAXID 19 /* number of valid hw ids */ #define CTL_HW_NAMES { \ { 0, 0 }, \ @@ -563,6 +568,11 @@ struct kinfo_proc2 { { "sensors", CTLTYPE_NODE}, \ { "cpuspeed", CTLTYPE_INT }, \ { "setperf", CTLTYPE_INT }, \ + { "vendor", CTLTYPE_STRING }, \ + { "product", CTLTYPE_STRING }, \ + { "version", CTLTYPE_STRING }, \ + { "serialno", CTLTYPE_STRING }, \ + { "uuid", CTLTYPE_STRING }, \ } /* |