Chameleon

Chameleon Svn Source Tree

Root/trunk/i386/libsaio/fake_efi.c

1
2/*
3 * Copyright 2007 David F. Elliott. All rights reserved.
4 */
5
6#include "libsaio.h"
7#include "boot.h"
8#include "bootstruct.h"
9#include "efi.h"
10#include "acpi.h"
11#include "fake_efi.h"
12#include "efi_tables.h"
13#include "platform.h"
14#include "dsdt_patcher.h"
15#include "smbios_patcher.h"
16#include "device_inject.h"
17#include "convert.h"
18#include "pci.h"
19#include "sl.h"
20
21extern struct SMBEntryPoint * getSmbios();
22extern void setup_pci_devs(pci_dt_t *pci_dt);
23
24/*
25Modern Darwin kernels require some amount of EFI because Apple machines all
26have EFI. Modifying the kernel source to not require EFI is of course
27possible but would have to be maintained as a separate patch because it is
28unlikely that Apple wishes to add legacy support to their kernel.
29
30As you can see from the Apple-supplied code in bootstruct.c, it seems that
31the intention was clearly to modify this booter to provide EFI-like structures
32to the kernel rather than modifying the kernel to handle non-EFI stuff. This
33makes a lot of sense from an engineering point of view as it means the kernel
34for the as yet unreleased EFI-only Macs could still be booted by the non-EFI
35DTK systems so long as the kernel checked to ensure the boot tables were
36filled in appropriately. Modern xnu requires a system table and a runtime
37services table and performs no checks whatsoever to ensure the pointers to
38these tables are non-NULL. Therefore, any modern xnu kernel will page fault
39early on in the boot process if the system table pointer is zero.
40
41Even before that happens, the tsc_init function in modern xnu requires the FSB
42Frequency to be a property in the /efi/platform node of the device tree or else
43it panics the bootstrap process very early on.
44
45As of this writing, the current implementation found here is good enough
46to make the currently available xnu kernel boot without modification on a
47system with an appropriate processor. With a minor source modification to
48the tsc_init function to remove the explicit check for Core or Core 2
49processors the kernel can be made to boot on other processors so long as
50the code can be executed by the processor and the machine contains the
51necessary hardware.
52*/
53
54
55/*==========================================================================
56 * Utility function to make a device tree string from an EFI_GUID
57 */
58
59static inline char * mallocStringForGuid(EFI_GUID const *pGuid)
60{
61 char *string = malloc(37);
62 efi_guid_unparse_upper(pGuid, string);
63 return string;
64}
65
66
67/*==========================================================================
68 * Function to map 32 bit physical address to 64 bit virtual address
69 */
70static uint64_t ptov64(uint32_t addr)
71{
72 return ((uint64_t)addr | 0xFFFFFF8000000000ULL);
73}
74
75
76/*==========================================================================
77 * Fake EFI implementation
78 */
79
80/* Identify ourselves as the EFI firmware vendor */
81static EFI_CHAR16 const FIRMWARE_VENDOR[] = {'C','h','a','m','e','l','e','o','n','_','2','.','0', 0};
82static EFI_UINT32 const FIRMWARE_REVISION = 132; /* FIXME: Find a constant for this. */
83
84/* Default platform system_id (fix by IntVar) */
85static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF";//random value gen by uuidgen
86
87/* Just a ret instruction */
88static uint8_t const VOIDRET_INSTRUCTIONS[] = {0xc3};
89/* movl $0x80000003,%eax; ret */
90static uint8_t const UNSUPPORTEDRET_INSTRUCTIONS[] = {0xb8, 0x03, 0x00, 0x00, 0x80, 0xc3};
91
92
93/* We use the fake_efi_pages struct so that we only need to do one kernel
94 * memory allocation for all needed EFI data. Otherwise, small allocations
95 * like the FIRMWARE_VENDOR string would take up an entire page.
96 * NOTE WELL: Do NOT assume this struct has any particular layout within itself.
97 * It is absolutely not intended to be publicly exposed anywhere
98 * We say pages (plural) although right now we are well within the 1 page size
99 * and probably will stay that way.
100 */
101struct fake_efi_pages
102{
103 EFI_SYSTEM_TABLE_64 efiSystemTable;
104 EFI_RUNTIME_SERVICES_64 efiRuntimeServices;
105 EFI_CONFIGURATION_TABLE_64 efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];
106 EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];
107 uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];
108 uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];
109};
110
111EFI_SYSTEM_TABLE_64 *gST = NULL;
112Node *gEfiConfigurationTableNode = NULL;
113
114extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias)
115{
116 EFI_UINTN i = gST->NumberOfTableEntries;
117 /* We only do adds, not modifications and deletes like InstallConfigurationTable */
118 if(i >= MAX_CONFIGURATION_TABLE_ENTRIES)
119 stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n");
120
121 if(pGuid == NULL)
122 return EFI_INVALID_PARAMETER;
123
124 if(table != NULL)
125 {
126 /* FIXME
127 ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
128 ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;
129
130 ++gST->NumberOfTableEntries;
131 */
132 Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));
133
134 /* Use the pointer to the GUID we just stuffed into the system table */
135 DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);
136
137 /* The "table" property is the 32-bit (in our implementation) physical address of the table */
138 DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);
139
140 /* Assume the alias pointer is a global or static piece of data */
141 if(alias != NULL)
142 DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);
143
144 return EFI_SUCCESS;
145 }
146 return EFI_UNSUPPORTED;
147}
148
149static inline void fixupEfiSystemTableCRC32(EFI_SYSTEM_TABLE_64 *efiSystemTable)
150{
151 efiSystemTable->Hdr.CRC32 = 0;
152 efiSystemTable->Hdr.CRC32 = crc32(0L, efiSystemTable, efiSystemTable->Hdr.HeaderSize);
153}
154
155/*
156What we do here is simply allocate a fake EFI system table and a fake EFI
157runtime services table.
158
159Because we build against modern headers with kBootArgsRevision 4 we
160also take care to set efiMode = 32.
161*/
162void
163setupEfiTables(void)
164{
165 struct fake_efi_pages *fakeEfiPages= (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));
166
167 /* Zero out all the tables in case fields are added later */
168 bzero(fakeEfiPages, sizeof(struct fake_efi_pages));
169
170 /* --------------------------------------------------------------------
171 * Initialize some machine code that will return EFI_UNSUPPORTED for
172 * functions returning int and simply return for void functions.
173 */
174 memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));
175 memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));
176
177 /* -------------------------------------------------------------------- */
178 /* System table */
179 EFI_SYSTEM_TABLE_64 *efiSystemTable = gST = &fakeEfiPages->efiSystemTable;
180 efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;
181 efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;
182 efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_64);
183 efiSystemTable->Hdr.CRC32 = 0; /* Initialize to zero and then do CRC32 */
184 efiSystemTable->Hdr.Reserved = 0;
185
186 efiSystemTable->FirmwareVendor = (EFI_PTR32)&fakeEfiPages->firmwareVendor;
187 memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));
188 efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;
189
190 /* XXX: We may need to have basic implementations of ConIn/ConOut/StdErr */
191 /* The EFI spec states that all handles are invalid after boot services have been
192 * exited so we can probably get by with leaving the handles as zero. */
193 efiSystemTable->ConsoleInHandle = 0;
194 efiSystemTable->ConIn = 0;
195
196 efiSystemTable->ConsoleOutHandle = 0;
197 efiSystemTable->ConOut = 0;
198
199 efiSystemTable->StandardErrorHandle = 0;
200 efiSystemTable->StdErr = 0;
201
202 efiSystemTable->RuntimeServices = ptov64((EFI_PTR32)&fakeEfiPages->efiRuntimeServices);
203 /* According to the EFI spec, BootServices aren't valid after the
204 * boot process is exited so we can probably do without it.
205 * Apple didn't provide a definition for it in pexpert/i386/efi.h
206 * so I'm guessing they don't use it.
207 */
208 efiSystemTable->BootServices = 0;
209
210 efiSystemTable->NumberOfTableEntries = 0;
211 efiSystemTable->ConfigurationTable = (EFI_PTR32)fakeEfiPages->efiConfigurationTable;
212
213
214 /* We're done. Now CRC32 the thing so the kernel will accept it */
215 fixupEfiSystemTableCRC32(efiSystemTable);
216
217 /* -------------------------------------------------------------------- */
218 /* Runtime services */
219 EFI_RUNTIME_SERVICES_64 *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;
220 efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;
221 efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;
222 efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_64);
223 efiRuntimeServices->Hdr.CRC32 = 0;
224 efiRuntimeServices->Hdr.Reserved = 0;
225
226 /* There are a number of function pointers in the efiRuntimeServices table.
227 * These are the Foundation (e.g. core) services and are expected to be present on
228 * all EFI-compliant machines. Some kernel extensions (notably AppleEFIRuntime)
229 * will call these without checking to see if they are null.
230 *
231 * We don't really feel like doing an EFI implementation in the bootloader
232 * but it is nice if we can at least prevent a complete crash by
233 * at least providing some sort of implementation until one can be provided
234 * nicely in a kext.
235 */
236 void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;
237 void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;
238 efiRuntimeServices->GetTime = ptov64((EFI_PTR32)unsupportedret_fp);
239 efiRuntimeServices->SetTime = ptov64((EFI_PTR32)unsupportedret_fp);
240 efiRuntimeServices->GetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
241 efiRuntimeServices->SetWakeupTime = ptov64((EFI_PTR32)unsupportedret_fp);
242 efiRuntimeServices->SetVirtualAddressMap = ptov64((EFI_PTR32)unsupportedret_fp);
243 efiRuntimeServices->ConvertPointer = ptov64((EFI_PTR32)unsupportedret_fp);
244 efiRuntimeServices->GetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
245 efiRuntimeServices->GetNextVariableName = ptov64((EFI_PTR32)unsupportedret_fp);
246 efiRuntimeServices->SetVariable = ptov64((EFI_PTR32)unsupportedret_fp);
247 efiRuntimeServices->GetNextHighMonotonicCount = ptov64((EFI_PTR32)unsupportedret_fp);
248 efiRuntimeServices->ResetSystem = ptov64((EFI_PTR32)voidret_fp);
249
250 /* We're done. Now CRC32 the thing so the kernel will accept it */
251 efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);
252
253
254 /* -------------------------------------------------------------------- */
255 /* Finish filling in the rest of the boot args that we need. */
256 bootArgs->efiSystemTable = (uint32_t)efiSystemTable;
257 bootArgs->efiMode = kBootArgsEfiMode64;
258
259 /* The bootArgs structure as a whole is bzero'd so we don't need to fill in
260 * things like efiRuntimeServices* and what not.
261 *
262 * In fact, the only code that seems to use that is the hibernate code so it
263 * knows not to save the pages. It even checks to make sure its nonzero.
264 */
265}
266
267/*
268In addition to the EFI tables there is also the EFI device tree node.
269In particular, we need /efi/platform to have an FSBFrequency key. Without it,
270the tsc_init function will panic very early on in kernel startup, before
271the console is available.
272*/
273
274/*==========================================================================
275 * FSB Frequency detection
276 */
277
278/* These should be const but DT__AddProperty takes char* */
279static const char const TSC_Frequency_prop[] = "TSCFrequency";
280static const char const FSB_Frequency_prop[] = "FSBFrequency";
281static const char const CPU_Frequency_prop[] = "CPUFrequency";
282
283/*==========================================================================
284 * SMBIOS
285 */
286
287/* From Foundation/Efi/Guid/Smbios/SmBios.h */
288/* Modified to wrap Data4 array init with {} */
289#define EFI_SMBIOS_TABLE_GUID \
290 { \
291 0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d} \
292 }
293
294/* From Foundation/Efi/Guid/Smbios/SmBios.c */
295EFI_GUID const gEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID;
296
297#define SMBIOS_RANGE_START 0x000F0000
298#define SMBIOS_RANGE_END 0x000FFFFF
299
300/* '_SM_' in little endian: */
301#define SMBIOS_ANCHOR_UINT32_LE 0x5f4d535f
302
303#define EFI_ACPI_TABLE_GUID \
304 { \
305 0xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
306 }
307
308#define EFI_ACPI_20_TABLE_GUID \
309 { \
310 0x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
311 }
312
313EFI_GUID gEfiAcpiTableGuid = EFI_ACPI_TABLE_GUID;
314EFI_GUID gEfiAcpi20TableGuid = EFI_ACPI_20_TABLE_GUID;
315
316
317/*==========================================================================
318 * Fake EFI implementation
319 */
320
321/* These should be const but DT__AddProperty takes char* */
322static const char const FIRMWARE_REVISION_PROP[] = "firmware-revision";
323static const char const FIRMWARE_ABI_PROP[] = "firmware-abi";
324static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor";
325static const char const FIRMWARE_ABI_PROP_VALUE[] = "EFI64";
326static const char const SYSTEM_ID_PROP[] = "system-id";
327static const char const SYSTEM_SERIAL_PROP[] = "SystemSerialNumber";
328static const char const SYSTEM_TYPE_PROP[] = "system-type";
329static const char const MODEL_PROP[] = "Model";
330
331
332/* Get an smbios option string option to convert to EFI_CHAR16 string */
333static EFI_CHAR16* getSmbiosChar16(const char * key, size_t* len)
334{
335 const char * src= getStringForKey(key, &bootInfo->smbiosConfig);
336 EFI_CHAR16* dst = 0;
337 size_t i=0;
338
339 if (!key || !(*key) || !len || !src) return 0;
340
341 *len = strlen(src);
342 dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 );
343 for (; i < (*len); i++) dst[i] = src[i];
344 dst[(*len)] = '\0';
345 *len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16
346 return dst;
347}
348
349#define DEBUG_SMBIOS 0
350
351/* Get the SystemID from the bios dmi info */
352static EFI_CHAR8* getSmbiosUUID()
353{
354struct SMBEntryPoint*smbios;
355struct DMIHeader*dmihdr;
356SMBByte*p;
357inti, found, isZero, isOnes;
358static EFI_CHAR8 uuid[UUID_LEN+1]="";
359
360smbios = getAddressOfSmbiosTable();/* checks for _SM_ anchor and table header checksum */
361if (memcmp( &smbios->dmi.anchor[0], "_DMI_", 5) != 0) {
362return 0;
363}
364#if DEBUG_SMBIOS
365verbose(">>> SMBIOSAddr=0x%08x\n", smbios);
366verbose(">>> DMI: addr=0x%08x, len=0x%d, count=%d\n", smbios->dmi.tableAddress,
367smbios->dmi.tableLength, smbios->dmi.structureCount);
368#endif
369i = 0;
370found = 0;
371p = (SMBByte *) smbios->dmi.tableAddress;
372while (i < smbios->dmi.structureCount && p + 4 <= (SMBByte *)smbios->dmi.tableAddress + smbios->dmi.tableLength) {
373dmihdr = (struct DMIHeader *) p;
374#if DEBUG_SMBIOS
375verbose(">>>>>> DMI(%d): type=0x%02x, len=0x%d\n",i,dmihdr->type,dmihdr->length);
376#endif
377if (dmihdr->length < 4 || dmihdr->type == 127 /* EOT */) break;
378if (dmihdr->type == 1) /* 3.3.2 System Information */
379{
380 if (dmihdr->length >= 0x19) found = 1;
381break;
382}
383p = p + dmihdr->length;
384while ((p - (SMBByte *)smbios->dmi.tableAddress + 1 < smbios->dmi.tableLength) && (p[0] != 0x00 || p[1] != 0x00))
385{
386p++;
387}
388p += 2;
389i++;
390}
391
392if (!found) return 0;
393
394verbose("Found SMBIOS System Information Table 1\n");
395p += 8;
396
397for (i=0, isZero=1, isOnes=1; i<UUID_LEN; i++) {
398if (p[i] != 0x00) isZero = 0;
399if (p[i] != 0xff) isOnes = 0;
400}
401if (isZero || isOnes) {/* empty or setable means: no uuid present */
402verbose("No UUID present in SMBIOS System Information Table\n");
403return 0;
404}
405
406memcpy(uuid, p, UUID_LEN+1);
407uuid[UUID_LEN]=0;
408return uuid;
409}
410
411/* return a binary UUID value from the overriden SystemID and SMUUID if found,
412 * or from the bios if not, or from a fixed value if no bios value is found
413 */
414static EFI_CHAR8* getSystemID()
415{ // unable to determine UUID for host. Error: 35 fix
416
417 // Rek: new SMsystemid option conforming to smbios notation standards, this option should
418 // belong to smbios config only ...
419 const char * sysId = getStringForKey(kSystemID, &bootInfo->bootConfig);
420 EFI_CHAR8* ret = getUUIDFromString(sysId);
421
422 if(!sysId || !ret) { // try bios dmi info UUID extraction
423 ret = getSmbiosUUID();
424 sysId = getStringFromUUID(ret);
425 }
426 if(!ret) // no bios dmi UUID available, set a fixed value for system-id
427 ret=getUUIDFromString((sysId = (const char*) SYSTEM_ID));
428
429 verbose("Customizing SystemID with : %s\n", sysId);
430 return ret;
431}
432
433void setupEfiDeviceTree(void)
434{
435 EFI_CHAR16* ret16=0;
436 EFI_CHAR8* ret=0;
437 size_t len=0;
438 Node *node;
439 const char *value;
440
441 node = DT__FindNode("/", false);
442
443 if (node == 0) stop("Couldn't get root node");
444
445 /* Export system-type only if it has been overrriden by the SystemType option */
446 Platform.Type = 1;/* Desktop */
447 if (getValueForKey(kSystemType, &value, &len, &bootInfo->bootConfig) && value != NULL)
448 {
449 if (Platform.Type > 6)
450verbose("Error: system-type must be 0..6. Defaulting to 1!\n");
451 else
452Platform.Type = (unsigned char) strtoul(value, NULL, 10);
453 verbose("Using system-type=0x%02x\n", Platform.Type);
454 DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform.Type), &Platform.Type);
455 }
456
457 /* We could also just do DT__FindNode("/efi/platform", true)
458 * But I think eventually we want to fill stuff in the efi node
459 * too so we might as well create it so we have a pointer for it too.
460 */
461 node = DT__AddChild(node, "efi");
462
463 DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
464 DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE);
465 DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);
466
467 /* TODO: Fill in other efi properties if necessary */
468
469 /* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
470 * is set up. That is, name and table properties */
471 Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");
472
473 /* The value of the table property is the 32-bit physical address for the RuntimeServices table.
474 * Since the EFI system table already has a pointer to it, we simply use the address of that pointer
475 * for the pointer to the property data. Warning.. DT finalization calls free on that but we're not
476 * the only thing to use a non-malloc'd pointer for something in the DT
477 */
478 DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices);
479
480 /* Set up the /efi/configuration-table node which will eventually have several child nodes for
481 * all of the configuration tables needed by various kernel extensions.
482 */
483 gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");
484
485 /* Now fill in the /efi/platform Node */
486 Node *efiPlatformNode = DT__AddChild(node, "platform");
487
488 /* NOTE WELL: If you do add FSB Frequency detection, make sure to store
489 * the value in the fsbFrequency global and not an malloc'd pointer
490 * because the DT_AddProperty function does not copy its args.
491 */
492 if(Platform.CPU.FSBFrequency != 0)
493 DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
494
495 /* Export TSC and CPU frequencies for use by the kernel or KEXTs */
496 if(Platform.CPU.TSCFrequency != 0)
497 DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
498
499 if(Platform.CPU.CPUFrequency != 0)
500 DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
501
502 /* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */
503 if((ret=getSystemID()))
504 DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret);
505
506 /* Export SystemSerialNumber if present */
507 if ((ret16=getSmbiosChar16("SMserial", &len)))
508 DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16);
509
510 /* Export Model if present */
511 if ((ret16=getSmbiosChar16("SMproductname", &len)))
512 DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16);
513
514 /* Fill /efi/device-properties node.
515 */
516 setupDeviceProperties(node);
517}
518
519/* Load the smbios.plist override config file if any */
520static void setupSmbiosConfigFile()
521{
522 const char * value = getStringForKey(kSMBIOS, &bootInfo->bootConfig);
523 if (!value) value = "/Extra/smbios.plist";
524 if (loadConfigFile(value, &bootInfo->smbiosConfig) == -1) {
525 verbose("No SMBIOS replacement found\n");
526 }
527}
528
529/* Installs all the needed configuration table entries */
530void setupEfiConfigurationTable()
531{
532 smbios_p = (EFI_PTR32)getSmbios();
533 addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL);
534
535 // Setup ACPI with DSDT overrides (mackerintel's patch)
536 setupAcpi();
537
538 // We've obviously changed the count.. so fix up the CRC32
539 fixupEfiSystemTableCRC32(gST);
540}
541
542void setupEfiDevices(void)
543{
544setup_pci_devs(root_pci_dev);
545}
546
547/* Entrypoint from boot.c */
548void setupFakeEfi(void)
549{
550 // load smbios.plist file if any
551 setupSmbiosConfigFile();
552
553 // Generate efi device strings
554setupEfiDevices();
555
556// Initialize the base table
557setupEfiTables();
558
559 // Initialize the device tree
560 setupEfiDeviceTree();
561
562 // Add configuration table entries to both the services table and the device tree
563 setupEfiConfigurationTable();
564}
565
566

Archive Download this file

Revision: 44