Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch search SMBIOS from UEFI configuration table when bo...
details: https://anonhg.NetBSD.org/src/rev/4dd8786e2be8
branches: trunk
changeset: 352029:4dd8786e2be8
user: nonaka <nonaka%NetBSD.org@localhost>
date: Sat Mar 11 07:21:10 2017 +0000
description:
search SMBIOS from UEFI configuration table when boot with UEFI.
diffstat:
sys/arch/amd64/amd64/bios32.c | 180 +++++++++++++++++++++++++++++---------
sys/arch/i386/i386/bios32.c | 178 ++++++++++++++++++++++++++++++--------
sys/arch/x86/include/efi.h | 13 ++-
sys/arch/x86/include/smbiosvar.h | 41 ++++++--
sys/arch/x86/x86/efi.c | 28 ++---
5 files changed, 328 insertions(+), 112 deletions(-)
diffs (truncated from 606 to 300 lines):
diff -r 9ba2dc9a46ac -r 4dd8786e2be8 sys/arch/amd64/amd64/bios32.c
--- a/sys/arch/amd64/amd64/bios32.c Sat Mar 11 07:10:37 2017 +0000
+++ b/sys/arch/amd64/amd64/bios32.c Sat Mar 11 07:21:10 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bios32.c,v 1.21 2015/11/22 13:41:24 maxv Exp $ */
+/* $NetBSD: bios32.c,v 1.22 2017/03/11 07:21:10 nonaka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.21 2015/11/22 13:41:24 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.22 2017/03/11 07:21:10 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +72,7 @@
#include <machine/segments.h>
#include <machine/bios32.h>
#include <x86/smbiosvar.h>
+#include <x86/efi.h>
#include <uvm/uvm.h>
@@ -85,6 +86,11 @@
struct bios32_entry bios32_entry;
struct smbios_entry smbios_entry;
+static int smbios2_check_header(const uint8_t *);
+static void smbios2_map_kva(const uint8_t *);
+static int smbios3_check_header(const uint8_t *);
+static void smbios3_map_kva(const uint8_t *);
+
/*
* Initialize the BIOS32 interface.
*/
@@ -132,59 +138,147 @@
}
#endif
uint8_t *p;
- int i;
/* see if we have SMBIOS extentions */
+#ifndef XEN
+ if (efi_probe()) {
+ p = efi_getcfgtbl(&EFI_UUID_SMBIOS3);
+ if (p != NULL && smbios3_check_header(p)) {
+ smbios3_map_kva(p);
+ return;
+ }
+ p = efi_getcfgtbl(&EFI_UUID_SMBIOS);
+ if (p != NULL && smbios2_check_header(p)) {
+ smbios2_map_kva(p);
+ return;
+ }
+ }
+#endif
for (p = ISA_HOLE_VADDR(SMBIOS_START);
p < (uint8_t *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) {
- struct smbhdr * sh = (struct smbhdr *)p;
- uint8_t chksum;
- vaddr_t eva;
- paddr_t pa, end;
+ if (smbios3_check_header(p)) {
+ smbios3_map_kva(p);
+ return;
+ }
+ if (smbios2_check_header(p)) {
+ smbios2_map_kva(p);
+ return;
+ }
+ }
+}
+
+static int
+smbios2_check_header(const uint8_t *p)
+{
+ const struct smbhdr *sh = (const struct smbhdr *)p;
+ uint8_t chksum;
+ int i;
- if (sh->sig != BIOS32_MAKESIG('_', 'S', 'M', '_'))
- continue;
- i = sh->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;
+ if (sh->sig != BIOS32_MAKESIG('_', 'S', 'M', '_'))
+ return 0;
+ i = sh->len;
+ for (chksum = 0; i--; )
+ chksum += p[i];
+ if (chksum != 0)
+ return 0;
+ p += 0x10;
+ if (p[0] != '_' || p[1] != 'D' || p[2] != 'M' ||
+ p[3] != 'I' || p[4] != '_')
+ return 0;
+ for (chksum = 0, i = 0xf; i--; )
+ chksum += p[i];
+ if (chksum != 0)
+ return 0;
+
+ return 1;
+}
+
+static void
+smbios2_map_kva(const uint8_t *p)
+{
+ const struct smbhdr *sh = (const struct smbhdr *)p;
+ paddr_t pa, end;
+ vaddr_t eva;
+
+ pa = trunc_page(sh->addr);
+ end = round_page(sh->addr + sh->size);
+ eva = uvm_km_alloc(kernel_map, end - pa, 0, UVM_KMF_VAONLY);
+ if (eva == 0)
+ return;
+
+ smbios_entry.addr = (uint8_t *)(eva + (sh->addr & PGOFSET));
+ smbios_entry.len = sh->size;
+ smbios_entry.rev = 0;
+ smbios_entry.mjr = sh->majrev;
+ smbios_entry.min = sh->minrev;
+ smbios_entry.doc = 0;
+ smbios_entry.count = sh->count;
- pa = trunc_page(sh->addr);
- end = round_page(sh->addr + sh->size);
- eva = uvm_km_alloc(kernel_map, end - pa, 0, UVM_KMF_VAONLY);
- if (eva == 0)
- break;
+ for (; pa < end; pa+= NBPG, eva+= NBPG)
+#ifdef XEN
+ pmap_kenter_ma(eva, pa, VM_PROT_READ, 0);
+#else
+ pmap_kenter_pa(eva, pa, VM_PROT_READ, 0);
+#endif
+ pmap_update(pmap_kernel());
+
+ aprint_debug("SMBIOS rev. %d.%d @ 0x%lx (%d entries)\n",
+ sh->majrev, sh->minrev, (u_long)sh->addr,
+ sh->count);
+}
- smbios_entry.addr = (uint8_t *)(eva +
- (sh->addr & PGOFSET));
- smbios_entry.len = sh->size;
- smbios_entry.mjr = sh->majrev;
- smbios_entry.min = sh->minrev;
- smbios_entry.count = sh->count;
+static int
+smbios3_check_header(const uint8_t *p)
+{
+ const struct smb3hdr *sh = (const struct smb3hdr *)p;
+ uint8_t chksum;
+ int i;
+
+ if (p[0] != '_' || p[1] != 'S' || p[2] != 'M' ||
+ p[3] != '3' || p[4] != '_')
+ return 0;
+ i = sh->len;
+ for (chksum = 0; i--; )
+ chksum += p[i];
+ if (chksum != 0)
+ return 0;
+ if (sh->eprev != SMBIOS3_EPREV_3_0)
+ return 0;
- for (; pa < end; pa+= NBPG, eva+= NBPG)
+ return 1;
+}
+
+static void
+smbios3_map_kva(const uint8_t *p)
+{
+ const struct smb3hdr *sh = (const struct smb3hdr *)p;
+ paddr_t pa, end;
+ vaddr_t eva;
+
+ pa = trunc_page(sh->addr);
+ end = round_page(sh->addr + sh->size);
+ eva = uvm_km_alloc(kernel_map, end - pa, 0, UVM_KMF_VAONLY);
+ if (eva == 0)
+ return;
+
+ smbios_entry.addr = (uint8_t *)(eva + (sh->addr & PGOFSET));
+ smbios_entry.len = sh->size;
+ smbios_entry.rev = sh->eprev;
+ smbios_entry.mjr = sh->majrev;
+ smbios_entry.min = sh->minrev;
+ smbios_entry.doc = sh->docrev;
+ smbios_entry.count = UINT16_MAX;
+
+ for (; pa < end; pa += NBPG, eva += NBPG)
#ifdef XEN
- pmap_kenter_ma(eva, pa, VM_PROT_READ, 0);
+ pmap_kenter_ma(eva, pa, VM_PROT_READ, 0);
#else
- pmap_kenter_pa(eva, pa, VM_PROT_READ, 0);
+ pmap_kenter_pa(eva, pa, VM_PROT_READ, 0);
#endif
- pmap_update(pmap_kernel());
+ pmap_update(pmap_kernel());
- aprint_debug("SMBIOS rev. %d.%d @ 0x%lx (%d entries)\n",
- sh->majrev, sh->minrev, (u_long)sh->addr,
- sh->count);
-
- break;
- }
+ aprint_debug("SMBIOS rev. %d.%d.%d @ 0x%lx\n",
+ sh->majrev, sh->minrev, sh->docrev, (u_long)sh->addr);
}
/*
diff -r 9ba2dc9a46ac -r 4dd8786e2be8 sys/arch/i386/i386/bios32.c
--- a/sys/arch/i386/i386/bios32.c Sat Mar 11 07:10:37 2017 +0000
+++ b/sys/arch/i386/i386/bios32.c Sat Mar 11 07:21:10 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bios32.c,v 1.29 2012/06/15 23:01:16 joerg Exp $ */
+/* $NetBSD: bios32.c,v 1.30 2017/03/11 07:21:10 nonaka Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -86,7 +86,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.29 2012/06/15 23:01:16 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.30 2017/03/11 07:21:10 nonaka Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -99,6 +99,7 @@
#include <machine/segments.h>
#include <machine/bios32.h>
#include <x86/smbiosvar.h>
+#include <x86/efi.h>
#include <uvm/uvm.h>
@@ -112,6 +113,11 @@
struct bios32_entry bios32_entry;
struct smbios_entry smbios_entry;
+static int smbios2_check_header(const uint8_t *);
+static void smbios2_map_kva(const uint8_t *);
+static int smbios3_check_header(const uint8_t *);
+static void smbios3_map_kva(const uint8_t *);
+
/*
* Initialize the BIOS32 interface.
*/
@@ -156,57 +162,153 @@
bios32_entry.offset = (void *)ISA_HOLE_VADDR(entry);
bios32_entry.segment = GSEL(GCODE_SEL, SEL_KPL);
}
+
/* see if we have SMBIOS extensions */
+#ifndef XEN
+ if (efi_probe()) {
+ p = efi_getcfgtbl(&EFI_UUID_SMBIOS3);
+ if (p != NULL && smbios3_check_header(p)) {
+ smbios3_map_kva(p);
+ goto out;
+ }
+ p = efi_getcfgtbl(&EFI_UUID_SMBIOS);
+ if (p != NULL && smbios2_check_header(p)) {
+ smbios2_map_kva(p);
+ goto out;
+ }
+ }
+#endif
for (p = ISA_HOLE_VADDR(SMBIOS_START);
p < (char *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) {
- struct smbhdr * sh = (struct smbhdr *)p;
- uint8_t chksum;
- vaddr_t eva;
- paddr_t pa, end;
+ if (smbios3_check_header(p)) {
+ smbios3_map_kva(p);
+ goto out;
+ } else if (smbios2_check_header(p)) {
+ smbios2_map_kva(p);
+ goto out;
+ }
+ }
+#ifndef XEN
Home |
Main Index |
Thread Index |
Old Index