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/d44507f509b9
branches:  trunk
changeset: 1022529:d44507f509b9
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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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 91f971f13cd2 -r d44507f509b9 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