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