Home | History | Annotate | Line # | Download | only in efiboot
      1 /*	$NetBSD: smbios.c,v 1.4 2021/09/16 22:19:11 andvar Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1999 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  * POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 /*
     34  * Copyright (c) 1999, by UCHIYAMA Yasushi
     35  * All rights reserved.
     36  *
     37  * Redistribution and use in source and binary forms, with or without
     38  * modification, are permitted provided that the following conditions
     39  * are met:
     40  * 1. Redistributions of source code must retain the above copyright
     41  *    notice, this list of conditions and the following disclaimer.
     42  * 2. The name of the developer may NOT be used to endorse or promote products
     43  *    derived from this software without specific prior written permission.
     44  *
     45  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     46  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     47  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     48  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     49  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     50  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     51  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     52  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     53  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     54  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     55  * SUCH DAMAGE.
     56  */
     57 
     58 /*
     59  * Copyright (c) 1997-2001 Michael Shalayeff
     60  * All rights reserved.
     61  *
     62  * Redistribution and use in source and binary forms, with or without
     63  * modification, are permitted provided that the following conditions
     64  * are met:
     65  * 1. Redistributions of source code must retain the above copyright
     66  *    notice, this list of conditions and the following disclaimer.
     67  * 2. Redistributions in binary form must reproduce the above copyright
     68  *    notice, this list of conditions and the following disclaimer in the
     69  *    documentation and/or other materials provided with the distribution.
     70  *
     71  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     72  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     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,
     75  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     76  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     77  * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     78  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     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
     81  * THE POSSIBILITY OF SUCH DAMAGE.
     82  */
     83 
     84 #include <sys/cdefs.h>
     85 __KERNEL_RCSID(0, "$NetBSD: smbios.c,v 1.4 2021/09/16 22:19:11 andvar Exp $");
     86 
     87 #include <sys/param.h>
     88 
     89 #include "efiboot.h"
     90 #include "smbios.h"
     91 
     92 struct smbios_entry smbios_entry;
     93 
     94 static void
     95 smbios2_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 
    108 static void
    109 smbios3_init(uint8_t *p)
    110 {
    111 	const struct smb3hdr *sh = (const struct smb3hdr *)p;
    112 
    113 	smbios_entry.addr = (void *)(uintptr_t)sh->addr;
    114 	smbios_entry.len = sh->size;
    115 	smbios_entry.rev = sh->eprev;
    116 	smbios_entry.mjr = sh->majrev;
    117 	smbios_entry.min = sh->minrev;
    118 	smbios_entry.doc = sh->docrev;
    119 	smbios_entry.count = UINT16_MAX;
    120 }
    121 
    122 void
    123 smbios_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 
    132 /*
    133  * smbios_find_table() takes a caller supplied smbios struct type and
    134  * a pointer to a handle (struct smbtable) returning one if the structure
    135  * is successfully located and zero otherwise. Callers should take care
    136  * to initilize the cookie field of the smbtable structure to zero before
    137  * the first invocation of this function.
    138  * Multiple tables of the same type can be located by repeadtly calling
    139  * smbios_find_table with the same arguments.
    140  */
    141 int
    142 smbios_find_table(uint8_t type, struct smbtable *st)
    143 {
    144 	uint8_t *va, *end;
    145 	struct smbtblhdr *hdr;
    146 	int ret = 0, tcount = 1;
    147 
    148 	if (smbios_entry.addr == 0) {
    149 		return 0;
    150 	}
    151 
    152 	va = smbios_entry.addr;
    153 	end = va + smbios_entry.len;
    154 
    155 	/*
    156 	 * The cookie field of the smtable structure is used to locate
    157 	 * multiple instances of a table of an arbitrary type. Following the
    158 	 * successful location of a table, the type is encoded as bits 0:7 of
    159 	 * the cookie value, the offset in terms of the number of structures
    160 	 * preceding that referenced by the handle is encoded in bits 15:31.
    161 	 */
    162 	if ((st->cookie & 0xfff) == type && st->cookie >> 16) {
    163 		if ((uint8_t *)st->hdr >= va && (uint8_t *)st->hdr < end) {
    164 			hdr = st->hdr;
    165 			if (hdr->type == type) {
    166 				va = (uint8_t *)hdr + hdr->size;
    167 				for (; va + 1 < end; va++)
    168 					if (*va == 0 && *(va + 1) == 0)
    169 						break;
    170 				va+= 2;
    171 				tcount = st->cookie >> 16;
    172 			}
    173 		}
    174 	}
    175 	for (; va + sizeof(struct smbtblhdr) < end && tcount <=
    176 	    smbios_entry.count; tcount++) {
    177 		hdr = (struct smbtblhdr *)va;
    178 		if (hdr->type == type) {
    179 			ret = 1;
    180 			st->hdr = hdr;
    181 			st->tblhdr = va + sizeof(struct smbtblhdr);
    182 			st->cookie = (tcount + 1) << 16 | type;
    183 			break;
    184 		}
    185 		if (hdr->type == SMBIOS_TYPE_EOT)
    186 			break;
    187 		va+= hdr->size;
    188 		for (; va + 1 < end; va++)
    189 			if (*va == 0 && *(va + 1) == 0)
    190 				break;
    191 		va+=2;
    192 	}
    193 
    194 	return ret;
    195 }
    196 
    197 char *
    198 smbios_get_string(struct smbtable *st, uint8_t indx, char *dest, size_t len)
    199 {
    200 	uint8_t *va, *end;
    201 	char *ret = NULL;
    202 	int i;
    203 
    204 	if (smbios_entry.addr == 0) {
    205 		return NULL;
    206 	}
    207 
    208 	va = (uint8_t *)st->hdr + st->hdr->size;
    209 	end = smbios_entry.addr + smbios_entry.len;
    210 	for (i = 1; va < end && i < indx && *va; i++)
    211 		while (*va++)
    212 			;
    213 	if (i == indx) {
    214 		if (va + len < end) {
    215 			ret = dest;
    216 			memcpy(ret, va, len);
    217 			ret[len - 1] = '\0';
    218 		}
    219 	}
    220 
    221 	return ret;
    222 }
    223