Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/smbios.c

1/*-
2 * Copyright (c) 2005-2009 Jung-uk Kim <jkim@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Detect SMBIOS and export information about the SMBIOS into the
29 * environment.
30 *
31 * System Management BIOS Reference Specification, v2.6 Final
32 * http://www.dmtf.org/standards/published_documents/DSP0134_2.6.0.pdf
33 */
34
35/*
36 * 2.1.1 SMBIOS Structure Table Entry Point
37 *
38 * "On non-EFI systems, the SMBIOS Entry Point structure, described below, can
39 * be located by application software by searching for the anchor-string on
40 * paragraph (16-byte) boundaries within the physical memory address range
41 * 000F0000h to 000FFFFFh. This entry point encapsulates an intermediate anchor
42 * string that is used by some existing DMI browsers."
43 */
44
45#include "libsaio.h"
46#include "SMBIOS.h"
47#include "Platform.h"
48
49#define SMBIOS_START 0xf0000
50#define SMBIOS_LENGTH 0x10000
51#define SMBIOS_STEP 0x10
52#define SMBIOS_SIG "_SM_"
53#define SMBIOS_DMI_SIG "_DMI_"
54
55#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off)))
56#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
57#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
58
59#define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01)
60#define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base))
61
62typedef char* caddr_t;
63
64static uint8_t
65smbios_checksum(const caddr_t addr, const uint8_t len)
66{
67uint8_t sum;
68int i;
69
70for (sum = 0, i = 0; i < len; i++)
71sum += SMBIOS_GET8(addr, i);
72return (sum);
73}
74
75static caddr_t
76smbios_sigsearch(const caddr_t addr, const uint32_t len)
77{
78caddr_t cp;
79
80/* Search on 16-byte boundaries. */
81for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
82if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
83smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
84strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 &&
85smbios_checksum(cp + 0x10, 0x0f) == 0)
86return (cp);
87return (NULL);
88}
89
90struct SMBEntryPoint *getSmbiosOriginal()
91{
92 static caddr_t smbios = NULL; // cached
93
94 if (smbios == NULL)
95{
96/* Search signatures and validate checksums. */
97smbios = smbios_sigsearch((caddr_t)ptov(SMBIOS_START), SMBIOS_LENGTH);
98
99if (smbios)
100{
101verbose("Found System Management BIOS (SMBIOS) table\n");
102}
103
104 }
105 return (struct SMBEntryPoint *)smbios;
106}
107
108/* get product Name from original SMBIOS */
109char* readDefaultPlatformName(void)
110{
111
112SMBEntryPoint *eps = getSmbiosOriginal();
113if (eps == NULL) return NULL;
114
115uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;
116SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;
117
118for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
119{
120switch (structHeader->type)
121{
122case kSMBTypeSystemInformation:
123{
124uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;
125uint8_t field = ((SMBSystemInformation *)structHeader)->productName;
126
127if (!field)
128return NULL;
129
130for (field--; field != 0 && strlen((char *)stringPtr) > 0;
131 field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));
132
133//DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);
134if (stringPtr)
135return (char *)stringPtr;
136else
137return NULL;
138
139break;
140}
141default:
142break;
143
144}
145
146structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
147for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);
148
149if (((uint16_t *)structPtr)[0] == 0)
150structPtr += 2;
151
152structHeader = (SMBStructHeader *)structPtr;
153}
154return NULL;
155}
156
157/* get UUID or product Name from original SMBIOS, stripped version of kabyl's readSMBIOSInfo */
158int readSMBIOS(int value)
159{
160
161SMBEntryPoint *eps = getSmbiosOriginal();
162if (eps == NULL) return 0;
163
164uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;
165SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;
166
167for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
168{
169switch (structHeader->type)
170{
171case kSMBTypeSystemInformation:
172{
173switch (value) {
174case theUUID:
175 safe_set_env(envUUID,(uint32_t)((SMBSystemInformation *)structHeader)->uuid);
176return 1;
177break;
178case thePlatformName:
179{
180uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;
181uint8_t field = ((SMBSystemInformation *)structHeader)->productName;
182
183if (!field)
184return 0;
185
186for (field--; field != 0 && strlen((char *)stringPtr) > 0;
187 field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));
188
189//DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);
190 SetgPlatformName((char *)stringPtr);
191if (GetgPlatformName()) return 1;
192break;
193}
194default:
195break;
196}
197
198break;
199}
200case kSMBTypeBaseBoard:
201 {
202switch (value) {
203case theProducBoard:
204{
205uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;
206uint8_t field = ((SMBBaseBoard *)structHeader)->product;
207
208if (!field)
209return 0;
210
211for (field--; field != 0 && strlen((char *)stringPtr) > 0;
212 field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));
213
214Setgboardproduct((char *)stringPtr);
215if (Getgboardproduct()) return 1;
216break;
217}
218default:
219break;
220}
221break;
222 }
223default:
224break;
225
226}
227
228structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
229for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);
230
231if (((uint16_t *)structPtr)[0] == 0)
232structPtr += 2;
233
234structHeader = (SMBStructHeader *)structPtr;
235}
236return 0;
237}

Archive Download this file

Revision: 2057