xref: /freebsd/tools/boot/smbios/main.c (revision 9f27341c336aa12f6c7163c17e646e76c813b689)
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 
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
62 cleanup(void)
63 {
64 	for (int i = 0; i < nmap; i++) {
65 		munmap(map[i].va, PAGE);
66 	}
67 }
68 
69 int
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
77 usage(void)
78 {
79 	errx(1, "smbios address");
80 }
81 
82 int
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