Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src smbios: Add character device for accessing SMBIOS tables
details: https://anonhg.NetBSD.org/src/rev/e258dffce9fd
branches: trunk
changeset: 984800:e258dffce9fd
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat Jul 24 11:39:18 2021 +0000
description:
smbios: Add character device for accessing SMBIOS tables
The /dev/smbios character device gives an aperture into physical memory
that allows read-only access to the SMBIOS header and tables.
diffstat:
etc/MAKEDEV.tmpl | 6 ++-
etc/etc.aarch64/MAKEDEV.conf | 3 +-
etc/etc.amd64/MAKEDEV.conf | 3 +-
etc/etc.i386/MAKEDEV.conf | 3 +-
sys/arch/arm/fdt/acpi_fdt.c | 8 ++-
sys/arch/x86/x86/bios32.c | 8 ++-
sys/conf/majors | 3 +-
sys/dev/smbios.c | 105 ++++++++++++++++++++++++++++++++++++++++++-
sys/dev/smbiosvar.h | 4 +-
9 files changed, 131 insertions(+), 12 deletions(-)
diffs (truncated from 314 to 300 lines):
diff -r 619c95ea3422 -r e258dffce9fd etc/MAKEDEV.tmpl
--- a/etc/MAKEDEV.tmpl Sat Jul 24 11:36:41 2021 +0000
+++ b/etc/MAKEDEV.tmpl Sat Jul 24 11:39:18 2021 +0000
@@ -1,5 +1,5 @@
#!/bin/sh -
-# $NetBSD: MAKEDEV.tmpl,v 1.223 2021/06/29 10:22:33 nia Exp $
+# $NetBSD: MAKEDEV.tmpl,v 1.224 2021/07/24 11:39:18 jmcneill Exp $
#
# Copyright (c) 2003,2007,2008 The NetBSD Foundation, Inc.
# All rights reserved.
@@ -2240,6 +2240,10 @@
mkdev acpi c %acpi_chr% 0
;;
+smbios)
+ mkdev smbios c %smbios_chr% 0
+ ;;
+
midevend)
%MI_DEVICES_END%
local)
diff -r 619c95ea3422 -r e258dffce9fd etc/etc.aarch64/MAKEDEV.conf
--- a/etc/etc.aarch64/MAKEDEV.conf Sat Jul 24 11:36:41 2021 +0000
+++ b/etc/etc.aarch64/MAKEDEV.conf Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: MAKEDEV.conf,v 1.8 2020/12/06 02:57:30 jmcneill Exp $
+# $NetBSD: MAKEDEV.conf,v 1.9 2021/07/24 11:39:18 jmcneill Exp $
all_md)
makedev wscons fd0 fd1 wd0 wd1 wd2 wd3 sd0 sd1 sd2 sd3
@@ -21,6 +21,7 @@
makedev bpf
makedev openfirm
makedev acpi
+ makedev smbios
;;
ramdisk|floppy)
diff -r 619c95ea3422 -r e258dffce9fd etc/etc.amd64/MAKEDEV.conf
--- a/etc/etc.amd64/MAKEDEV.conf Sat Jul 24 11:36:41 2021 +0000
+++ b/etc/etc.amd64/MAKEDEV.conf Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: MAKEDEV.conf,v 1.32 2020/12/06 02:57:30 jmcneill Exp $
+# $NetBSD: MAKEDEV.conf,v 1.33 2021/07/24 11:39:18 jmcneill Exp $
# As of 2003-04-17, the "init" case must not create more than 890 entries.
all_md)
@@ -46,6 +46,7 @@
makedev bio
makedev xmm0
makedev acpi
+ makedev smbios
;;
xen)
diff -r 619c95ea3422 -r e258dffce9fd etc/etc.i386/MAKEDEV.conf
--- a/etc/etc.i386/MAKEDEV.conf Sat Jul 24 11:36:41 2021 +0000
+++ b/etc/etc.i386/MAKEDEV.conf Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: MAKEDEV.conf,v 1.33 2020/12/06 02:57:30 jmcneill Exp $
+# $NetBSD: MAKEDEV.conf,v 1.34 2021/07/24 11:39:19 jmcneill Exp $
# As of 2005-03-15, the "init" case must not create more than 1024 entries.
all_md)
@@ -50,6 +50,7 @@
makedev bio
makedev cfs
makedev acpi
+ makedev smbios
;;
xen)
diff -r 619c95ea3422 -r e258dffce9fd sys/arch/arm/fdt/acpi_fdt.c
--- a/sys/arch/arm/fdt/acpi_fdt.c Sat Jul 24 11:36:41 2021 +0000
+++ b/sys/arch/arm/fdt/acpi_fdt.c Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_fdt.c,v 1.21 2021/07/23 21:33:35 jmcneill Exp $ */
+/* $NetBSD: acpi_fdt.c,v 1.22 2021/07/24 11:39:19 jmcneill Exp $ */
/*-
* Copyright (c) 2015-2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -30,7 +30,7 @@
#include "opt_efi.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_fdt.c,v 1.21 2021/07/23 21:33:35 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_fdt.c,v 1.22 2021/07/24 11:39:19 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -179,6 +179,8 @@
return;
}
+ smbios_entry.hdrphys = smbios_table;
+
smbver = acpi_fdt_smbios_version();
if (smbver == 3) {
struct smb3hdr *sh = AcpiOsMapMemory(smbios_table, sizeof(*sh));
@@ -188,6 +190,7 @@
ptr = AcpiOsMapMemory(sh->addr, sh->size);
if (ptr != NULL) {
+ smbios_entry.tabphys = sh->addr;
smbios_entry.addr = ptr;
smbios_entry.len = sh->size;
smbios_entry.rev = sh->eprev;
@@ -208,6 +211,7 @@
ptr = AcpiOsMapMemory(sh->addr, sh->size);
if (ptr != NULL) {
+ smbios_entry.tabphys = sh->addr;
smbios_entry.addr = ptr;
smbios_entry.len = sh->size;
smbios_entry.rev = 0;
diff -r 619c95ea3422 -r e258dffce9fd sys/arch/x86/x86/bios32.c
--- a/sys/arch/x86/x86/bios32.c Sat Jul 24 11:36:41 2021 +0000
+++ b/sys/arch/x86/x86/bios32.c Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bios32.c,v 1.5 2021/07/21 23:16:09 jmcneill Exp $ */
+/* $NetBSD: bios32.c,v 1.6 2021/07/24 11:39:19 jmcneill Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -86,7 +86,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.5 2021/07/21 23:16:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bios32.c,v 1.6 2021/07/24 11:39:19 jmcneill Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -252,6 +252,8 @@
if (eva == 0)
return;
+ smbios_entry.hdrphys = vtophys(p);
+ smbios_entry.tabphys = sh->addr;
smbios_entry.addr = (uint8_t *)(eva + (sh->addr & PGOFSET));
smbios_entry.len = sh->size;
smbios_entry.rev = 0;
@@ -285,6 +287,8 @@
if (eva == 0)
return;
+ smbios_entry.hdrphys = vtophys(p);
+ smbios_entry.tabphys = sh->addr;
smbios_entry.addr = (uint8_t *)(eva + ((vaddr_t)sh->addr & PGOFSET));
smbios_entry.len = sh->size;
smbios_entry.rev = sh->eprev;
diff -r 619c95ea3422 -r e258dffce9fd sys/conf/majors
--- a/sys/conf/majors Sat Jul 24 11:36:41 2021 +0000
+++ b/sys/conf/majors Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: majors,v 1.97 2020/12/06 02:57:30 jmcneill Exp $
+# $NetBSD: majors,v 1.98 2021/07/24 11:39:19 jmcneill Exp $
#
# Device majors for Machine-Independent drivers.
#
@@ -91,3 +91,4 @@
device-major fault char 357 fault
device-major wwanc char 358 wwanc
device-major acpi char 359 acpi
+device-major smbios char 360 smbios
diff -r 619c95ea3422 -r e258dffce9fd sys/dev/smbios.c
--- a/sys/dev/smbios.c Sat Jul 24 11:36:41 2021 +0000
+++ b/sys/dev/smbios.c Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: smbios.c,v 1.1 2021/07/21 23:16:09 jmcneill Exp $ */
+/* $NetBSD: smbios.c,v 1.2 2021/07/24 11:39:19 jmcneill Exp $ */
/*
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -86,12 +86,15 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: smbios.c,v 1.1 2021/07/21 23:16:09 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: smbios.c,v 1.2 2021/07/24 11:39:19 jmcneill Exp $");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <uvm/uvm_extern.h>
+
#include <dev/smbiosvar.h>
#define SMBIOS_MAKESIG(a, b, c, d) \
@@ -99,6 +102,104 @@
struct smbios_entry smbios_entry;
+static dev_type_read(smbios_read);
+
+const struct cdevsw smbios_cdevsw = {
+ .d_open = nullopen,
+ .d_close = nullclose,
+ .d_read = smbios_read,
+ .d_write = nowrite,
+ .d_ioctl = noioctl,
+ .d_stop = nostop,
+ .d_tty = notty,
+ .d_poll = nopoll,
+ .d_mmap = nommap,
+ .d_kqfilter = nokqfilter,
+ .d_discard = nodiscard,
+ .d_flag = D_OTHER | D_MPSAFE,
+};
+
+static void *
+smbios_map_memory(paddr_t pa, size_t size)
+{
+ paddr_t spa, epa, curpa;
+ vaddr_t va, curva;
+
+ spa = trunc_page(pa);
+ epa = round_page(pa + size);
+
+ va = uvm_km_alloc(kernel_map, epa - spa, 0, UVM_KMF_VAONLY);
+ if (va == 0) {
+ return NULL;
+ }
+
+ for (curpa = spa, curva = va; curpa < epa; curpa += PAGE_SIZE, curva += PAGE_SIZE) {
+ pmap_kenter_pa(curva, curpa, VM_PROT_READ, PMAP_WRITE_BACK);
+ }
+ pmap_update(pmap_kernel());
+
+ return (void *)(va + (pa - spa));
+}
+
+static void
+smbios_unmap_memory(void *va, size_t size)
+{
+ vaddr_t ova;
+ vsize_t osz;
+
+ ova = trunc_page((vaddr_t)va);
+ osz = round_page((vaddr_t)va + size) - ova;
+
+ pmap_kremove(ova, osz);
+ pmap_update(pmap_kernel());
+ uvm_km_free(kernel_map, ova, osz, UVM_KMF_VAONLY);
+}
+
+/*
+ * smbios_read --
+ *
+ * Read data from an SMBIOS table that resides in physical memory.
+ */
+static int
+smbios_read(dev_t dev, struct uio *uio, int flag)
+{
+ paddr_t pa;
+ uint8_t *data;
+ size_t len;
+ int error;
+
+ if (smbios_entry.addr == NULL) {
+ return EIO;
+ }
+ if (uio->uio_rw != UIO_READ) {
+ return EPERM;
+ }
+
+ pa = uio->uio_offset;
+ if (pa == smbios_entry.hdrphys) {
+ /* SMBIOS header */
+ len = uimin(0x20, uio->uio_resid);
+
+ } else {
+ /* Table data */
+ if (pa < smbios_entry.tabphys ||
+ pa >= smbios_entry.tabphys + smbios_entry.len) {
+ return EFAULT;
+ }
+ len = uimin(smbios_entry.len - (pa - smbios_entry.tabphys),
+ uio->uio_resid);
+ }
+
+ data = smbios_map_memory(pa, len);
+ if (data == NULL) {
+ return ENOMEM;
+ }
+ error = uiomove(data, len, uio);
+ smbios_unmap_memory(data, len);
+
+ return error;
+}
+
int
smbios2_check_header(const uint8_t *p)
{
diff -r 619c95ea3422 -r e258dffce9fd sys/dev/smbiosvar.h
--- a/sys/dev/smbiosvar.h Sat Jul 24 11:36:41 2021 +0000
+++ b/sys/dev/smbiosvar.h Sat Jul 24 11:39:18 2021 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index