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