1 | ␊ |
2 | ␊ |
3 | #include "SMBIOS.h"␊ |
4 | #include "Platform.h"␊ |
5 | #include "boot.h"␊ |
6 | ␊ |
7 | static const char * const SMTAG = "_SM_";␊ |
8 | static const char* const DMITAG= "_DMI_";␊ |
9 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void);␊ |
10 | ␊ |
11 | static struct SMBEntryPoint *getAddressOfSmbiosTable(void)␊ |
12 | {␊ |
13 | ␉struct SMBEntryPoint␉*smbios;␊ |
14 | ␉/* ␊ |
15 | ␉ * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking␊ |
16 | ␉ * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").␊ |
17 | ␉ */␊ |
18 | ␉smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;␊ |
19 | ␉while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END)␊ |
20 | ␉{␊ |
21 | ␉␉if (COMPARE_DWORD(smbios->anchor, SMTAG) && ␊ |
22 | ␉␉␉COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&␊ |
23 | ␉␉␉smbios->dmi.anchor[4]==DMITAG[4] &&␊ |
24 | ␉␉␉checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)␊ |
25 | ␉ {␉␉␉␊ |
26 | ␉␉␉return ((void*)smbios);␊ |
27 | ␉ }␊ |
28 | ␉␉smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );␊ |
29 | ␉}␊ |
30 | ␉printf("Error: Could not find original SMBIOS !!\n");␊ |
31 | ␉pause();␊ |
32 | ␉return NULL;␊ |
33 | }␊ |
34 | ␊ |
35 | struct SMBEntryPoint *getSmbiosOriginal()␊ |
36 | { ␉␊ |
37 | static struct SMBEntryPoint *orig = NULL; // cached␊ |
38 | ␊ |
39 | if (orig == NULL)␊ |
40 | ␉{␊ |
41 | ␉␉orig = getAddressOfSmbiosTable();␉␉␊ |
42 | ␉␉␊ |
43 | ␉␉if (orig)␊ |
44 | ␉␉{␊ |
45 | ␉␉␉verbose("Found System Management BIOS (SMBIOS) table\n");␉␉␉␊ |
46 | ␉␉}␊ |
47 | ␊ |
48 | }␊ |
49 | return orig; ␊ |
50 | }␊ |
51 | ␊ |
52 | /* get UUID or product Name from original SMBIOS, stripped version of kabyl's readSMBIOSInfo */␊ |
53 | int readSMBIOS(int value)␊ |
54 | {␉␉␉␊ |
55 | ␉␊ |
56 | ␉SMBEntryPoint *eps = getSmbiosOriginal();␊ |
57 | ␉if (eps == NULL) return 0;␊ |
58 | ␉␊ |
59 | ␉uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;␊ |
60 | ␉SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;␊ |
61 | ␉␊ |
62 | ␉for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)␊ |
63 | ␉{␊ |
64 | ␉␉switch (structHeader->type)␊ |
65 | ␉␉{␉␉␉␉␊ |
66 | ␉␉␉case kSMBTypeSystemInformation: ␊ |
67 | ␉␉␉{␊ |
68 | ␉␉␉␉switch (value) {␊ |
69 | ␉␉␉␉␉case theUUID:␊ |
70 | ␉␉␉␉␉␉Platform->UUID = ((SMBSystemInformation *)structHeader)->uuid;␊ |
71 | ␉␉␉␉␉␉return 1;␊ |
72 | ␉␉␉␉␉␉break;␊ |
73 | ␉␉␉␉␉case thePlatformName:␊ |
74 | ␉␉␉␉␉{␊ |
75 | ␉␉␉␉␉␉uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;␊ |
76 | ␉␉␉␉␉␉uint8_t field = ((SMBSystemInformation *)structHeader)->productName;␊ |
77 | ␉␉␉␉␉␉␊ |
78 | ␉␉␉␉␉␉if (!field)␊ |
79 | ␉␉␉␉␉␉␉return 0;␊ |
80 | ␉␉␉␉␉␉␊ |
81 | ␉␉␉␉␉␉for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
82 | ␉␉␉␉␉␉␉ field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));␊ |
83 | ␉␉␉␉␉␉␊ |
84 | ␉␉␉␉␉␉//DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);␊ |
85 | ␉␉␉␉␉␉gPlatformName = (char *)stringPtr;␊ |
86 | ␉␉␉␉␉␉if (gPlatformName) return 1;␊ |
87 | ␉␉␉␉␉␉break;␊ |
88 | ␉␉␉␉␉}␊ |
89 | ␉␉␉␉␉default:␊ |
90 | ␉␉␉␉␉␉break;␊ |
91 | ␉␉␉␉}␉␉␉␉␊ |
92 | ␉␉␉␉␊ |
93 | ␉␉␉␉break;␉␊ |
94 | ␉␉␉}␊ |
95 | ␉␉␉case kSMBTypeBaseBoard:␊ |
96 | {␊ |
97 | ␉␉␉␉switch (value) {␊ |
98 | ␉␉␉␉␉case theProducBoard:␊ |
99 | ␉␉␉␉␉{␊ |
100 | ␉␉␉␉␉␉uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;␊ |
101 | ␉␉␉␉␉␉uint8_t field = ((SMBBaseBoard *)structHeader)->product;␊ |
102 | ␉␉␉␉␉␉␊ |
103 | ␉␉␉␉␉␉if (!field)␊ |
104 | ␉␉␉␉␉␉␉return 0;␊ |
105 | ␉␉␉␉␉␉␊ |
106 | ␉␉␉␉␉␉for (field--; field != 0 && strlen((char *)stringPtr) > 0; ␊ |
107 | ␉␉␉␉␉␉␉ field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));␊ |
108 | ␉␉␉␉␉␉␊ |
109 | ␉␉␉␉␉␉gboardproduct = (char *)stringPtr;␊ |
110 | ␉␉␉␉␉␉if (gboardproduct) return 1;␊ |
111 | ␉␉␉␉␉␉break;␊ |
112 | ␉␉␉␉␉}␊ |
113 | ␉␉␉␉␉default:␊ |
114 | ␉␉␉␉␉␉break;␊ |
115 | ␉␉␉␉}␊ |
116 | ␉␉␉␉break;␊ |
117 | }␊ |
118 | ␉␉␉default:␊ |
119 | ␉␉␉␉break;␊ |
120 | ␉␉␉␉␊ |
121 | ␉␉}␊ |
122 | ␉␉␊ |
123 | ␉␉structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);␊ |
124 | ␉␉for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);␊ |
125 | ␉␉␊ |
126 | ␉␉if (((uint16_t *)structPtr)[0] == 0)␊ |
127 | ␉␉␉structPtr += 2;␊ |
128 | ␉␉␊ |
129 | ␉␉structHeader = (SMBStructHeader *)structPtr;␊ |
130 | ␉}␉␊ |
131 | ␉return 0;␊ |
132 | } |