Chameleon

Chameleon Svn Source Tree

Root/branches/cparm/i386/libsaio/fake_efi.c

1
2/*
3 * Copyright 2007 David F. Elliott. All rights reserved.
4 */
5
6/*
7 * Copyright 2010,2011 Cadet-petit Armel <armelcadetpetit@gmail.com>. All rights reserved.
8 */
9
10#include "libsaio.h"
11#include "boot.h"
12#include "bootstruct.h"
13#include "efi.h"
14#include "acpi.h"
15#include "fake_efi.h"
16#include "efi_tables.h"
17#include "platform.h"
18#include "device_inject.h"
19#include "convert.h"
20#include "pci.h"
21#include "sl.h"
22#include "modules.h"
23
24/*
25 * Modern Darwin kernels require some amount of EFI because Apple machines all
26 * have EFI. Modifying the kernel source to not require EFI is of course
27 * possible but would have to be maintained as a separate patch because it is
28 * unlikely that Apple wishes to add legacy support to their kernel.
29 *
30 * As you can see from the Apple-supplied code in bootstruct.c, it seems that
31 * the intention was clearly to modify this booter to provide EFI-like structures
32 * to the kernel rather than modifying the kernel to handle non-EFI stuff. This
33 * makes a lot of sense from an engineering point of view as it means the kernel
34 * for the as yet unreleased EFI-only Macs could still be booted by the non-EFI
35 * DTK systems so long as the kernel checked to ensure the boot tables were
36 * filled in appropriately. Modern xnu requires a system table and a runtime
37 * services table and performs no checks whatsoever to ensure the pointers to
38 * these tables are non-NULL.Therefore, any modern xnu kernel will page fault
39 * early on in the boot process if the system table pointer is zero.
40 *
41 * Even before that happens, the tsc_init function in modern xnu requires the FSB
42 * Frequency to be a property in the /efi/platform node of the device tree or else
43 * it panics the bootstrap process very early on.
44 *
45 * As of this writing, the current implementation found here is good enough
46 * to make the currently available xnu kernel boot without modification on a
47 * system with an appropriate processor. With a minor source modification to
48 * the tsc_init function to remove the explicit check for Core or Core 2
49 * processors the kernel can be made to boot on other processors so long as
50 * the code can be executed by the processor and the machine contains the
51 * necessary hardware.
52 */
53
54/*==========================================================================
55 * Utility function to make a device tree string from an EFI_GUID
56 */
57
58static inline char * mallocStringForGuid(EFI_GUID const *pGuid)
59{
60char *string = malloc(37);
61efi_guid_unparse_upper(pGuid, string);
62return string;
63}
64
65/*==========================================================================
66 * Function to map 32 bit physical address to 64 bit virtual address
67 */
68
69#define ptov64(addr) (uint64_t)((uint64_t)addr | 0xFFFFFF8000000000ULL)
70
71/*==========================================================================
72 * Fake EFI implementation
73 */
74
75/* Identify ourselves as the EFI firmware vendor */
76static EFI_CHAR16 const FIRMWARE_VENDOR[] = {'J','a','r','o','d','_','1','.','2', 0};
77static EFI_UINT32 const FIRMWARE_REVISION = 0x0001000a;
78static EFI_UINT32 const DEVICE_SUPPORTED = 0x00000001;
79
80/* Default platform system_id (fix by IntVar) */
81static EFI_CHAR8 const SYSTEM_ID[] = "0123456789ABCDEF"; //random value gen by uuidgen
82
83/* Just a ret instruction */
84static uint8_t const VOIDRET_INSTRUCTIONS[] = {0xc3};
85
86/* movl $0x80000003,%eax; ret */
87static uint8_t const UNSUPPORTEDRET_INSTRUCTIONS[] = {0xb8, 0x03, 0x00, 0x00, 0x80, 0xc3};
88
89EFI_SYSTEM_TABLE_32 *gST32 = NULL;
90EFI_SYSTEM_TABLE_64 *gST64 = NULL;
91Node *gEfiConfigurationTableNode = NULL;
92
93extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias)
94{
95EFI_UINTN i = 0;
96
97//Azi: as is, cpu's with em64t will use EFI64 on pre 10.6 systems,
98// wich seems to cause no problem. In case it does, force i386 arch.
99if (archCpuType == CPU_TYPE_I386)
100{
101i = gST32->NumberOfTableEntries;
102}
103else
104{
105i = gST64->NumberOfTableEntries;
106}
107
108// We only do adds, not modifications and deletes like InstallConfigurationTable
109if (i >= MAX_CONFIGURATION_TABLE_ENTRIES)
110stop("Ran out of space for configuration tables. Increase the reserved size in the code.\n");
111
112if (pGuid == NULL)
113return EFI_INVALID_PARAMETER;
114
115if (table != NULL)
116{
117// FIXME
118//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
119//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;
120
121//++gST->NumberOfTableEntries;
122
123Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));
124
125// Use the pointer to the GUID we just stuffed into the system table
126DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);
127
128// The "table" property is the 32-bit (in our implementation) physical address of the table
129DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);
130
131// Assume the alias pointer is a global or static piece of data
132if (alias != NULL)
133DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);
134
135return EFI_SUCCESS;
136}
137return EFI_UNSUPPORTED;
138}
139
140/*
141 * What we do here is simply allocate a fake EFI system table and a fake EFI
142 * runtime services table.
143 *
144 * Because we build against modern headers with kBootArgsRevision 4 we
145 * also take care to set efiMode = 32.
146 */
147
148#define pto(mode, addr) (mode == 64) ? ptov64((EFI_PTR32)addr) : (EFI_PTR32)addr
149
150
151#define setupEfiTables(mode) \
152{ \
153struct fake_efi_pages \
154{\
155/* We use the fake_efi_pages struct so that we only need to do one kernel
156 * memory allocation for all needed EFI data. Otherwise, small allocations
157 * like the FIRMWARE_VENDOR string would take up an entire page.
158 * NOTE WELL: Do NOT assume this struct has any particular layout within itself.
159 * It is absolutely not intended to be publicly exposed anywhere
160 * We say pages (plural) although right now we are well within the 1 page size
161 * and probably will stay that way.
162 */\
163EFI_SYSTEM_TABLE_##mode efiSystemTable;\
164EFI_RUNTIME_SERVICES_##mode efiRuntimeServices;\
165EFI_CONFIGURATION_TABLE_##mode efiConfigurationTable[MAX_CONFIGURATION_TABLE_ENTRIES];\
166EFI_CHAR16 firmwareVendor[sizeof(FIRMWARE_VENDOR)/sizeof(EFI_CHAR16)];\
167uint8_t voidret_instructions[sizeof(VOIDRET_INSTRUCTIONS)/sizeof(uint8_t)];\
168uint8_t unsupportedret_instructions[sizeof(UNSUPPORTEDRET_INSTRUCTIONS)/sizeof(uint8_t)];\
169};\
170struct fake_efi_pages *fakeEfiPages = (struct fake_efi_pages*)AllocateKernelMemory(sizeof(struct fake_efi_pages));\
171/* Zero out all the tables in case fields are added later*/\
172bzero(fakeEfiPages, sizeof(struct fake_efi_pages));\
173/*--------------------------------------------------------------------
174 * Initialize some machine code that will return EFI_UNSUPPORTED for
175 * functions returning int and simply return for void functions.*/\
176memcpy(fakeEfiPages->voidret_instructions, VOIDRET_INSTRUCTIONS, sizeof(VOIDRET_INSTRUCTIONS));\
177memcpy(fakeEfiPages->unsupportedret_instructions, UNSUPPORTEDRET_INSTRUCTIONS, sizeof(UNSUPPORTEDRET_INSTRUCTIONS));\
178/*--------------------------------------------------------------------
179 * System table*/\
180EFI_SYSTEM_TABLE_##mode *efiSystemTable = gST##mode = &fakeEfiPages->efiSystemTable;\
181efiSystemTable->Hdr.Signature = EFI_SYSTEM_TABLE_SIGNATURE;\
182efiSystemTable->Hdr.Revision = EFI_SYSTEM_TABLE_REVISION;\
183efiSystemTable->Hdr.HeaderSize = sizeof(EFI_SYSTEM_TABLE_##mode);\
184efiSystemTable->Hdr.CRC32 = 0;/*Initialize to zero and then do CRC32*/ \
185efiSystemTable->Hdr.Reserved = 0;\
186efiSystemTable->FirmwareVendor = pto(mode, &fakeEfiPages->firmwareVendor);\
187memcpy(fakeEfiPages->firmwareVendor, FIRMWARE_VENDOR, sizeof(FIRMWARE_VENDOR));\
188efiSystemTable->FirmwareRevision = FIRMWARE_REVISION;\
189/* XXX: We may need to have basic implementations of ConIn/ConOut/StdErr
190 * The EFI spec states that all handles are invalid after boot services have been
191 * exited so we can probably get by with leaving the handles as zero.
192 */\
193efiSystemTable->ConsoleInHandle = 0;\
194efiSystemTable->ConIn = 0;\
195efiSystemTable->ConsoleOutHandle = 0;\
196efiSystemTable->ConOut = 0;\
197efiSystemTable->StandardErrorHandle = 0;\
198efiSystemTable->StdErr = 0;\
199efiSystemTable->RuntimeServices = pto(mode,&fakeEfiPages->efiRuntimeServices) ;\
200/* According to the EFI spec, BootServices aren't valid after the
201 * boot process is exited so we can probably do without it.
202 * Apple didn't provide a definition for it in pexpert/i386/efi.h
203 * so I'm guessing they don't use it.
204 */\
205efiSystemTable->BootServices = 0;\
206efiSystemTable->NumberOfTableEntries = 0;\
207efiSystemTable->ConfigurationTable = pto(mode,fakeEfiPages->efiConfigurationTable);\
208/* We're done. Now CRC32 the thing so the kernel will accept it.
209 * Must be initialized to zero before CRC32, done above.
210 */\
211gST##mode->Hdr.CRC32 = crc32(0L, gST##mode, gST##mode->Hdr.HeaderSize);\
212/*--------------------------------------------------------------------
213 * Runtime services*/\
214EFI_RUNTIME_SERVICES_##mode *efiRuntimeServices = &fakeEfiPages->efiRuntimeServices;\
215efiRuntimeServices->Hdr.Signature = EFI_RUNTIME_SERVICES_SIGNATURE;\
216efiRuntimeServices->Hdr.Revision = EFI_RUNTIME_SERVICES_REVISION;\
217efiRuntimeServices->Hdr.HeaderSize = sizeof(EFI_RUNTIME_SERVICES_##mode);\
218efiRuntimeServices->Hdr.CRC32 = 0;\
219efiRuntimeServices->Hdr.Reserved = 0;\
220/* There are a number of function pointers in the efiRuntimeServices table.
221 * These are the Foundation (e.g. core) services and are expected to be present on
222 * all EFI-compliant machines.Some kernel extensions (notably AppleEFIRuntime)
223 * will call these without checking to see if they are null.
224 *
225 * We don't really feel like doing an EFI implementation in the bootloader
226 * but it is nice if we can at least prevent a complete crash by
227 * at least providing some sort of implementation until one can be provided
228 * nicely in a kext.
229 */\
230void (*voidret_fp)() = (void*)fakeEfiPages->voidret_instructions;\
231void (*unsupportedret_fp)() = (void*)fakeEfiPages->unsupportedret_instructions;\
232efiRuntimeServices->GetTime = pto(mode,unsupportedret_fp);\
233efiRuntimeServices->SetTime = pto(mode,unsupportedret_fp);\
234efiRuntimeServices->GetWakeupTime = pto(mode,unsupportedret_fp);\
235efiRuntimeServices->SetWakeupTime = pto(mode,unsupportedret_fp);\
236efiRuntimeServices->SetVirtualAddressMap = pto(mode,unsupportedret_fp);\
237efiRuntimeServices->ConvertPointer = pto(mode,unsupportedret_fp);\
238efiRuntimeServices->GetVariable = pto(mode,unsupportedret_fp);\
239efiRuntimeServices->GetNextVariableName = pto(mode,unsupportedret_fp);\
240efiRuntimeServices->SetVariable = pto(mode,unsupportedret_fp);\
241efiRuntimeServices->GetNextHighMonotonicCount = pto(mode,unsupportedret_fp);\
242efiRuntimeServices->ResetSystem = pto(mode,voidret_fp);\
243/*We're done.Now CRC32 the thing so the kernel will accept it*/\
244efiRuntimeServices->Hdr.CRC32 = crc32(0L, efiRuntimeServices, efiRuntimeServices->Hdr.HeaderSize);\
245/*--------------------------------------------------------------------
246 * Finish filling in the rest of the boot args that we need.*/\
247bootArgs->efiSystemTable = (uint32_t)efiSystemTable;\
248bootArgs->efiMode = kBootArgsEfiMode##mode;\
249/* The bootArgs structure as a whole is bzero'd so we don't need to fill in
250 * things like efiRuntimeServices* and what not.
251 *
252 * In fact, the only code that seems to use that is the hibernate code so it
253 * knows not to save the pages. It even checks to make sure its nonzero.
254*/\
255}
256
257
258/*
259 * In addition to the EFI tables there is also the EFI device tree node.
260 * In particular, we need /efi/platform to have an FSBFrequency key. Without it,
261 * the tsc_init function will panic very early on in kernel startup, before
262 * the console is available.
263 */
264
265/*==========================================================================
266 * FSB Frequency detection
267 */
268
269/* These should be const but DT__AddProperty takes char* */
270static const char const TSC_Frequency_prop[] = "TSCFrequency";
271static const char const FSB_Frequency_prop[] = "FSBFrequency";
272static const char const CPU_Frequency_prop[] = "CPUFrequency";
273
274/*==========================================================================
275 * SMBIOS
276 */
277
278/* From Foundation/Efi/Guid/Smbios/SmBios.h */
279/* Modified to wrap Data4 array init with {} */
280#define EFI_SMBIOS_TABLE_GUID {0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
281
282/* From Foundation/Efi/Guid/Smbios/SmBios.c */
283EFI_GUID constgEfiSmbiosTableGuid = EFI_SMBIOS_TABLE_GUID;
284
285#define SMBIOS_RANGE_START0x000F0000
286#define SMBIOS_RANGE_END0x000FFFFF
287
288/* '_SM_' in little endian: */
289#define SMBIOS_ANCHOR_UINT32_LE 0x5f4d535f
290
291#ifndef DEBUG_SMBIOS
292#define DEBUG_SMBIOS 0
293#endif
294
295#if DEBUG_SMBIOS
296#define DBG(x...)printf(x)
297#else
298#define DBG(x...)
299#endif
300
301uint64_t smbios_p;
302
303// getting smbios addr with fast compare ops, late checksum testing ...
304#define COMPARE_DWORD(a,b) ( *((u_int32_t *) a) == *((u_int32_t *) b) )
305static const char * const SMTAG = "_SM_";
306static const char* const DMITAG= "_DMI_";
307
308static struct SMBEntryPoint *getAddressOfSmbiosTable(void)
309{
310struct SMBEntryPoint*smbios;
311/*
312 * The logic is to start at 0xf0000 and end at 0xfffff iterating 16 bytes at a time looking
313 * for the SMBIOS entry-point structure anchor (literal ASCII "_SM_").
314 */
315smbios = (struct SMBEntryPoint*) SMBIOS_RANGE_START;
316while (smbios <= (struct SMBEntryPoint *)SMBIOS_RANGE_END) {
317if (COMPARE_DWORD(smbios->anchor, SMTAG) &&
318COMPARE_DWORD(smbios->dmi.anchor, DMITAG) &&
319smbios->dmi.anchor[4]==DMITAG[4] &&
320checksum8(smbios, sizeof(struct SMBEntryPoint)) == 0)
321 {
322return smbios;
323 }
324smbios = (struct SMBEntryPoint*) ( ((char*) smbios) + 16 );
325}
326printf("Error: Could not find original SMBIOS !!\n");
327pause();
328return NULL;
329}
330
331static struct SMBEntryPoint *orig = NULL; // cached
332
333struct SMBEntryPoint *getSmbiosOriginal()
334{
335 if (orig == NULL) {
336orig = getAddressOfSmbiosTable();
337
338if (orig) {
339verbose("Found System Management BIOS (SMBIOS) table\n");
340}
341
342 }
343 return orig;
344}
345
346
347#define theUUID 0
348#define thePlatformName 1
349
350/* get UUID or product Name from original SMBIOS, stripped version of kabyl's readSMBIOSInfo */
351void local_readSMBIOS(int value)
352{
353
354SMBEntryPoint *eps = getSmbiosOriginal();
355if (eps == NULL) return;
356
357uint8_t *structPtr = (uint8_t *)eps->dmi.tableAddress;
358SMBStructHeader *structHeader = (SMBStructHeader *)structPtr;
359
360for (;((eps->dmi.tableAddress + eps->dmi.tableLength) > ((uint32_t)(uint8_t *)structHeader + sizeof(SMBStructHeader)));)
361{
362switch (structHeader->type)
363{
364case 1: //kSMBTypeSystemInformation
365{
366switch (value) {
367case theUUID:
368Platform->UUID = ((SMBSystemInformation *)structHeader)->uuid;
369break;
370case thePlatformName:
371{
372uint8_t *stringPtr = (uint8_t *)structHeader + structHeader->length;
373uint8_t field = ((SMBSystemInformation *)structHeader)->productName;
374
375if (!field)
376return;
377
378for (field--; field != 0 && strlen((char *)stringPtr) > 0;
379 field--, stringPtr = (uint8_t *)((uint32_t)stringPtr + strlen((char *)stringPtr) + 1));
380
381DBG("original SMBIOS Product name: %s\n",(char *)stringPtr);
382gPlatformName = (char *)stringPtr;
383break;
384}
385default:
386break;
387}
388
389return;
390
391break;
392}
393
394}
395
396structPtr = (uint8_t *)((uint32_t)structHeader + structHeader->length);
397for (; ((uint16_t *)structPtr)[0] != 0; structPtr++);
398
399if (((uint16_t *)structPtr)[0] == 0)
400structPtr += 2;
401
402structHeader = (SMBStructHeader *)structPtr;
403}
404}
405
406/*==========================================================================
407 * ACPI
408 */
409
410#define EFI_ACPI_TABLE_GUID \
411 { \
4120xeb9d2d30, 0x2d88, 0x11d3, { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
413 }
414
415#define EFI_ACPI_20_TABLE_GUID \
416 { \
4170x8868e871, 0xe4f1, 0x11d3, { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
418 }
419
420EFI_GUID gEfiAcpiTableGuid = EFI_ACPI_TABLE_GUID;
421EFI_GUID gEfiAcpi20TableGuid = EFI_ACPI_20_TABLE_GUID;
422
423uint64_t acpi10_p;
424uint64_t acpi20_p;
425
426static uint64_t local_acpi10_p;
427static uint64_t local_acpi20_p;
428
429#define tableSign(table, sgn) (table[0]==sgn[0] && table[1]==sgn[1] && table[2]==sgn[2] && table[3]==sgn[3])
430
431static struct acpi_common_header * get_ACPI_TABLE(const char * table);
432static struct acpi_2_fadt *gFADT = 0;
433
434#define EFI_MPS_TABLE_GUID \
435{ \
4360xeb9d2d2f,0x2d88,0x11d3,{0x9a,0x16,0x0,0x90,0x27,0x3f,0xc1,0x4d} \
437}
438EFI_GUID gEfiMpsTableGuid = EFI_MPS_TABLE_GUID;
439
440#define MP_SIGL 0x5f504d5f
441#define MP_SIGSTR "_MP_"
442struct mp_t {
443uint8_t sig[4];
444uint32_t config_ptr;
445uint8_t len;
446uint8_t ver;
447uint8_t checksum;
448uint8_t f1;
449uint8_t f2;
450uint8_t fr[3];
451}__attribute__((packed)) mp_t;
452
453/*
454 * THIS FILE USE SOME CODE FROM smp-imps
455 *
456 * <Insert copyright here : it must be BSD-like so anyone can use it>
457 *
458 * Author: Erich Boleyn <erich@uruk.org> http://www.uruk.org/~erich/
459 *
460 * Source file implementing Intel MultiProcessor Specification (MPS)
461 * version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs,
462 * with hooks for running correctly on a standard PC without the hardware.
463 *
464 * This file was created from information in the Intel MPS version 1.4
465 * document, order number 242016-004, which can be ordered from the
466 * Intel literature center.
467 *
468 * General limitations of this code:
469 *
470 * (1) : This code has never been tested on an MPS-compatible system with
471 * 486 CPUs, but is expected to work.
472 * (2) : Presumes "int", "long", and "unsigned" are 32 bits in size, and
473 * that 32-bit pointers and memory addressing is used uniformly.
474 */
475
476/*
477 * MP Configuration Table Header (cth)
478 *
479 * Look at page 4-5 of the MP spec for the starting definitions of
480 * this structure.
481 */
482struct imps_cth
483{
484unsigned sig;
485unsigned short base_length;
486unsigned char spec_rev;
487unsigned char checksum;
488char oem_id[8];
489char prod_id[12];
490unsigned oem_table_ptr;
491unsigned short oem_table_size;
492unsigned short entry_count;
493unsigned lapic_addr;
494unsigned short extended_length;
495unsigned char extended_checksum;
496char reserved[1];
497};
498
499static inline void
500cmos_write_byte (int loc, int val)
501{
502outb (0x70, loc);
503outb (0x71, val);
504}
505
506static inline unsigned
507cmos_read_byte (int loc)
508{
509outb (0x70, loc);
510return inb (0x71);
511}
512
513#define LAPIC_ID0x20
514
515static int lapic_dummy = 0;
516unsigned imps_lapic_addr = ((unsigned)(&lapic_dummy)) - LAPIC_ID;
517
518#include "smp.h"
519
520#define CMOS_WRITE_BYTE(x, y)cmos_write_byte(x, y)
521#define CMOS_READ_BYTE(x)cmos_read_byte(x)
522
523/*
524 * Defines that are here so as not to be in the global header file.
525 */
526#define EBDA_SEG_ADDR0x40E
527#define EBDA_SEG_LEN0x400
528#define BIOS_RESET_VECTOR0x467
529#define LAPIC_ADDR_DEFAULT0xFEE00000uL
530#define IOAPIC_ADDR_DEFAULT0xFEC00000uL
531#define CMOS_RESET_CODE0xF
532#defineCMOS_RESET_JUMP0xa
533#define CMOS_BASE_MEMORY0x15
534
535static struct mp_t *
536biosacpi_search_mp(char *base, int length);
537
538struct mp_t* getAddressOfMPSTable()
539{
540struct mp_t *mp;
541 uint16_t*addr;
542
543 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
544 addr = (uint16_t *)ptov(EBDA_SEG_ADDR);
545 if ((mp = biosacpi_search_mp((char *)(*addr << 4), EBDA_SEG_LEN)) != NULL)
546return (mp);
547
548unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
549 | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10;
550
551if ((mp = biosacpi_search_mp((char *)mem_lower, EBDA_SEG_LEN)) != NULL)
552return (mp);
553
554 if ((mp = biosacpi_search_mp((char *)0x00F0000, ACPI_RANGE_END)) != NULL)
555return (mp);
556
557 return (NULL);
558
559}
560
561static struct mp_t *
562biosacpi_search_mp(char *base, int length)
563{
564/* TODO: Before searching the BIOS space we are supposed to search the first 1K of the EBDA */
565struct mp_t *mp;
566 intofs;
567
568 /* search on 16-byte boundaries */
569 for (ofs = 0; ofs < length; ofs += 16) {
570
571mp = (struct mp_t*)ptov(base + ofs);
572
573/* compare signature, validate checksum */
574if (!strncmp((char*)mp->sig, MP_SIGSTR, strlen(MP_SIGSTR))) {
575uint8_t csum = checksum8(mp, sizeof(struct mp_t));
576if(csum == 0) {
577return mp;
578}
579
580}
581}
582 return NULL;
583}
584
585#define ACPI_SIG_RSDP "RSD PTR " /* Root System Description Pointer */
586#define RSDP_CHECKSUM_LENGTH 20
587
588/*-
589 *FOR biosacpi_search_rsdp AND biosacpi_find_rsdp
590 *
591 * Copyright (c) 2001 Michael Smith <msmith@freebsd.org>
592 * All rights reserved.
593 *
594 * Redistribution and use in source and binary forms, with or without
595 * modification, are permitted provided that the following conditions
596 * are met:
597 * 1. Redistributions of source code must retain the above copyright
598 * notice, this list of conditions and the following disclaimer.
599 * 2. Redistributions in binary form must reproduce the above copyright
600 * notice, this list of conditions and the following disclaimer in the
601 * documentation and/or other materials provided with the distribution.
602 *
603 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
604 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
605 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
606 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
607 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
608 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
609 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
610 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
611 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
612 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
613 * SUCH DAMAGE.
614 *
615 * $FreeBSD: src/sys/boot/i386/libi386/biosacpi.c,v 1.7 2003/08/25 23:28:31 obrien Exp $
616 * $DragonFly: src/sys/boot/pc32/libi386/biosacpi.c,v 1.5 2007/01/17 17:31:19 y0netan1 Exp $
617 */
618
619static struct acpi_2_rsdp *
620biosacpi_search_rsdp(char *base, int length, int rev);
621
622/*
623 * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec.
624 */
625static struct acpi_2_rsdp *
626biosacpi_find_rsdp(int rev)
627{
628 struct acpi_2_rsdp *rsdp;
629 uint16_t*addr;
630
631 /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */
632 addr = (uint16_t *)ptov(EBDA_SEG_ADDR);
633 if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), EBDA_SEG_LEN, rev)) != NULL)
634return (rsdp);
635
636unsigned mem_lower = ((CMOS_READ_BYTE(CMOS_BASE_MEMORY+1) << 8)
637 | CMOS_READ_BYTE(CMOS_BASE_MEMORY)) << 10;
638
639if ((rsdp = biosacpi_search_rsdp((char *)mem_lower, EBDA_SEG_LEN, rev)) != NULL)
640return (rsdp);
641
642
643 /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */
644 if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000, rev)) != NULL)
645return (rsdp);
646
647 return (NULL);
648}
649
650static struct acpi_2_rsdp *
651biosacpi_search_rsdp(char *base, int length, int rev)
652{
653 struct acpi_2_rsdp *rsdp;
654 intofs;
655
656 /* search on 16-byte boundaries */
657 for (ofs = 0; ofs < length; ofs += 16) {
658rsdp = (struct acpi_2_rsdp*)ptov(base + ofs);
659
660/* compare signature, validate checksum */
661if (!strncmp(rsdp->Signature, ACPI_SIG_RSDP, strlen(ACPI_SIG_RSDP))) {
662
663uint8_t csum = checksum8(rsdp, RSDP_CHECKSUM_LENGTH);
664 if(csum == 0)
665 {
666/* Only assume this is a 2.0 or better table if the revision is greater than 0
667 * NOTE: ACPI 3.0 spec only seems to say that 1.0 tables have revision 1
668 * and that the current revision is 2.. I am going to assume that rev > 0 is 2.0.
669 */
670
671if((rsdp->Revision > 0) && rev > 0)
672{
673uint8_t csum2 = checksum8(rsdp, sizeof(struct acpi_2_rsdp));
674if(csum2 == 0)
675return(rsdp);
676}
677
678 // Only return the table if it is a true version 1.0 table (Revision 0)
679 if((rsdp->Revision == 0) && rev == 0)
680 return(rsdp);
681 }
682
683}
684 }
685 return(NULL);
686}
687
688/* Setup ACPI without any patch. */
689static int setupAcpiNoMod()
690{
691int ret = 0;
692if(local_acpi20_p) {
693addConfigurationTable(&gEfiAcpi20TableGuid, &local_acpi20_p, "ACPI_20");
694ret = 1;
695} else if (local_acpi10_p) {
696addConfigurationTable(&gEfiAcpiTableGuid, &local_acpi10_p, "ACPI");
697ret = 1;
698}
699
700
701return ret;
702}
703
704int setup_acpi (void)
705{
706int ret = 0;
707
708/* XXX aserebln why uint32 cast if pointer is uint64 ? */
709acpi10_p = local_acpi10_p = (uint32_t)biosacpi_find_rsdp(0);
710acpi20_p = local_acpi20_p = (uint32_t)biosacpi_find_rsdp(2);
711
712execute_hook("setupEfiConfigurationTable", &ret, NULL, NULL, NULL, NULL, NULL);
713
714if (!ret) {
715gFADT = (struct acpi_2_fadt *)get_ACPI_TABLE("FACP");
716uint8_t type = gFADT->PM_Profile;
717if (type <= MaxSupportedPMProfile) {
718Platform->Type = type;
719}
720ret = setupAcpiNoMod();
721}
722
723return ret;
724
725}
726
727/*==========================================================================
728 * Fake EFI implementation
729 */
730
731/* These should be const but DT__AddProperty takes char* */
732static const char const FIRMWARE_REVISION_PROP[] = "firmware-revision";
733static const char const FIRMWARE_ABI_PROP[] = "firmware-abi";
734static const char const FIRMWARE_VENDOR_PROP[] = "firmware-vendor";
735static const char const FIRMWARE_ABI_32_PROP_VALUE[] = "EFI32";
736static const char const FIRMWARE_ABI_64_PROP_VALUE[] = "EFI64";
737static const char const SYSTEM_ID_PROP[] = "system-id";
738static const char const SYSTEM_SERIAL_PROP[] = "SystemSerialNumber";
739static const char const SYSTEM_TYPE_PROP[] = "system-type";
740static const char const MODEL_PROP[] = "Model";
741
742
743/*
744 * Get an smbios option string option to convert to EFI_CHAR16 string
745 */
746
747static EFI_CHAR16* getSmbiosChar16(const char * key, size_t* len)
748{
749if (!gPlatformName && strcmp(key, "SMproductname") == 0)
750local_readSMBIOS(thePlatformName);
751
752const char*src = (strcmp(key, "SMproductname") == 0) ? gPlatformName : getStringForKey(key, &bootInfo->smbiosConfig);
753
754EFI_CHAR16* dst = 0;
755size_t i = 0;
756
757if (!key || !(*key) || !src) return 0;
758
759*len = strlen(src);
760dst = (EFI_CHAR16*) malloc( ((*len)+1) * 2 );
761for (; i < (*len); i++) dst[i] = src[i];
762dst[(*len)] = '\0';
763*len = ((*len)+1)*2; // return the CHAR16 bufsize in cluding zero terminated CHAR16
764return dst;
765}
766
767/*
768 * Get the SystemID from the bios dmi info
769 */
770
771staticEFI_CHAR8* getSmbiosUUID()
772{
773static EFI_CHAR8 uuid[UUID_LEN];
774int i, isZero, isOnes;
775SMBByte*p;
776
777local_readSMBIOS(theUUID);
778p = (SMBByte*)Platform->UUID;
779for (i=0, isZero=1, isOnes=1; i<UUID_LEN; i++)
780{
781if (p[i] != 0x00) isZero = 0;
782if (p[i] != 0xff) isOnes = 0;
783}
784
785if (isZero || isOnes) // empty or setable means: no uuid present
786{
787verbose("No UUID present in SMBIOS System Information Table\n");
788return 0;
789}
790#if DEBUG_SMBIOS
791else
792verbose("Found UUID in SMBIOS System Information Table\n");
793#endif
794
795memcpy(uuid, p, UUID_LEN);
796return uuid;
797}
798
799/*
800 * return a binary UUID value from the overriden SystemID and SMUUID if found,
801 * or from the bios if not, or from a fixed value if no bios value is found
802 */
803
804static EFI_CHAR8* getSystemID()
805{
806// unable to determine UUID for host. Error: 35 fix
807// Rek: new SMsystemid option conforming to smbios notation standards, this option should
808// belong to smbios config only ...
809EFI_CHAR8*ret = getUUIDFromString(getStringForKey(kSystemID, &bootInfo->bootConfig));
810
811if (!ret) // try bios dmi info UUID extraction
812ret = getSmbiosUUID();
813
814
815if (!ret) {
816// no bios dmi UUID available, set a fixed value for system-id
817ret=getUUIDFromString((const char*) SYSTEM_ID);
818verbose("Customizing SystemID with : %s\n", getStringFromUUID(ret)); // apply a nice formatting to the displayed output
819}
820else
821{
822const char *mac = getStringFromUUID(ret);
823verbose("MAC address : %c%c:%c%c:%c%c:%c%c:%c%c:%c%c\n",mac[24],mac[25],mac[26],mac[27],mac[28],mac[29]
824,mac[30],mac[31],mac[32],mac[33],mac[34],mac[35]);
825
826}
827
828if (ret)
829memcpy(bootInfo->sysid, ret, UUID_LEN);
830
831return ret;
832}
833
834/*
835 * Must be called AFTER setup Acpi because we need to take care of correct
836 * facp content to reflect in ioregs
837 */
838
839void setupSystemType()
840{
841Node *node = DT__FindNode("/", false);
842if (node == 0) stop("Couldn't get root node");
843// we need to write this property after facp parsing
844// Export system-type only if it has been overrriden by the SystemType option
845DT__AddProperty(node, SYSTEM_TYPE_PROP, sizeof(Platform->Type), &Platform->Type);
846}
847
848struct boot_progress_element {
849unsigned intwidth;
850unsigned intheight;
851intyOffset;
852unsigned intres[5];
853unsigned chardata[0];
854};
855typedef struct boot_progress_element boot_progress_element;
856
857void setupEfiDeviceTree(void)
858{
859EFI_CHAR16* serial = 0, *productname = 0;
860size_t len = 0;
861Node*node;
862extern char gMacOSVersion[];
863node = DT__FindNode("/", false);
864
865if (node == 0) stop("Couldn't get root node");
866
867#include "appleClut8.h"
868long clut = AllocateKernelMemory(sizeof(appleClut8));
869bcopy(&appleClut8, (void*)clut, sizeof(appleClut8));
870AllocateMemoryRange( "BootCLUT", clut, sizeof(appleClut8),-1);
871
872#include "failedboot.h"
873
874long bootPict = AllocateKernelMemory(sizeof(boot_progress_element));
875((boot_progress_element *)bootPict)->width = kFailedBootWidth;
876 ((boot_progress_element *)bootPict)->height = kFailedBootHeight;
877 ((boot_progress_element *)bootPict)->yOffset = kFailedBootOffset;
878
879long bootFail = AllocateKernelMemory(sizeof(gFailedBootPict));
880bcopy(&gFailedBootPict, (void*)bootFail, sizeof(gFailedBootPict));
881 ((boot_progress_element *)bootPict)->data[0] = (uint8_t)bootFail;// ?? please verify
882
883AllocateMemoryRange( "Pict-FailedBoot", bootPict, sizeof(boot_progress_element),-1);
884
885//Fix error message with Lion DP2+ installer
886const char *boardid = getStringForKey("SMboardproduct", &bootInfo->smbiosConfig);
887if (boardid)
888DT__AddProperty(node, "board-id", strlen(boardid)+1, (char*)boardid);
889
890
891Node *chosenNode = DT__FindNode("/chosen", true);
892if (chosenNode) {
893
894DT__AddProperty(chosenNode, "boot-args", strlen(bootArgs->CommandLine)+1, (EFI_CHAR16*)bootArgs->CommandLine);
895
896if (uuidSet &&bootInfo->uuidStr[0])
897DT__AddProperty(chosenNode, kBootUUIDKey, strlen(bootInfo->uuidStr)+1, bootInfo->uuidStr);
898
899/*if (gRootPath[0]) {
900
901DT__AddProperty(chosenNode, "rootpath", 256, gRootPath);
902
903} else */if (gRootDevice) {
904
905DT__AddProperty(chosenNode, "boot-device-path", strlen(gRootDevice)+1, gRootDevice);
906
907}
908
909
910// "boot-file" is not used by kextcache if there is no "boot-device-path" or if there is a valid "rootpath" ,
911// but i let it by default since it may be used by another service
912DT__AddProperty(chosenNode, "boot-file", strlen(bootInfo->bootFile)+1, (EFI_CHAR16*)bootInfo->bootFile);
913
914
915if (bootInfo->adler32)
916DT__AddProperty(chosenNode, "boot-kernelcache-adler32", sizeof(unsigned long), &bootInfo->adler32);
917
918}
919
920// We could also just do DT__FindNode("/efi/platform", true)
921// But I think eventually we want to fill stuff in the efi node
922// too so we might as well create it so we have a pointer for it too.
923node = DT__AddChild(node, "efi");
924// Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
925// is set up. That is, name and table properties
926Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");
927
928Node *kernelCompatibilityNode = 0; // ??? not sure that it should be used like that
929if (gMacOSVersion[3] == '7'){
930kernelCompatibilityNode = DT__AddChild(node, "kernel-compatibility");
931DT__AddProperty(kernelCompatibilityNode, "i386", sizeof(uint32_t), (EFI_UINT32*)&DEVICE_SUPPORTED);
932}
933
934if (archCpuType == CPU_TYPE_I386)
935{
936// The value of the table property is the 32-bit physical address for the RuntimeServices table.
937// Since the EFI system table already has a pointer to it, we simply use the address of that pointer
938// for the pointer to the property data. Warning.. DT finalization calls free on that but we're not
939// the only thing to use a non-malloc'd pointer for something in the DT
940
941DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices);
942DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE);
943}
944else
945{
946if (kernelCompatibilityNode)
947DT__AddProperty(kernelCompatibilityNode, "x86_64", sizeof(uint32_t), (EFI_UINT32*)&DEVICE_SUPPORTED);
948
949DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices);
950DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE);
951}
952DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
953DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);
954
955// Set up the /efi/configuration-table node which will eventually have several child nodes for
956// all of the configuration tables needed by various kernel extensions.
957gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");
958
959// Now fill in the /efi/platform Node
960Node *efiPlatformNode = DT__AddChild(node, "platform");
961
962DT__AddProperty(efiPlatformNode, "DevicePathsSupported", sizeof(uint32_t), (EFI_UINT32*)&DEVICE_SUPPORTED);
963
964// NOTE WELL: If you do add FSB Frequency detection, make sure to store
965// the value in the fsbFrequency global and not an malloc'd pointer
966// because the DT_AddProperty function does not copy its args.
967
968if (Platform->CPU.FSBFrequency != 0)
969DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform->CPU.FSBFrequency);
970
971
972#if UNUSED
973// Export TSC and CPU frequencies for use by the kernel or KEXTs
974if (Platform->CPU.TSCFrequency != 0)
975DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform->CPU.TSCFrequency);
976
977if (Platform->CPU.CPUFrequency != 0)
978DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform->CPU.CPUFrequency);
979#endif
980
981// Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist
982
983if (getSystemID())
984DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) bootInfo->sysid);
985
986 // Export SystemSerialNumber if present
987if ((serial=getSmbiosChar16("SMserial", &len)))
988DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, serial);
989
990// Export Model if present
991if ((productname=getSmbiosChar16("SMproductname", &len)))
992DT__AddProperty(efiPlatformNode, MODEL_PROP, len, productname);
993
994// Fill /efi/device-properties node.
995setupDeviceProperties(node);
996}
997
998/*
999 * Load the smbios.plist override config file if any
1000 */
1001static bool readSmbConfigFile = true;
1002
1003void setupSmbiosConfigFile(const char *filename)
1004{
1005
1006if (readSmbConfigFile == true) {
1007
1008chardirSpecSMBIOS[128] = "";
1009const char *override_pathname = NULL;
1010intlen = 0, err = 0;
1011
1012// Take in account user overriding
1013if (getValueForKey("SMBIOS", &override_pathname, &len, &bootInfo->bootConfig) && len > 0)
1014{
1015// Specify a path to a file, e.g. SMBIOS=/Extra/macProXY.plist
1016sprintf(dirSpecSMBIOS, override_pathname);
1017err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig);
1018}
1019else
1020{
1021// Check selected volume's Extra.
1022sprintf(dirSpecSMBIOS, "/Extra/%s", filename);
1023if (err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig))
1024{
1025// Check booter volume/rdbt Extra.
1026sprintf(dirSpecSMBIOS, "bt(0,0)/Extra/%s", filename);
1027err = loadConfigFile(dirSpecSMBIOS, &bootInfo->smbiosConfig);
1028}
1029}
1030
1031if (err)
1032{
1033verbose("No SMBIOS config file found.\n");
1034}
1035readSmbConfigFile = false;
1036}
1037}
1038
1039static void setup_Smbios()
1040{
1041struct SMBEntryPoint *smbios_o = getSmbiosOriginal();
1042smbios_p = (EFI_PTR32)smbios_o;
1043if (smbios_o != NULL) {
1044execute_hook("smbios_helper", (void *)smbios_o, NULL, NULL, NULL, NULL, NULL);
1045if (execute_hook("getSmbiosPatched",(void *)smbios_o, NULL, NULL, NULL, NULL, NULL) == 0)
1046verbose("Using the original SMBIOS !!\n");
1047}
1048
1049}
1050
1051struct acpi_common_header * get_ACPI_TABLE(const char * table)
1052{
1053int version;
1054struct acpi_common_header *header = NULL;
1055for (version=0; version<2; version++) {
1056struct acpi_2_rsdp *rsdp=(struct acpi_2_rsdp *)(version?((struct acpi_2_rsdp *)(uint32_t)local_acpi20_p):((struct acpi_2_rsdp *)(uint32_t)local_acpi10_p));
1057if (!rsdp)
1058{
1059DBG("No ACPI version %d found. Ignoring\n", version+1);
1060continue;
1061}
1062struct acpi_2_rsdt *rsdt=(struct acpi_2_rsdt *)(rsdp->RsdtAddress);
1063if (rsdt && (uint32_t)rsdt !=0xffffffff && rsdt->Length<0x10000)
1064{
1065int i;
1066int rsdt_entries_num=(rsdt->Length-sizeof(struct acpi_2_rsdt))/4;
1067uint32_t *rsdt_entries=(uint32_t *)(rsdt+1);
1068for (i=0;i<rsdt_entries_num;i++)
1069{
1070header=(struct acpi_common_header *)rsdt_entries[i];
1071if (!header)
1072continue;
1073if (strcmp(header->Signature, table) == 0)
1074{
1075if ((uint32_t)header == 0xffffffff )
1076{
1077printf("ACPI TABLE (%s) incorrect.\n", table);
1078header = NULL;
1079}
1080break;
1081}
1082}
1083}
1084if (version)
1085{
1086struct acpi_2_xsdt *xsdt ;
1087xsdt=(struct acpi_2_xsdt*) ((uint32_t)rsdp->XsdtAddress);
1088if (xsdt && (uint64_t)rsdp->XsdtAddress<0xffffffff && xsdt->Length<0x10000)
1089{
1090int i;
1091int xsdt_entries_num=(xsdt->Length-sizeof(struct acpi_2_xsdt))/8;
1092uint64_t *xsdt_entries=(uint64_t *)(xsdt+1);
1093for (i=0;i<xsdt_entries_num;i++)
1094{
1095header=(struct acpi_common_header *)((uint32_t)(xsdt_entries[i]));
1096if (!header)
1097continue;
1098if (strcmp(header->Signature, table))
1099{
1100header=(struct acpi_common_header *)(uint32_t)xsdt_entries[i];
1101if (!header || (uint64_t)xsdt_entries[i] >= 0xffffffff)
1102{
1103printf("ACPIv2+ TABLE (%s) incorrect.\n", table);
1104header = NULL;
1105}
1106break;
1107}
1108}
1109}
1110}
1111}
1112return header;
1113}
1114
1115static void setup_machine_signature()
1116{
1117Node *chosenNode = DT__FindNode("/chosen", false);
1118if (chosenNode) {
1119if (Platform->hardware_signature == 0xFFFFFFFF)
1120{
1121if (!gFADT)
1122gFADT = (struct acpi_2_fadt *)get_ACPI_TABLE("FACP");
1123
1124struct acpi_2_facs * facs = 0;
1125
1126facs = (struct acpi_2_facs *)(uint32_t)gFADT->X_FIRMWARE_CTRL;
1127
1128if (!facs || strcmp(facs->Signature, "FACS") != 0)
1129facs = (struct acpi_2_facs *)gFADT->FIRMWARE_CTRL;
1130
1131if (!facs || strcmp(facs->Signature, "FACS") != 0)
1132Platform->hardware_signature = 0;
1133else
1134Platform->hardware_signature = facs->hardware_signature;
1135
1136}
1137
1138// Verify that we have a valid hardware signature
1139if (Platform->hardware_signature == 0xFFFFFFFF)
1140{
1141printf("warning hardware_signature is invalid");
1142 Platform->hardware_signature = 0;
1143}
1144
1145DT__AddProperty(chosenNode, "machine-signature", sizeof(uint32_t), &Platform->hardware_signature);
1146}
1147
1148}
1149
1150/*
1151 * Installs all the needed configuration table entries
1152 */
1153
1154static void setupEfiConfigurationTable()
1155{
1156addConfigurationTable(&gEfiSmbiosTableGuid, &smbios_p, NULL);
1157
1158
1159
1160struct mp_t *mps_p = getAddressOfMPSTable() ;
1161uint64_t mps = (uint32_t)mps_p;
1162
1163if (mps_p->config_ptr) {
1164
1165struct imps_cth *local_cth_ptr
1166= (struct imps_cth *)ptov(mps_p->config_ptr);
1167
1168imps_lapic_addr = local_cth_ptr->lapic_addr;
1169
1170} else {
1171imps_lapic_addr = LAPIC_ADDR_DEFAULT;
1172}
1173
1174addConfigurationTable(&gEfiMpsTableGuid, &mps, NULL);
1175
1176
1177//Slice
1178// PM_Model
1179if (platformCPUFeature(CPU_FEATURE_MOBILE)) {
1180Platform->Type = Mobile;
1181} else {
1182Platform->Type = Desktop;
1183}
1184
1185// Invalid the platform hardware signature (this needs to be verified with acpica, but i guess that 0xFFFFFFFF is an invalid signature)
1186Platform->hardware_signature = 0xFFFFFFFF;
1187
1188// Setup ACPI with DSDT overrides (mackerintel's patch)
1189setup_acpi();
1190
1191setup_machine_signature();
1192// We now have to write the systemm-type in ioregs: we cannot do it before in setupDeviceTree()
1193// because we need to take care of facp original content, if it is correct.
1194setupSystemType();
1195
1196// We've obviously changed the count.. so fix up the CRC32
1197if (archCpuType == CPU_TYPE_I386)
1198{
1199gST32->Hdr.CRC32 = 0;
1200gST32->Hdr.CRC32 = crc32(0L, gST32, gST32->Hdr.HeaderSize);
1201}
1202else
1203{
1204gST64->Hdr.CRC32 = 0;
1205gST64->Hdr.CRC32 = crc32(0L, gST64, gST64->Hdr.HeaderSize);
1206}
1207}
1208
1209/*
1210 * Entrypoint from boot.c
1211 */
1212
1213void setupFakeEfi(void)
1214{
1215// Generate efi device strings
1216setup_pci_devs(root_pci_dev);
1217
1218// load smbios.plist file if any
1219setupSmbiosConfigFile("SMBIOS.plist");
1220setup_Smbios();
1221
1222// Initialize the base table
1223if (archCpuType == CPU_TYPE_I386)
1224{
1225setupEfiTables(32);
1226}
1227else
1228{
1229setupEfiTables(64);
1230}
1231
1232// Initialize the device tree
1233setupEfiDeviceTree();
1234
1235// Add configuration table entries to both the services table and the device tree
1236setupEfiConfigurationTable();
1237}
1238
1239

Archive Download this file

Revision: 789