1 /*
2 * Copyright (c) 2023 Warner Losh
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7 /*
8 * Test program for smbios support in the boot loader. This program will mmap
9 * physical memory, and print the smbios table at the passed in PA. This is
10 * intended to test the code and debug problems in a debugger friendly
11 * environment.
12 */
13
14 #include <sys/param.h>
15 #define setenv my_setenv
16
17 #define SMBIOS_SERIAL_NUMBERS 1
18 #define SMBIOS_LITTLE_ENDIAN_UUID 1
19
20 #include <arpa/inet.h>
21
22 #include "smbios.h"
23 #include "smbios.c"
24
25 #include <sys/mman.h>
26
27 #define MAX_MAP 10
28 #define PAGE (64<<10)
29
30 static struct mapping
31 {
32 uintptr_t pa;
33 caddr_t va;
34 } map[MAX_MAP];
35 static int fd;
36 static int nmap;
37
ptov(uintptr_t pa)38 caddr_t ptov(uintptr_t pa)
39 {
40 caddr_t va;
41 uintptr_t pa2;
42 struct mapping *m = map;
43
44 pa2 = rounddown(pa, PAGE);
45 for (int i = 0; i < nmap; i++, m++) {
46 if (m->pa == pa2) {
47 return (m->va + pa - m->pa);
48 }
49 }
50 if (nmap == MAX_MAP)
51 errx(1, "Too many maps");
52 va = mmap(0, PAGE, PROT_READ, MAP_SHARED, fd, pa2);
53 if (va == MAP_FAILED)
54 err(1, "mmap offset %#lx", (long)pa2);
55 m = &map[nmap++];
56 m->pa = pa2;
57 m->va = va;
58 return (m->va + pa - m->pa);
59 }
60
61 static void
cleanup(void)62 cleanup(void)
63 {
64 for (int i = 0; i < nmap; i++) {
65 munmap(map[i].va, PAGE);
66 }
67 }
68
69 int
my_setenv(const char * name,const char * value,int overwrite __unused)70 my_setenv(const char *name, const char *value, int overwrite __unused)
71 {
72 printf("%s=%s\n", name, value);
73 return 0;
74 }
75
76 static void
usage(void)77 usage(void)
78 {
79 errx(1, "smbios address");
80 }
81
82 int
main(int argc,char ** argv)83 main(int argc, char **argv)
84 {
85 uintptr_t addr;
86
87 if (argc != 2)
88 usage();
89 addr = strtoull(argv[1], NULL, 0);
90 /* For mmap later */
91 fd = open("/dev/mem", O_RDONLY);
92 if (fd < 0)
93 err(1, "Opening /dev/mem");
94 smbios_detect(ptov(addr));
95 cleanup();
96 }
97