Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/util/smbios-fbsd.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
47#define SMBIOS_START 0xf0000
48#define SMBIOS_LENGTH 0x10000
49#define SMBIOS_STEP 0x10
50#define SMBIOS_SIG "_SM_"
51#define SMBIOS_DMI_SIG "_DMI_"
52
53#define SMBIOS_GET8(base, off) (*(uint8_t *)((base) + (off)))
54#define SMBIOS_GET16(base, off) (*(uint16_t *)((base) + (off)))
55#define SMBIOS_GET32(base, off) (*(uint32_t *)((base) + (off)))
56
57#define SMBIOS_GETLEN(base) SMBIOS_GET8(base, 0x01)
58#define SMBIOS_GETSTR(base) ((base) + SMBIOS_GETLEN(base))
59
60static uint32_t smbios_enabled_memory = 0;
61static uint32_t smbios_old_enabled_memory = 0;
62static uint8_t smbios_enabled_sockets = 0;
63static uint8_t smbios_populated_sockets = 0;
64typedef char* caddr_t;
65
66static uint8_t
67smbios_checksum(const caddr_t addr, const uint8_t len)
68{
69uint8_t sum;
70int i;
71
72for (sum = 0, i = 0; i < len; i++)
73sum += SMBIOS_GET8(addr, i);
74return (sum);
75}
76
77static caddr_t
78smbios_sigsearch(const caddr_t addr, const uint32_t len)
79{
80caddr_t cp;
81
82/* Search on 16-byte boundaries. */
83for (cp = addr; cp < addr + len; cp += SMBIOS_STEP)
84if (strncmp(cp, SMBIOS_SIG, 4) == 0 &&
85smbios_checksum(cp, SMBIOS_GET8(cp, 0x05)) == 0 &&
86strncmp(cp + 0x10, SMBIOS_DMI_SIG, 5) == 0 &&
87smbios_checksum(cp + 0x10, 0x0f) == 0)
88return (cp);
89return (NULL);
90}
91
92void
93smbios_detect(void)
94{
95char buf[16];
96caddr_t addr, dmi, smbios;
97size_t count, length;
98uint32_t paddr;
99int i, major, minor, ver;
100
101/* Search signatures and validate checksums. */
102smbios = smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH);
103if (smbios == NULL)
104return;
105
106length = SMBIOS_GET16(smbios, 0x16); /* Structure Table Length */
107paddr = SMBIOS_GET32(smbios, 0x18); /* Structure Table Address */
108count = SMBIOS_GET16(smbios, 0x1c); /* No of SMBIOS Structures */
109ver = SMBIOS_GET8(smbios, 0x1e); /* SMBIOS BCD Revision */
110
111if (ver != 0) {
112major = ver >> 4;
113minor = ver & 0x0f;
114if (major > 9 || minor > 9)
115ver = 0;
116}
117if (ver == 0) {
118major = SMBIOS_GET8(smbios, 0x06); /* SMBIOS Major Version */
119minor = SMBIOS_GET8(smbios, 0x07); /* SMBIOS Minor Version */
120}
121ver = (major << 8) | minor;
122
123addr = PTOV(paddr);
124for (dmi = addr, i = 0; dmi < addr + length && i < count; i++)
125dmi = smbios_parse_table(dmi, ver);
126
127sprintf(buf, "%d.%d", major, minor);
128setenv("smbios.version", buf, 1);
129if (smbios_enabled_memory > 0 || smbios_old_enabled_memory > 0) {
130sprintf(buf, "%u", smbios_enabled_memory > 0 ?
131336 smbios_enabled_memory : smbios_old_enabled_memory);
132setenv("smbios.memory.enabled", buf, 1);
133}
134if (smbios_enabled_sockets > 0) {
135sprintf(buf, "%u", smbios_enabled_sockets);
136setenv("smbios.socket.enabled", buf, 1);
137}
138if (smbios_populated_sockets > 0) {
139sprintf(buf, "%u", smbios_populated_sockets);
140setenv("smbios.socket.populated", buf, 1);
141}
142}
143

Archive Download this file

Revision: 1972