1 | /*␊ |
2 | * Idea and template by (c) 2009 Evan Lojewski. All rights reserved.␊ |
3 | *␊ |
4 | * NVRAM module by Slice 2010.␊ |
5 | */␊ |
6 | ␊ |
7 | #include "libsaio.h"␊ |
8 | #include "modules.h"␊ |
9 | #include "boot.h"␊ |
10 | #include "bootstruct.h"␊ |
11 | #include "pci.h"␊ |
12 | #include "efi.h"␊ |
13 | #include "smbios_patcher.h"␊ |
14 | ␊ |
15 | #ifndef DEBUG_NVRAM␊ |
16 | #define DEBUG_NVRAM 0␊ |
17 | #endif␊ |
18 | ␊ |
19 | #if DEBUG_NVRAM␊ |
20 | #define DBG(x...) verbose(x)␊ |
21 | #else␊ |
22 | #define DBG(x...) msglog(x)␊ |
23 | #endif␊ |
24 | ␊ |
25 | /*static const char const FIRMWARE_REVISION_PROP[] = "firmware-revision";␊ |
26 | static const char const FIRMWARE_ABI_PROP[] = "firmware-abi";␊ |
27 | static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor";␊ |
28 | static const char const FIRMWARE_ABI_32_PROP_VALUE[] = "EFI32";␊ |
29 | static const char const FIRMWARE_ABI_64_PROP_VALUE[] = "EFI64";␊ |
30 | static const char const SYSTEM_ID_PROP[] = "system-id";␊ |
31 | static const char const SYSTEM_SERIAL_PROP[] = "SystemSerialNumber";␊ |
32 | static const char const SYSTEM_TYPE_PROP[] = "system-type";␊ |
33 | static const char const MODEL_PROP[] = "Model";␊ |
34 | */␊ |
35 | const char PLATFORM_UUID[] = "platform-uuid"; ␊ |
36 | //EFI_UINT32 const FIRMWARE_FEATURE_MASK = 0x000003FF;␊ |
37 | EFI_UINT32 const STATIC_ZERO = 0;␊ |
38 | ␊ |
39 | #define kBL_GLOBAL_NVRAM_GUID "8BE4DF61-93CA-11D2-AA0D-00E098032B8C"␊ |
40 | ␊ |
41 | // Check if a system supports CSM legacy mode␊ |
42 | #define kBL_APPLE_VENDOR_NVRAM_GUID "4D1EDE05-38C7-4A6A-9CC6-4BCCA8B38C14"␊ |
43 | #define UUID_LEN␉16␊ |
44 | ␊ |
45 | extern EFI_GUID* getSystemID();␊ |
46 | void NVRAM_hook(void* arg1, void* arg2, void* arg3, void* arg4);␊ |
47 | void NVRAM_start(void);␊ |
48 | int readNVRAM(void);␊ |
49 | ␊ |
50 | typedef struct {␊ |
51 | ␉char Name[32];␊ |
52 | ␉char Value[512];␊ |
53 | } variables;␊ |
54 | variables* var;␊ |
55 | ␊ |
56 | void NVRAM_hook(void* arg1, void* arg2, void* arg3, void* arg4)␊ |
57 | {␊ |
58 | ␉char␉␉bootName[128];␊ |
59 | ␉␊ |
60 | ␉char*␉␉ffName;␊ |
61 | ␉uint8_t *␉FirmwareFeatures;␊ |
62 | ␉uint8_t *␉FirmwareFeaturesMask;␊ |
63 | ␉char*␉␉ffmName;␊ |
64 | ␉char*␉␉boName;␊ |
65 | ␉char*␉␉bnName;␊ |
66 | ␉EFI_GUID*␉ret = 0;␊ |
67 | ␉uint16_t␉bootOptionNumber = 0;␊ |
68 | ␉msglog("NVRAM is not implemented yet\n");␊ |
69 | ␉␊ |
70 | ␉return;␊ |
71 | ␉␊ |
72 | ␉msglog("NVRAM started\n");␊ |
73 | ␉␊ |
74 | ␉//Slice create /options node -> /fakenvram␊ |
75 | ␉// I need to use fakenvram until I know what is happen␊ |
76 | //␉bool UseNVRAM = FALSE;␊ |
77 | ␉bool ClearNVRAM = FALSE;␊ |
78 | ␉const char* buff;␊ |
79 | ␉int cnt;␊ |
80 | ␉ClearNVRAM = getValueForKey(kClearNVRAM, &buff, &cnt, &bootInfo->bootConfig);␊ |
81 | ␉if (!ClearNVRAM) {␊ |
82 | ␉␉readNVRAM();␊ |
83 | ␉}␊ |
84 | ␉␉␊ |
85 | ␉Node* optionsNode = DT__FindNode("/options", true);␊ |
86 | ␉ffName = malloc(sizeof(PLATFORM_UUID)+1);␊ |
87 | ␉strcpy(ffName, PLATFORM_UUID);␊ |
88 | ␉ret = getSystemID();␊ |
89 | ␉DT__AddProperty(optionsNode, ffName, UUID_LEN, (EFI_UINT32*) ret);␉␉␊ |
90 | ␉␉␊ |
91 | ␉␉// this information can be obtained from DMI Type 0␊ |
92 | ␉␉SMBByte* p = (SMBByte*)FindFirstDmiTableOfType(0, 0x18);␊ |
93 | ␉␉FirmwareFeatures = malloc(sizeof(SMBByte));␊ |
94 | ␉␉//TODO - the bufferFF must be composed from bits p[0x12] and [0x13]. Datasheet needed␊ |
95 | ␉␉*FirmwareFeatures = ((p[19] >> 1) & 1) //USB Legacy is supported␊ |
96 | ␉␉␉| ((p[18] >> 14) & 2) //Boot from CD is supported␊ |
97 | ␉␉␉| 0x14; //default for bless (GUID partition)␊ |
98 | ␉␉␊ |
99 | ␉␉sprintf(bootName, "%s:FirmwareFeatures", kBL_APPLE_VENDOR_NVRAM_GUID);␊ |
100 | ␉␉ffName = malloc(sizeof(bootName)+1);␊ |
101 | ␉␉strcpy(ffName, bootName);␊ |
102 | ␉␉DT__AddProperty(optionsNode, ffName, sizeof(uint32_t), (char *)FirmwareFeatures); //legacy support␊ |
103 | ␉␉␊ |
104 | ␉␉sprintf(bootName, "%s:FirmwareFeaturesMask", kBL_APPLE_VENDOR_NVRAM_GUID);␊ |
105 | ␉FirmwareFeaturesMask = malloc(sizeof(EFI_UINT32));␊ |
106 | ␉*FirmwareFeaturesMask = (EFI_UINT32)0x3ff;␊ |
107 | ␉␉ffmName = malloc(sizeof(bootName)+1);␊ |
108 | ␉␉strcpy(ffmName, bootName);␉␊ |
109 | ␉␉DT__AddProperty(optionsNode, ffmName, sizeof(uint32_t), (EFI_UINT32*)FirmwareFeaturesMask); ␉␊ |
110 | ␉␉␊ |
111 | ␉␉//TODO - check, validate and fill by bvr structure.␊ |
112 | ␉␉//here I am not sure what is BootOrder: node or property?␊ |
113 | ␉␉//Node* bootNode = DT__AddChild(optionsNode, kBL_GLOBAL_NVRAM_GUID ":BootOrder");␊ |
114 | ␉␉sprintf(bootName, "%s:BootOrder", kBL_GLOBAL_NVRAM_GUID);␊ |
115 | ␉␉boName = malloc(sizeof(bootName)+1);␊ |
116 | ␉␉strcpy(boName, bootName);␉␉␊ |
117 | ␉␉DT__AddProperty(optionsNode, boName, sizeof(uint32_t), (EFI_UINT32*)&STATIC_ZERO);␉␊ |
118 | ␉␉␊ |
119 | ␉␉sprintf(bootName, "%s:Boot%04hx", kBL_GLOBAL_NVRAM_GUID, bootOptionNumber);␊ |
120 | ␉␉bnName = malloc(sizeof(bootName)+1);␊ |
121 | ␉␉strcpy(bnName, bootName);␉␉␉␊ |
122 | ␉␉DT__AddProperty(optionsNode, bnName, sizeof(uint32_t), (EFI_UINT32*)&STATIC_ZERO); ␊ |
123 | ␉␉␊ |
124 | ␉␉␊ |
125 | ␉␉//can we add here boot-properties?␊ |
126 | ␉␉//␉optionsNode = DT__FindNode("chosen", true);␊ |
127 | #if 1 //NOTYET␊ |
128 | ␉␉int lbC = 0;␊ |
129 | ␉␉while(((char*)&bootInfo->bootConfig)[lbC++]);␊ |
130 | ␉␉if (lbC > sizeof(bootInfo->bootConfig)) lbC = sizeof(bootInfo->bootConfig);␊ |
131 | ␉␉DT__AddProperty(optionsNode, "boot-args", lbC, (char*)&bootInfo->bootConfig);␉␊ |
132 | #endif␊ |
133 | ␉␉//TODO - BootCamp emulation?␊ |
134 | ␉␉/*␊ |
135 | ␉␉ romNode = DT__FindNode("/rom", true);␊ |
136 | ␉␉ DT__AddProperty(romNode, "fv-main-address"... //provided by AppleSMBIOS␊ |
137 | ␉␉ DT__AddProperty(romNode, "fv-main-size"...␊ |
138 | ␉␉ "IOEFIDevicePathType" -> "MediaFirmwareVolumeFilePath"␊ |
139 | ␉␉ "Guid" -> "2B0585EB-D8B8-49A9-8B8C-E21B01AEF2B7"␊ |
140 | ␉␉ ␊ |
141 | ␉␉ */␊ |
142 | ␉␉//end Slice␊ |
143 | }␊ |
144 | ␊ |
145 | void NVRAM_start()␊ |
146 | {␊ |
147 | ␉register_hook_callback("Kernel Start", &NVRAM_hook);␊ |
148 | }␊ |
149 | ␊ |
150 | const char NVRAM_INF[] = "nvram.inf";␊ |
151 | int readNVRAM()␊ |
152 | {␊ |
153 | ␉int fd, fsize;␊ |
154 | ␉char* nvr = 0;␊ |
155 | ␉if ((fd = open(NVRAM_INF, 0)) < 0) {␊ |
156 | ␉␉return -1;␊ |
157 | ␉}␊ |
158 | ␉fsize = file_size(fd);␊ |
159 | ␉if (!fsize) {␊ |
160 | ␉␉close (fd);␊ |
161 | ␉␉return -1;␊ |
162 | ␉}␊ |
163 | ␉if ((nvr = malloc(fsize)) == NULL) {␊ |
164 | ␉␉verbose("[ERROR] alloc NVRAM memory failed\n");␊ |
165 | ␉␉close (fd);␊ |
166 | ␉␉return -1;␊ |
167 | ␉}␊ |
168 | ␉if (read (fd, nvr, fsize) != fsize) {␊ |
169 | ␉␉verbose("[ERROR] read %s failed\n", NVRAM_INF);␊ |
170 | ␉␉close (fd);␊ |
171 | ␉␉return -1;␊ |
172 | ␉}␊ |
173 | ␉close (fd);␊ |
174 | ␉if ((var = malloc(fsize)) == NULL) {␊ |
175 | ␉␉verbose("[ERROR] alloc VAR memory failed\n");␊ |
176 | ␉␉return -1;␊ |
177 | ␉}␊ |
178 | ␉int i = 0;␊ |
179 | ␉bool skipGUID;␊ |
180 | ␉while (*nvr) {␊ |
181 | ␉␉int j = 0;␊ |
182 | ␉␉skipGUID = false;␊ |
183 | ␉␉while (*nvr != 9) {␊ |
184 | ␉␉␉if (*nvr == 4) {␊ |
185 | ␉␉␉␉skipGUID = true; //TODO this is GUID␊ |
186 | ␉␉␉}␊ |
187 | ␉␉␉var[i].Name[j++] = *nvr++; ␊ |
188 | ␉␉}␊ |
189 | ␉␉nvr++; //skip \09␊ |
190 | ␉␉var[i].Name[j] = 0; //end of c-string␊ |
191 | ␉␉if (skipGUID) {␊ |
192 | ␉␉␉//TODO this is GUID␊ |
193 | ␉␉␉while (*nvr++ != 0x0A) {}␊ |
194 | ␉␉␉i--;␊ |
195 | ␉␉} else {␊ |
196 | ␉␉␉␊ |
197 | ␉␉␉j = 0;␊ |
198 | ␉␉␉char c;␊ |
199 | ␉␉␉while (*nvr != 0x0A) {␊ |
200 | ␉␉␉␉c = *nvr++;␊ |
201 | ␉␉␉␉if (c == 0x25) { //TODO this is hex ␊ |
202 | ␉␉␉␉␉int k1=*nvr++;␊ |
203 | ␉␉␉␉␉if ((k1 > 0x30) && (k1 < 0x39)) {␊ |
204 | ␉␉␉␉␉␉k1 = k1 - 0x30;␊ |
205 | ␉␉␉␉␉}␊ |
206 | ␉␉␉␉␉if ((k1 > 0x60) && (k1 < 0x69)) {␊ |
207 | ␉␉␉␉␉␉k1 = k1 - 0x60 + 10;␊ |
208 | ␉␉␉␉␉}␊ |
209 | ␉␉␉␉␉int k2=*nvr++;␊ |
210 | ␉␉␉␉␉if ((k2 > 0x30) && (k2 < 0x39)) {␊ |
211 | ␉␉␉␉␉␉k2 = k2 - 0x30;␊ |
212 | ␉␉␉␉␉}␊ |
213 | ␉␉␉␉␉if ((k2 > 0x60) && (k2 < 0x69)) {␊ |
214 | ␉␉␉␉␉␉k2 = k2 - 0x60 + 10;␊ |
215 | ␉␉␉␉␉}␊ |
216 | ␉␉␉␉␉c = (k1 << 4) + k2;␊ |
217 | ␉␉␉␉␉break; ␊ |
218 | ␉␉␉␉}␊ |
219 | ␉␉␉␉var[i].Value[j++] = c; ␊ |
220 | ␉␉␉}␊ |
221 | ␉␉}␊ |
222 | ␉␉i++;␊ |
223 | ␉␉if (i > fsize) {␊ |
224 | ␉␉␉break;␊ |
225 | ␉␉}␊ |
226 | ␉}␊ |
227 | ␉␊ |
228 | ␉return 0;␊ |
229 | } |