Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115828508
D28707.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D28707.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D28707: Fix attachment of IPMI driver on ARM64
Attached
Detach File
Event Timeline
Log In to Comment