Fri Jul 23 21:33:00 2021 UTC ()
efiboot: Add support for SMBIOS 2.x tables.


(jmcneill)
diff -r1.9 -r1.10 src/sys/stand/efiboot/efiacpi.c
diff -r1.2 -r1.3 src/sys/stand/efiboot/smbios.c

cvs diff -r1.9 -r1.10 src/sys/stand/efiboot/efiacpi.c (expand / switch to unified diff)

--- src/sys/stand/efiboot/efiacpi.c 2021/05/21 21:53:15 1.9
+++ src/sys/stand/efiboot/efiacpi.c 2021/07/23 21:33:00 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: efiacpi.c,v 1.9 2021/05/21 21:53:15 jmcneill Exp $ */ 1/* $NetBSD: efiacpi.c,v 1.10 2021/07/23 21:33:00 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 4 * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared McNeill <jmcneill@invisible.ca>. 8 * by Jared McNeill <jmcneill@invisible.ca>.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -42,43 +42,48 @@ struct acpi_rdsp { @@ -42,43 +42,48 @@ struct acpi_rdsp {
42 uint32_t rsdtphys; 42 uint32_t rsdtphys;
43 uint32_t length; 43 uint32_t length;
44 uint64_t xsdtphys; 44 uint64_t xsdtphys;
45 uint8_t extcsum; 45 uint8_t extcsum;
46 uint8_t reserved[3]; 46 uint8_t reserved[3];
47}; 47};
48 48
49#include <libfdt.h> 49#include <libfdt.h>
50 50
51#define ACPI_FDT_SIZE (128 * 1024) 51#define ACPI_FDT_SIZE (128 * 1024)
52 52
53static EFI_GUID Acpi20TableGuid = ACPI_20_TABLE_GUID; 53static EFI_GUID Acpi20TableGuid = ACPI_20_TABLE_GUID;
54static EFI_GUID Smbios3TableGuid = SMBIOS3_TABLE_GUID; 54static EFI_GUID Smbios3TableGuid = SMBIOS3_TABLE_GUID;
 55static EFI_GUID SmbiosTableGuid = SMBIOS_TABLE_GUID;
55 56
56static int acpi_enable = 1; 57static int acpi_enable = 1;
57static void *acpi_root = NULL; 58static void *acpi_root = NULL;
58static void *smbios3_table = NULL; 59static void *smbios_table = NULL;
59 60
60int 61int
61efi_acpi_probe(void) 62efi_acpi_probe(void)
62{ 63{
63 EFI_STATUS status; 64 EFI_STATUS status;
64 65
65 status = LibGetSystemConfigurationTable(&Acpi20TableGuid, &acpi_root); 66 status = LibGetSystemConfigurationTable(&Acpi20TableGuid, &acpi_root);
66 if (EFI_ERROR(status)) 67 if (EFI_ERROR(status))
67 return EIO; 68 return EIO;
68 69
69 status = LibGetSystemConfigurationTable(&Smbios3TableGuid, &smbios3_table); 70 status = LibGetSystemConfigurationTable(&Smbios3TableGuid, &smbios_table);
70 if (EFI_ERROR(status)) 71 if (EFI_ERROR(status)) {
71 smbios3_table = NULL; 72 status = LibGetSystemConfigurationTable(&SmbiosTableGuid, &smbios_table);
 73 }
 74 if (EFI_ERROR(status)) {
 75 smbios_table = NULL;
 76 }
72 77
73 return 0; 78 return 0;
74} 79}
75 80
76int 81int
77efi_acpi_available(void) 82efi_acpi_available(void)
78{ 83{
79 return acpi_root != NULL; 84 return acpi_root != NULL;
80} 85}
81 86
82int 87int
83efi_acpi_enabled(void) 88efi_acpi_enabled(void)
84{ 89{
@@ -93,28 +98,28 @@ efi_acpi_enable(int enable) @@ -93,28 +98,28 @@ efi_acpi_enable(int enable)
93 98
94static char model_buf[128]; 99static char model_buf[128];
95 100
96static const char * 101static const char *
97efi_acpi_get_model(void) 102efi_acpi_get_model(void)
98{ 103{
99 struct smbtable smbios; 104 struct smbtable smbios;
100 struct smbios_sys *psys; 105 struct smbios_sys *psys;
101 const char *s; 106 const char *s;
102 char *buf; 107 char *buf;
103 108
104 memset(model_buf, 0, sizeof(model_buf)); 109 memset(model_buf, 0, sizeof(model_buf));
105 110
106 if (smbios3_table != NULL) { 111 if (smbios_table != NULL) {
107 smbios_init(smbios3_table); 112 smbios_init(smbios_table);
108 113
109 buf = model_buf; 114 buf = model_buf;
110 smbios.cookie = 0; 115 smbios.cookie = 0;
111 if (smbios_find_table(SMBIOS_TYPE_SYSTEM, &smbios)) { 116 if (smbios_find_table(SMBIOS_TYPE_SYSTEM, &smbios)) {
112 psys = smbios.tblhdr; 117 psys = smbios.tblhdr;
113 if ((s = smbios_get_string(&smbios, psys->vendor, buf, 64)) != NULL) { 118 if ((s = smbios_get_string(&smbios, psys->vendor, buf, 64)) != NULL) {
114 buf += strlen(s); 119 buf += strlen(s);
115 *buf++ = ' '; 120 *buf++ = ' ';
116 } 121 }
117 smbios_get_string(&smbios, psys->product, buf, 64); 122 smbios_get_string(&smbios, psys->product, buf, 64);
118 } 123 }
119 } 124 }
120 125
@@ -126,27 +131,27 @@ efi_acpi_get_model(void) @@ -126,27 +131,27 @@ efi_acpi_get_model(void)
126 131
127void 132void
128efi_acpi_show(void) 133efi_acpi_show(void)
129{ 134{
130 struct acpi_rdsp *rsdp = acpi_root; 135 struct acpi_rdsp *rsdp = acpi_root;
131 136
132 if (!efi_acpi_available()) 137 if (!efi_acpi_available())
133 return; 138 return;
134 139
135 printf("ACPI: v%02d %c%c%c%c%c%c\n", rsdp->revision, 140 printf("ACPI: v%02d %c%c%c%c%c%c\n", rsdp->revision,
136 rsdp->oemid[0], rsdp->oemid[1], rsdp->oemid[2], 141 rsdp->oemid[0], rsdp->oemid[1], rsdp->oemid[2],
137 rsdp->oemid[3], rsdp->oemid[4], rsdp->oemid[5]); 142 rsdp->oemid[3], rsdp->oemid[4], rsdp->oemid[5]);
138 143
139 if (smbios3_table) 144 if (smbios_table)
140 printf("SMBIOS: %s\n", efi_acpi_get_model()); 145 printf("SMBIOS: %s\n", efi_acpi_get_model());
141} 146}
142 147
143int 148int
144efi_acpi_create_fdt(void) 149efi_acpi_create_fdt(void)
145{ 150{
146 int error; 151 int error;
147 void *fdt; 152 void *fdt;
148 153
149 if (acpi_root == NULL) 154 if (acpi_root == NULL)
150 return EINVAL; 155 return EINVAL;
151 156
152 fdt = AllocatePool(ACPI_FDT_SIZE); 157 fdt = AllocatePool(ACPI_FDT_SIZE);
@@ -156,21 +161,21 @@ efi_acpi_create_fdt(void) @@ -156,21 +161,21 @@ efi_acpi_create_fdt(void)
156 error = fdt_create_empty_tree(fdt, ACPI_FDT_SIZE); 161 error = fdt_create_empty_tree(fdt, ACPI_FDT_SIZE);
157 if (error) 162 if (error)
158 return EIO; 163 return EIO;
159 164
160 const char *model = efi_acpi_get_model(); 165 const char *model = efi_acpi_get_model();
161 166
162 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "compatible", "netbsd,generic-acpi"); 167 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "compatible", "netbsd,generic-acpi");
163 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", model); 168 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/"), "model", model);
164 fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#address-cells", 2); 169 fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#address-cells", 2);
165 fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#size-cells", 2); 170 fdt_setprop_cell(fdt, fdt_path_offset(fdt, "/"), "#size-cells", 2);
166 171
167 fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "chosen"); 172 fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "chosen");
168 fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,acpi-root-table", (uint64_t)(uintptr_t)acpi_root); 173 fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,acpi-root-table", (uint64_t)(uintptr_t)acpi_root);
169 if (smbios3_table) 174 if (smbios_table)
170 fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,smbios-table", (uint64_t)(uintptr_t)smbios3_table); 175 fdt_setprop_u64(fdt, fdt_path_offset(fdt, "/chosen"), "netbsd,smbios-table", (uint64_t)(uintptr_t)smbios_table);
171 176
172 fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "acpi"); 177 fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), "acpi");
173 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/acpi"), "compatible", "netbsd,acpi"); 178 fdt_setprop_string(fdt, fdt_path_offset(fdt, "/acpi"), "compatible", "netbsd,acpi");
174 179
175 return efi_fdt_set_data(fdt); 180 return efi_fdt_set_data(fdt);
176} 181}

cvs diff -r1.2 -r1.3 src/sys/stand/efiboot/smbios.c (expand / switch to unified diff)

--- src/sys/stand/efiboot/smbios.c 2019/12/27 09:45:27 1.2
+++ src/sys/stand/efiboot/smbios.c 2021/07/23 21:33:00 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: smbios.c,v 1.2 2019/12/27 09:45:27 msaitoh Exp $ */ 1/* $NetBSD: smbios.c,v 1.3 2021/07/23 21:33:00 jmcneill Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1999 The NetBSD Foundation, Inc. 4 * Copyright (c) 1999 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center. 9 * NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -72,65 +72,93 @@ @@ -72,65 +72,93 @@
72 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 72 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
73 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 73 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
74 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 74 * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
75 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 75 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 76 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
77 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 77 * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
78 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 78 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
79 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 79 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
80 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 80 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
81 * THE POSSIBILITY OF SUCH DAMAGE. 81 * THE POSSIBILITY OF SUCH DAMAGE.
82 */ 82 */
83 83
84#include <sys/cdefs.h> 84#include <sys/cdefs.h>
85__KERNEL_RCSID(0, "$NetBSD: smbios.c,v 1.2 2019/12/27 09:45:27 msaitoh Exp $"); 85__KERNEL_RCSID(0, "$NetBSD: smbios.c,v 1.3 2021/07/23 21:33:00 jmcneill Exp $");
86 86
87#include <sys/param.h> 87#include <sys/param.h>
88 88
89#include "efiboot.h" 89#include "efiboot.h"
90#include "smbios.h" 90#include "smbios.h"
91 91
92struct smbios_entry smbios_entry; 92struct smbios_entry smbios_entry;
93 93
94void 94static void
95smbios_init(uint8_t *p) 95smbios2_init(uint8_t *p)
 96{
 97 const struct smbhdr *sh = (const struct smbhdr *)p;
 98
 99 smbios_entry.addr = (void *)(uintptr_t)sh->addr;
 100 smbios_entry.len = sh->size;
 101 smbios_entry.rev = 0;
 102 smbios_entry.mjr = sh->majrev;
 103 smbios_entry.min = sh->minrev;
 104 smbios_entry.doc = 0;
 105 smbios_entry.count = sh->count;
 106}
 107
 108static void
 109smbios3_init(uint8_t *p)
96{ 110{
97 const struct smb3hdr *sh = (const struct smb3hdr *)p; 111 const struct smb3hdr *sh = (const struct smb3hdr *)p;
98 112
99 smbios_entry.addr = (void *)(uintptr_t)sh->addr; 113 smbios_entry.addr = (void *)(uintptr_t)sh->addr;
100 smbios_entry.len = sh->size; 114 smbios_entry.len = sh->size;
101 smbios_entry.rev = sh->eprev; 115 smbios_entry.rev = sh->eprev;
102 smbios_entry.mjr = sh->majrev; 116 smbios_entry.mjr = sh->majrev;
103 smbios_entry.min = sh->minrev; 117 smbios_entry.min = sh->minrev;
104 smbios_entry.doc = sh->docrev; 118 smbios_entry.doc = sh->docrev;
105 smbios_entry.count = UINT16_MAX; 119 smbios_entry.count = UINT16_MAX;
106} 120}
107 121
 122void
 123smbios_init(uint8_t *p)
 124{
 125 if (memcmp(p, "_SM3_", 5) == 0) {
 126 smbios3_init(p);
 127 } else if (memcmp(p, "_SM_", 4) == 0) {
 128 smbios2_init(p);
 129 }
 130}
 131
108/* 132/*
109 * smbios_find_table() takes a caller supplied smbios struct type and 133 * smbios_find_table() takes a caller supplied smbios struct type and
110 * a pointer to a handle (struct smbtable) returning one if the structure 134 * a pointer to a handle (struct smbtable) returning one if the structure
111 * is successfully located and zero otherwise. Callers should take care 135 * is successfully located and zero otherwise. Callers should take care
112 * to initilize the cookie field of the smbtable structure to zero before 136 * to initilize the cookie field of the smbtable structure to zero before
113 * the first invocation of this function. 137 * the first invocation of this function.
114 * Multiple tables of the same type can be located by repeadtly calling 138 * Multiple tables of the same type can be located by repeadtly calling
115 * smbios_find_table with the same arguments. 139 * smbios_find_table with the same arguments.
116 */ 140 */
117int 141int
118smbios_find_table(uint8_t type, struct smbtable *st) 142smbios_find_table(uint8_t type, struct smbtable *st)
119{ 143{
120 uint8_t *va, *end; 144 uint8_t *va, *end;
121 struct smbtblhdr *hdr; 145 struct smbtblhdr *hdr;
122 int ret = 0, tcount = 1; 146 int ret = 0, tcount = 1;
123 147
 148 if (smbios_entry.addr == 0) {
 149 return 0;
 150 }
 151
124 va = smbios_entry.addr; 152 va = smbios_entry.addr;
125 end = va + smbios_entry.len; 153 end = va + smbios_entry.len;
126 154
127 /* 155 /*
128 * The cookie field of the smtable structure is used to locate 156 * The cookie field of the smtable structure is used to locate
129 * multiple instances of a table of an arbitrary type. Following the 157 * multiple instances of a table of an arbitrary type. Following the
130 * sucessful location of a table, the type is encoded as bits 0:7 of 158 * sucessful location of a table, the type is encoded as bits 0:7 of
131 * the cookie value, the offset in terms of the number of structures 159 * the cookie value, the offset in terms of the number of structures
132 * preceding that referenced by the handle is encoded in bits 15:31. 160 * preceding that referenced by the handle is encoded in bits 15:31.
133 */ 161 */
134 if ((st->cookie & 0xfff) == type && st->cookie >> 16) { 162 if ((st->cookie & 0xfff) == type && st->cookie >> 16) {
135 if ((uint8_t *)st->hdr >= va && (uint8_t *)st->hdr < end) { 163 if ((uint8_t *)st->hdr >= va && (uint8_t *)st->hdr < end) {
136 hdr = st->hdr; 164 hdr = st->hdr;
@@ -163,26 +191,30 @@ smbios_find_table(uint8_t type, struct s @@ -163,26 +191,30 @@ smbios_find_table(uint8_t type, struct s
163 va+=2; 191 va+=2;
164 } 192 }
165 193
166 return ret; 194 return ret;
167} 195}
168 196
169char * 197char *
170smbios_get_string(struct smbtable *st, uint8_t indx, char *dest, size_t len) 198smbios_get_string(struct smbtable *st, uint8_t indx, char *dest, size_t len)
171{ 199{
172 uint8_t *va, *end; 200 uint8_t *va, *end;
173 char *ret = NULL; 201 char *ret = NULL;
174 int i; 202 int i;
175 203
 204 if (smbios_entry.addr == 0) {
 205 return NULL;
 206 }
 207
176 va = (uint8_t *)st->hdr + st->hdr->size; 208 va = (uint8_t *)st->hdr + st->hdr->size;
177 end = smbios_entry.addr + smbios_entry.len; 209 end = smbios_entry.addr + smbios_entry.len;
178 for (i = 1; va < end && i < indx && *va; i++) 210 for (i = 1; va < end && i < indx && *va; i++)
179 while (*va++) 211 while (*va++)
180 ; 212 ;
181 if (i == indx) { 213 if (i == indx) {
182 if (va + len < end) { 214 if (va + len < end) {
183 ret = dest; 215 ret = dest;
184 memcpy(ret, va, len); 216 memcpy(ret, va, len);
185 ret[len - 1] = '\0'; 217 ret[len - 1] = '\0';
186 } 218 }
187 } 219 }
188 220