Page MenuHomeFreeBSD

D28707.diff
No OneTemporary

D28707.diff

Index: stand/efi/loader/main.c
===================================================================
--- stand/efi/loader/main.c
+++ stand/efi/loader/main.c
@@ -1161,17 +1161,32 @@
efi_init_environment();
#if !defined(__arm__)
+ int found = 0;
for (k = 0; k < ST->NumberOfTableEntries; k++) {
+ guid = &ST->ConfigurationTable[k].VendorGuid;
+ if (!memcmp(guid, &smbios3, sizeof(EFI_GUID))) {
+ found = 3;
+ break;
+ }
+ }
+ for (k = 0; found == 0 && k < ST->NumberOfTableEntries; k++) {
guid = &ST->ConfigurationTable[k].VendorGuid;
if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
- char buf[40];
+ found = 2;
+ break;
+ }
+ }
+ if (found > 0) {
+ char buf[40];
- snprintf(buf, sizeof(buf), "%p",
- ST->ConfigurationTable[k].VendorTable);
+ snprintf(buf, sizeof(buf), "%p",
+ ST->ConfigurationTable[k].VendorTable);
+ if (found == 3) {
+ setenv("hint.smbios3.0.mem", buf, 1);
+ } else {
setenv("hint.smbios.0.mem", buf, 1);
- smbios_detect(ST->ConfigurationTable[k].VendorTable);
- break;
}
+ smbios_detect(ST->ConfigurationTable[k].VendorTable);
}
#endif
Index: stand/libsa/smbios.c
===================================================================
--- stand/libsa/smbios.c
+++ stand/libsa/smbios.c
@@ -54,10 +54,12 @@
#define SMBIOS_STEP 0x10
#define SMBIOS_SIG "_SM_"
#define SMBIOS_DMI_SIG "_DMI_"
+#define SMBIOS3_SIG "_SM3_"
#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off)))
#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
+#define SMBIOS_GET64(base, off) (*(uint64_t *)((base) + (off)))
#define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01)
#define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base))
@@ -98,6 +100,11 @@
caddr_t cp;
/* Search on 16-byte boundaries. */
+ for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
+ if (strncmp(cp, SMBIOS3_SIG, 5) == 0 &&
+ smbios_checksum(cp, SMBIOS_GET8(cp, 0x06)) == 0)
+ return (cp);
+
for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
@@ -423,7 +430,9 @@
return (NULL);
for (dmi = smbios.addr, i = 0;
- dmi < smbios.addr + smbios.length && i < smbios.count; i++) {
+ dmi < smbios.addr + smbios.length &&
+ (smbios.count == 0 || i < smbios.count);
+ i++) {
if (SMBIOS_GET8(dmi, 0) == type)
return dmi;
/* Find structure terminator. */
@@ -437,25 +446,44 @@
}
static void
-smbios_probe(const caddr_t addr)
+smbios_probe(caddr_t addr)
{
caddr_t saddr, info;
uintptr_t paddr;
+ uint32_t searchlen;
+ bool ep_64bit;
if (smbios.probed)
return;
smbios.probed = 1;
+ if (addr == 0) {
+ addr = PTOV(SMBIOS_START);
+ searchlen = SMBIOS_LENGTH;
+ } else {
+ searchlen = 1;
+ }
+
/* Search signatures and validate checksums. */
- saddr = smbios_sigsearch(addr ? addr : PTOV(SMBIOS_START),
- SMBIOS_LENGTH);
+ saddr = smbios_sigsearch(addr, searchlen);
if (saddr == NULL)
return;
- smbios.length = SMBIOS_GET16(saddr, 0x16); /* Structure Table Length */
- paddr = SMBIOS_GET32(saddr, 0x18); /* Structure Table Address */
- smbios.count = SMBIOS_GET16(saddr, 0x1c); /* No of SMBIOS Structures */
- smbios.ver = SMBIOS_GET8(saddr, 0x1e); /* SMBIOS BCD Revision */
+ ep_64bit = (SMBIOS_GET8(saddr, 0x3) == '3') ? true : false;
+
+ if (ep_64bit) {
+ /* SMBIOS 3.0 (64-bit) Entry Point */
+ smbios.length = SMBIOS_GET32(saddr, 0xc); /* Structure table maximum size */
+ paddr = SMBIOS_GET64(saddr, 0x10); /* Structure table address */
+ smbios.ver = 0;
+ smbios.count = 0;
+ } else {
+ /* SMBIOS 2.1 (32-bit) Entry Point */
+ smbios.length = SMBIOS_GET16(saddr, 0x16); /* Structure Table Length */
+ paddr = SMBIOS_GET32(saddr, 0x18); /* Structure Table Address */
+ smbios.count = SMBIOS_GET16(saddr, 0x1c); /* No of SMBIOS Structures */
+ smbios.ver = SMBIOS_GET8(saddr, 0x1e); /* SMBIOS BCD Revision */
+ }
if (smbios.ver != 0) {
smbios.major = smbios.ver >> 4;
@@ -464,8 +492,13 @@
smbios.ver = 0;
}
if (smbios.ver == 0) {
- smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version */
- smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version */
+ if (ep_64bit) {
+ smbios.major = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Major Version */
+ smbios.minor = SMBIOS_GET8(saddr, 0x08);/* SMBIOS Minor Version */
+ } else {
+ smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version */
+ smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version */
+ }
}
smbios.ver = (smbios.major << 8) | smbios.minor;
smbios.addr = PTOV(paddr);
@@ -489,12 +522,17 @@
caddr_t dmi;
size_t i;
+ if (smbios.addr != NULL)
+ return;
+
smbios_probe(addr);
if (smbios.addr == NULL)
return;
for (dmi = smbios.addr, i = 0;
- dmi < smbios.addr + smbios.length && i < smbios.count; i++)
+ dmi < smbios.addr + smbios.length &&
+ (smbios.count == 0 || i < smbios.count);
+ i++)
dmi = smbios_parse_table(dmi);
sprintf(buf, "%d.%d", smbios.major, smbios.minor);
Index: sys/amd64/conf/GENERIC
===================================================================
--- sys/amd64/conf/GENERIC
+++ sys/amd64/conf/GENERIC
@@ -129,6 +129,7 @@
# Bus support.
device acpi
+device smbios
options IOMMU
device pci
options PCI_HP # PCI-Express native HotPlug
Index: sys/amd64/conf/MINIMAL
===================================================================
--- sys/amd64/conf/MINIMAL
+++ sys/amd64/conf/MINIMAL
@@ -103,6 +103,7 @@
# Bus support.
device acpi
+device smbios
options IOMMU
device pci
Index: sys/amd64/include/pc/bios.h
===================================================================
--- sys/amd64/include/pc/bios.h
+++ sys/amd64/include/pc/bios.h
@@ -64,38 +64,6 @@
u_int32_t xattr;
} __packed;
-/*
- * System Management BIOS
- */
-#define SMBIOS_START 0xf0000
-#define SMBIOS_STEP 0x10
-#define SMBIOS_OFF 0
-#define SMBIOS_LEN 4
-#define SMBIOS_SIG "_SM_"
-
-struct smbios_eps {
- uint8_t anchor_string[4]; /* '_SM_' */
- uint8_t checksum;
- uint8_t length;
- uint8_t major_version;
- uint8_t minor_version;
- uint16_t maximum_structure_size;
- uint8_t entry_point_revision;
- uint8_t formatted_area[5];
- uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
- uint8_t intermediate_checksum;
- uint16_t structure_table_length;
- uint32_t structure_table_address;
- uint16_t number_structures;
- uint8_t BCD_revision;
-};
-
-struct smbios_structure_header {
- uint8_t type;
- uint8_t length;
- uint16_t handle;
-};
-
#ifdef _KERNEL
#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
Index: sys/arm64/conf/GENERIC
===================================================================
--- sys/arm64/conf/GENERIC
+++ sys/arm64/conf/GENERIC
@@ -383,6 +383,7 @@
options FDT
device acpi
+device smbios
# DTBs
makeoptions MODULES_EXTRA="dtb/allwinner dtb/freescale dtb/imx8 dtb/nvidia dtb/mv dtb/rockchip dtb/rpi"
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -3095,6 +3095,7 @@
dev/siis/siis.c optional siis pci
dev/sis/if_sis.c optional sis pci
dev/sk/if_sk.c optional sk pci
+dev/smbios/smbios.c optional smbios
dev/smbus/smb.c optional smb
dev/smbus/smbconf.c optional smbus
dev/smbus/smbus.c optional smbus
Index: sys/conf/files.x86
===================================================================
--- sys/conf/files.x86
+++ sys/conf/files.x86
@@ -293,7 +293,6 @@
x86/acpica/acpi_apm.c optional acpi
x86/acpica/acpi_wakeup.c optional acpi
x86/acpica/srat.c optional acpi
-x86/bios/smbios.c optional smbios
x86/bios/vpd.c optional vpd
x86/cpufreq/est.c optional cpufreq
x86/cpufreq/hwpstate_amd.c optional cpufreq
Index: sys/dev/acpica/acpi_resource.c
===================================================================
--- sys/dev/acpica/acpi_resource.c
+++ sys/dev/acpica/acpi_resource.c
@@ -496,6 +496,13 @@
acpi_MatchHid(handle, "ARMHC9FF") != ACPI_MATCHHID_NOMATCH)
arc.ignore_producer_flag = true;
+ /*
+ * The DesignWare I2C Controller on Ampere Altra sets ResourceProducer on
+ * memory resources.
+ */
+ if (acpi_MatchHid(handle, "APMC0D0F") != ACPI_MATCHHID_NOMATCH)
+ arc.ignore_producer_flag = true;
+
status = AcpiWalkResources(handle, "_CRS", acpi_parse_resource, &arc);
if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
printf("can't fetch resources for %s - %s\n",
Index: sys/dev/ichiic/ig4_acpi.c
===================================================================
--- sys/dev/ichiic/ig4_acpi.c
+++ sys/dev/ichiic/ig4_acpi.c
@@ -89,8 +89,16 @@
sc = device_get_softc(dev);
sc->dev = dev;
- /* All the HIDs matched are Atom SOCs. */
- sc->version = IG4_ATOM;
+ if (acpi_MatchHid(acpi_get_handle(dev), "APMC0D0F") !=
+ ACPI_MATCHHID_NOMATCH) {
+ sc->version = IG4_EMAG;
+ } else {
+ /*
+ * All the other HIDs matched are compatible with Atom
+ * mode.
+ */
+ sc->version = IG4_ATOM;
+ }
sc->regs_rid = 0;
sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&sc->regs_rid, RF_ACTIVE);
Index: sys/dev/ichiic/ig4_iic.c
===================================================================
--- sys/dev/ichiic/ig4_iic.c
+++ sys/dev/ichiic/ig4_iic.c
@@ -91,8 +91,11 @@
* Ig4 hardware parameters except Haswell are taken from intel_lpss driver
*/
static const struct ig4_hw ig4iic_hw[] = {
- [IG4_HASWELL] = {
+ [IG4_EMAG] = {
.ic_clock_rate = 100, /* MHz */
+ },
+ [IG4_HASWELL] = {
+ .ic_clock_rate = 100,
.sda_hold_time = 90, /* nsec */
.txfifo_depth = 32,
.rxfifo_depth = 32,
@@ -267,7 +270,7 @@
int error;
int txlvl = -1;
u_int count_us = 0;
- u_int limit_us = 25000; /* 25ms */
+ u_int limit_us = 1000000; /* 1sec */
for (;;) {
/*
@@ -801,7 +804,13 @@
elems = obj->Package.Elements;
*scl_hcnt = elems[0].Integer.Value & IG4_SCL_CLOCK_MASK;
*scl_lcnt = elems[1].Integer.Value & IG4_SCL_CLOCK_MASK;
- *sda_hold = elems[2].Integer.Value & IG4_SDA_TX_HOLD_MASK;
+ if (elems[2].Integer.Value != 0) {
+ /*
+ * If the value in the table is zero, stick
+ * with value calculated earlier for sda_hold.
+ */
+ *sda_hold = elems[2].Integer.Value & IG4_SDA_TX_HOLD_MASK;
+ }
status = AE_OK;
}
Index: sys/dev/ichiic/ig4_var.h
===================================================================
--- sys/dev/ichiic/ig4_var.h
+++ sys/dev/ichiic/ig4_var.h
@@ -44,6 +44,7 @@
#include "iicbus_if.h"
enum ig4_vers {
+ IG4_EMAG,
IG4_HASWELL,
IG4_ATOM,
IG4_SKYLAKE,
Index: sys/dev/iicbus/iicsmb.c
===================================================================
--- sys/dev/iicbus/iicsmb.c
+++ sys/dev/iicbus/iicsmb.c
@@ -455,7 +455,7 @@
int error;
/* Have to do this because the command is split in two transfers. */
- error = iicbus_request_bus(parent, dev, IIC_WAIT);
+ error = iicbus_request_bus(parent, dev, IIC_WAIT | IIC_RECURSIVE);
if (error == 0)
error = TRANSFER_MSGS(dev, msgs);
if (error == 0) {
Index: sys/dev/ipmi/ipmi_isa.c
===================================================================
--- sys/dev/ipmi/ipmi_isa.c
+++ sys/dev/ipmi/ipmi_isa.c
@@ -286,3 +286,4 @@
};
DRIVER_MODULE(ipmi_isa, isa, ipmi_isa_driver, ipmi_devclass, 0, 0);
+MODULE_DEPEND(ipmi_isa, smbios, 1, 1, 1);
Index: sys/dev/ipmi/ipmi_pci.c
===================================================================
--- sys/dev/ipmi/ipmi_pci.c
+++ sys/dev/ipmi/ipmi_pci.c
@@ -179,6 +179,7 @@
};
DRIVER_MODULE(ipmi_pci, pci, ipmi_pci_driver, ipmi_devclass, 0, 0);
+MODULE_DEPEND(ipmi_pci, smbios, 1, 1, 1);
/* Native IPMI on PCI driver. */
Index: sys/dev/ipmi/ipmi_smbios.c
===================================================================
--- sys/dev/ipmi/ipmi_smbios.c
+++ sys/dev/ipmi/ipmi_smbios.c
@@ -39,7 +39,10 @@
#include <vm/vm.h>
#include <vm/pmap.h>
+#if defined(__amd64__) || defined(__i386__)
#include <machine/pc/bios.h>
+#endif
+#include <dev/smbios/smbios.h>
#ifdef LOCAL_MODULE
#include <ipmi.h>
@@ -84,8 +87,7 @@
MTX_SYSINIT(ipmi_info, &ipmi_info_mtx, "ipmi info", MTX_DEF);
static void ipmi_smbios_probe(struct ipmi_get_info *);
-static int smbios_cksum(struct smbios_eps *);
-static void smbios_walk_table(uint8_t *, int, smbios_callback_t,
+static void smbios_walk_table(uint8_t *, vm_size_t, smbios_callback_t,
void *);
static void smbios_ipmi_info(struct smbios_structure_header *, void *);
@@ -144,11 +146,12 @@
}
static void
-smbios_walk_table(uint8_t *p, int entries, smbios_callback_t cb, void *arg)
+smbios_walk_table(uint8_t *table, vm_size_t size, smbios_callback_t cb, void *arg)
{
struct smbios_structure_header *s;
+ uint8_t *p;
- while (entries--) {
+ for (p = table; p < table + size;) {
s = (struct smbios_structure_header *)p;
cb(s, arg);
@@ -157,8 +160,11 @@
* formatted area of this structure.
*/
p += s->length;
- while (!(p[0] == 0 && p[1] == 0))
+ while (!(p[0] == 0 && p[1] == 0)) {
p++;
+ if (p >= table + size)
+ return;
+ }
/*
* Skip over the double-nul to the start of the next
@@ -176,41 +182,23 @@
static void
ipmi_smbios_probe(struct ipmi_get_info *info)
{
- struct smbios_eps *header;
void *table;
- u_int32_t addr;
+ vm_paddr_t table_paddr;
+ vm_size_t table_size;
+ int err;
bzero(info, sizeof(struct ipmi_get_info));
- /* Find the SMBIOS table header. */
- addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
- SMBIOS_STEP, SMBIOS_OFF);
- if (addr == 0)
+ err = smbios_get_structure_table(&table_paddr, &table_size);
+ if (err != 0)
return;
- /*
- * Map the header. We first map a fixed size to get the actual
- * length and then map it a second time with the actual length so
- * we can verify the checksum.
- */
- header = pmap_mapbios(addr, sizeof(struct smbios_eps));
- table = pmap_mapbios(addr, header->length);
- pmap_unmapbios((vm_offset_t)header, sizeof(struct smbios_eps));
- header = table;
- if (smbios_cksum(header) != 0) {
- pmap_unmapbios((vm_offset_t)header, header->length);
- return;
- }
+ table = pmap_mapbios(table_paddr, table_size);
- /* Now map the actual table and walk it looking for an IPMI entry. */
- table = pmap_mapbios(header->structure_table_address,
- header->structure_table_length);
- smbios_walk_table(table, header->number_structures, smbios_ipmi_info,
- info);
+ smbios_walk_table(table, table_size, smbios_ipmi_info, info);
/* Unmap everything. */
- pmap_unmapbios((vm_offset_t)table, header->structure_table_length);
- pmap_unmapbios((vm_offset_t)header, header->length);
+ pmap_unmapbios((vm_offset_t)table, table_size);
}
/*
@@ -248,19 +236,3 @@
return (info->iface_type != 0);
}
-
-static int
-smbios_cksum(struct smbios_eps *e)
-{
- u_int8_t *ptr;
- u_int8_t cksum;
- int i;
-
- ptr = (u_int8_t *)e;
- cksum = 0;
- for (i = 0; i < e->length; i++) {
- cksum += ptr[i];
- }
-
- return (cksum);
-}
Index: sys/dev/ipmi/ipmi_smbus.c
===================================================================
--- sys/dev/ipmi/ipmi_smbus.c
+++ sys/dev/ipmi/ipmi_smbus.c
@@ -131,3 +131,8 @@
DRIVER_MODULE(ipmi_smbus, smbus, ipmi_smbus_driver, ipmi_devclass, 0, 0);
MODULE_DEPEND(ipmi_smbus, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_DEPEND(ipmi_smbus, smbios, 1, 1, 1);
+#if defined(__aarch64__)
+MODULE_DEPEND(ipmi_smbus, iicsmb, 1, 1, 1);
+MODULE_DEPEND(ipmi_smbus, ig4iic, 1, 1, 1);
+#endif
Index: sys/dev/ipmi/ipmi_ssif.c
===================================================================
--- sys/dev/ipmi/ipmi_ssif.c
+++ sys/dev/ipmi/ipmi_ssif.c
@@ -297,7 +297,7 @@
len += count - 1;
/* If this was the last block we are done. */
- if (ssif_buf[0] != 0xff)
+ if (ssif_buf[0] == 0xff)
break;
block++;
}
Index: sys/dev/smbios/smbios.h
===================================================================
--- sys/dev/smbios/smbios.h
+++ sys/dev/smbios/smbios.h
@@ -29,40 +29,10 @@
* $FreeBSD$
*/
-#ifndef _MACHINE_PC_BIOS_H_
-#define _MACHINE_PC_BIOS_H_
+#ifndef _SMBIOS_H_
+#define _SMBIOS_H_
-/*
- * Int 15:E820 'SMAP' structure
- */
-#define SMAP_SIG 0x534D4150 /* 'SMAP' */
-
-#define SMAP_TYPE_MEMORY 1
-#define SMAP_TYPE_RESERVED 2
-#define SMAP_TYPE_ACPI_RECLAIM 3
-#define SMAP_TYPE_ACPI_NVS 4
-#define SMAP_TYPE_ACPI_ERROR 5
-#define SMAP_TYPE_DISABLED 6
-#define SMAP_TYPE_PMEM 7
-#define SMAP_TYPE_PRAM 12
-
-#define SMAP_XATTR_ENABLED 0x00000001
-#define SMAP_XATTR_NON_VOLATILE 0x00000002
-#define SMAP_XATTR_MASK (SMAP_XATTR_ENABLED | SMAP_XATTR_NON_VOLATILE)
-
-struct bios_smap {
- u_int64_t base;
- u_int64_t length;
- u_int32_t type;
-} __packed;
-
-/* Structure extended to include extended attribute field in ACPI 3.0. */
-struct bios_smap_xattr {
- u_int64_t base;
- u_int64_t length;
- u_int32_t type;
- u_int32_t xattr;
-} __packed;
+int smbios_get_structure_table(vm_paddr_t *table, vm_size_t *size);
/*
* System Management BIOS
@@ -72,6 +42,8 @@
#define SMBIOS_OFF 0
#define SMBIOS_LEN 4
#define SMBIOS_SIG "_SM_"
+#define SMBIOS3_LEN 5
+#define SMBIOS3_SIG "_SM3_"
struct smbios_eps {
uint8_t anchor_string[4]; /* '_SM_' */
@@ -90,37 +62,23 @@
uint8_t BCD_revision;
};
+struct smbios3_eps {
+ uint8_t anchor_string[5]; /* '_SM3_' */
+ uint8_t checksum;
+ uint8_t length;
+ uint8_t major_version;
+ uint8_t minor_version;
+ uint8_t docrev;
+ uint8_t entry_point_revision;
+ uint8_t reserved;
+ uint32_t structure_table_max_size;
+ uint64_t structure_table_address;
+};
+
struct smbios_structure_header {
uint8_t type;
uint8_t length;
uint16_t handle;
};
-#ifdef _KERNEL
-#define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE)
-#define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE)
-
-struct bios_oem_signature {
- char * anchor; /* search anchor string in BIOS memory */
- size_t offset; /* offset from anchor (may be negative) */
- size_t totlen; /* total length of BIOS string to copy */
-} __packed;
-
-struct bios_oem_range {
- u_int from; /* shouldn't be below 0xe0000 */
- u_int to; /* shouldn't be above 0xfffff */
-} __packed;
-
-struct bios_oem {
- struct bios_oem_range range;
- struct bios_oem_signature signature[];
-} __packed;
-
-int bios_oem_strings(struct bios_oem *oem, u_char *buffer, size_t maxlen);
-uint32_t bios_sigsearch(uint32_t start, u_char *sig, int siglen, int paralen,
- int sigofs);
-void bios_add_smap_entries(struct bios_smap *smapbase, u_int32_t smapsize,
- vm_paddr_t *physmap, int *physmap_idx);
-#endif
-
-#endif /* _MACHINE_PC_BIOS_H_ */
+#endif /* _SMBIOS_H_ */
Index: sys/dev/smbios/smbios.c
===================================================================
--- sys/dev/smbios/smbios.c
+++ sys/dev/smbios/smbios.c
@@ -46,7 +46,12 @@
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <machine/md_var.h>
+#if defined(__amd64__) || defined(__i386__)
#include <machine/pc/bios.h>
+#endif
+#include <dev/smbios/smbios.h>
+
+static struct smbios_softc *smbios;
/*
* System Management BIOS Reference Specification, v2.4 Final
@@ -58,11 +63,15 @@
struct resource * res;
int rid;
- struct smbios_eps * eps;
+ union {
+ struct smbios_eps * eps;
+ struct smbios3_eps * eps3;
+ };
+ bool eps_64bit;
};
#define RES2EPS(res) ((struct smbios_eps *)rman_get_virtual(res))
-#define ADDR2EPS(addr) ((struct smbios_eps *)BIOS_PADDRTOVADDR(addr))
+#define RES2EPS3(res) ((struct smbios3_eps *)rman_get_virtual(res))
static devclass_t smbios_devclass;
@@ -72,30 +81,61 @@
static int smbios_detach (device_t);
static int smbios_modevent (module_t, int, void *);
-static int smbios_cksum (struct smbios_eps *);
+static bool smbios_eps_64bit(void *);
+static int smbios_cksum (void *);
static void
smbios_identify (driver_t *driver, device_t parent)
{
+ struct smbios3_eps *eps3;
+ struct smbios_eps *eps;
device_t child;
- u_int32_t addr;
+ vm_paddr_t addr;
int length;
int rid;
+ bool eps_64bit;
if (!device_is_alive(parent))
return;
- addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
- SMBIOS_STEP, SMBIOS_OFF);
+ if (resource_long_value("smbios3", 0, "mem", &addr) != 0) {
+#if defined(__amd64__) || defined(__i386__)
+ addr = bios_sigsearch(SMBIOS_START, SMBIOS3_SIG, SMBIOS3_LEN,
+ SMBIOS_STEP, SMBIOS_OFF);
+#else
+ addr = 0;
+#endif
+ }
+
if (addr != 0) {
+ eps_64bit = true;
+ } else {
+ eps_64bit = false;
+ if (resource_long_value("smbios", 0, "mem", &addr) != 0) {
+#if defined(__amd64__) || defined(__i386__)
+ addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN,
+ SMBIOS_STEP, SMBIOS_OFF);
+#else
+ addr = 0;
+#endif
+ }
+ }
+
+ if (addr != 0) {
+ if (eps_64bit) {
+ eps3 = pmap_mapbios(addr, 0x18);
+ length = eps3->length;
+ } else {
+ eps = pmap_mapbios(addr, 0x1f);
+ length = eps->length;
+ }
rid = 0;
- length = ADDR2EPS(addr)->length;
- if (length != 0x1f) {
+ if (!eps_64bit && length != 0x1f) {
u_int8_t major, minor;
- major = ADDR2EPS(addr)->major_version;
- minor = ADDR2EPS(addr)->minor_version;
+ major = eps->major_version;
+ minor = eps->minor_version;
/* SMBIOS v2.1 implementation might use 0x1e. */
if (length == 0x1e && major == 2 && minor == 1)
@@ -108,6 +148,11 @@
device_set_driver(child, driver);
bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length);
device_set_desc(child, "System Management BIOS");
+
+ if (eps_64bit)
+ pmap_unmapbios((vm_offset_t)eps3, 0x18);
+ else
+ pmap_unmapbios((vm_offset_t)eps, 0x1f);
}
return;
@@ -129,7 +174,7 @@
goto bad;
}
- if (smbios_cksum(RES2EPS(res))) {
+ if (smbios_cksum(rman_get_virtual(res))) {
device_printf(dev, "SMBIOS checksum failed.\n");
error = ENXIO;
goto bad;
@@ -159,16 +204,24 @@
error = ENOMEM;
goto bad;
}
- sc->eps = RES2EPS(sc->res);
-
- device_printf(dev, "Version: %u.%u",
- sc->eps->major_version, sc->eps->minor_version);
- if (bcd2bin(sc->eps->BCD_revision))
- printf(", BCD Revision: %u.%u",
- bcd2bin(sc->eps->BCD_revision >> 4),
- bcd2bin(sc->eps->BCD_revision & 0x0f));
+ sc->eps_64bit = smbios_eps_64bit(rman_get_virtual(sc->res));
+
+ if (sc->eps_64bit) {
+ sc->eps3 = RES2EPS3(sc->res);
+ device_printf(dev, "Version: %u.%u",
+ sc->eps3->major_version, sc->eps3->minor_version);
+ } else {
+ sc->eps = RES2EPS(sc->res);
+ device_printf(dev, "Version: %u.%u",
+ sc->eps->major_version, sc->eps->minor_version);
+ if (bcd2bin(sc->eps->BCD_revision))
+ printf(", BCD Revision: %u.%u",
+ bcd2bin(sc->eps->BCD_revision >> 4),
+ bcd2bin(sc->eps->BCD_revision & 0x0f));
+ }
printf("\n");
+ smbios = sc;
return (0);
bad:
if (sc->res)
@@ -181,6 +234,7 @@
{
struct smbios_softc *sc;
+ smbios = NULL;
sc = device_get_softc(dev);
if (sc->res)
@@ -189,6 +243,23 @@
return (0);
}
+int
+smbios_get_structure_table(vm_paddr_t *table, vm_size_t *size)
+{
+
+ if (smbios == NULL)
+ return (ENXIO);
+ if (smbios->eps_64bit) {
+ *table = smbios->eps3->structure_table_address;
+ *size = smbios->eps3->structure_table_max_size;
+ } else {
+ *table = smbios->eps->structure_table_address;
+ *size = smbios->eps->structure_table_length;
+ }
+ return (0);
+}
+
+
static int
smbios_modevent (mod, what, arg)
module_t mod;
@@ -234,16 +305,35 @@
DRIVER_MODULE(smbios, nexus, smbios_driver, smbios_devclass, smbios_modevent, 0);
MODULE_VERSION(smbios, 1);
+static bool
+smbios_eps_64bit (void *v)
+{
+ struct smbios3_eps *e;
+
+ e = (struct smbios3_eps *)v;
+ return (memcmp(e->anchor_string, SMBIOS3_SIG, SMBIOS3_LEN) == 0);
+}
+
static int
-smbios_cksum (struct smbios_eps *e)
+smbios_cksum (void *v)
{
+ struct smbios3_eps *eps3;
+ struct smbios_eps *eps;
u_int8_t *ptr;
u_int8_t cksum;
+ u_int8_t length;
int i;
- ptr = (u_int8_t *)e;
+ if (smbios_eps_64bit(v)) {
+ eps3 = (struct smbios3_eps *)v;
+ length = eps3->length;
+ } else {
+ eps = (struct smbios_eps *)v;
+ length = eps->length;
+ }
+ ptr = (u_int8_t *)v;
cksum = 0;
- for (i = 0; i < e->length; i++) {
+ for (i = 0; i < length; i++) {
cksum += ptr[i];
}
Index: sys/i386/conf/GENERIC
===================================================================
--- sys/i386/conf/GENERIC
+++ sys/i386/conf/GENERIC
@@ -115,6 +115,7 @@
# Bus support.
device acpi
+device smbios
device pci
options PCI_HP # PCI-Express native HotPlug
options PCI_IOV # PCI SR-IOV support
Index: sys/i386/conf/MINIMAL
===================================================================
--- sys/i386/conf/MINIMAL
+++ sys/i386/conf/MINIMAL
@@ -104,6 +104,7 @@
# Bus support.
device acpi
+device smbios
device pci
# atkbdc0 controls both the keyboard and the PS/2 mouse
Index: sys/i386/include/pc/bios.h
===================================================================
--- sys/i386/include/pc/bios.h
+++ sys/i386/include/pc/bios.h
@@ -234,38 +234,6 @@
u_int32_t xattr;
} __packed;
-/*
- * System Management BIOS
- */
-#define SMBIOS_START 0xf0000
-#define SMBIOS_STEP 0x10
-#define SMBIOS_OFF 0
-#define SMBIOS_LEN 4
-#define SMBIOS_SIG "_SM_"
-
-struct smbios_eps {
- uint8_t anchor_string[4]; /* '_SM_' */
- uint8_t checksum;
- uint8_t length;
- uint8_t major_version;
- uint8_t minor_version;
- uint16_t maximum_structure_size;
- uint8_t entry_point_revision;
- uint8_t formatted_area[5];
- uint8_t intermediate_anchor_string[5]; /* '_DMI_' */
- uint8_t intermediate_checksum;
- uint16_t structure_table_length;
- uint32_t structure_table_address;
- uint16_t number_structures;
- uint8_t BCD_revision;
-};
-
-struct smbios_structure_header {
- uint8_t type;
- uint8_t length;
- uint16_t handle;
-};
-
#ifdef _KERNEL
#define BIOS_PADDRTOVADDR(x) ((x) + PMAP_MAP_LOW)
#define BIOS_VADDRTOPADDR(x) ((x) - PMAP_MAP_LOW)
Index: sys/modules/bios/smbios/Makefile
===================================================================
--- sys/modules/bios/smbios/Makefile
+++ sys/modules/bios/smbios/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
#
-.PATH: ${SRCTOP}/sys/x86/bios
+.PATH: ${SRCTOP}/sys/dev/smbios
KMOD= smbios
SRCS= smbios.c \
Index: sys/modules/ipmi/Makefile
===================================================================
--- sys/modules/ipmi/Makefile
+++ sys/modules/ipmi/Makefile
@@ -14,12 +14,17 @@
SRCS+= ipmi_acpi.c
SRCS+= opt_acpi.h
SRCS+= acpi_if.h
+SRCS+= ipmi_smbios.c
+SRCS+= ipmi_ssif.c
+SRCS+= ipmi_pci.c
+SRCS+= ipmi_smbus.c
+SRCS+= pci_if.h
+SRCS+= smbus_if.h
.endif
.if ${MACHINE_CPUARCH} == "i386" || ${MACHINE_CPUARCH} == "amd64"
-SRCS+= ipmi_smbios.c ipmi_ssif.c
-SRCS+= ipmi_isa.c ipmi_pci.c ipmi_smbus.c
-SRCS+= isa_if.h pci_if.h smbus_if.h
+SRCS+= ipmi_isa.c
+SRCS+= isa_if.h
SUBDIR+= ipmi_linux

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 30, 6:12 AM (20 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17852668
Default Alt Text
D28707.diff (26 KB)

Event Timeline