Beispiel #1
0
Node *CreateMemoryMapNode(void)
{
    Node *root = DT__RootNode();
    Node *chosen;
    Node *memory_map;

    /* /chosen/memory-map */
    chosen = DT__AddChild(root, "chosen");
    memory_map = DT__AddChild(chosen, "memory-map");

    gChosen = chosen;

    return memory_map;
}
Beispiel #2
0
extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias)
{
    EFI_UINTN i = gST->NumberOfTableEntries;
    /* We only do adds, not modifications and deletes like InstallConfigurationTable */
    if(i >= MAX_CONFIGURATION_TABLE_ENTRIES)
        stop("Ran out of space for configuration tables.  Increase the reserved size in the code.\n");

    if(pGuid == NULL)
        return EFI_INVALID_PARAMETER;

    if(table != NULL)
    {
    	/* FIXME
        ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
        ((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;

        ++gST->NumberOfTableEntries;
		  */
      Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));

      /* Use the pointer to the GUID we just stuffed into the system table */
	  	DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);

      /* The "table" property is the 32-bit (in our implementation) physical address of the table */
  		DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);

      /* Assume the alias pointer is a global or static piece of data */
      if(alias != NULL)
        DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);

      return EFI_SUCCESS;
    }
    return EFI_UNSUPPORTED;
}
Beispiel #3
0
extern EFI_STATUS addConfigurationTable(EFI_GUID const *pGuid, void *table, char const *alias)
{
	EFI_UINTN i = 0;

	//Azi: as is, cpu's with em64t will use EFI64 on pre 10.6 systems,
	// wich seems to cause no problem. In case it does, force i386 arch.
	if (archCpuType == CPU_TYPE_I386)
	{
		i = gST32->NumberOfTableEntries;
	}
	else
	{
		i = gST64->NumberOfTableEntries;
	}

	// We only do adds, not modifications and deletes like InstallConfigurationTable
	if (i >= MAX_CONFIGURATION_TABLE_ENTRIES)
	{
		stop("Ran out of space for configuration tables.  Increase the reserved size in the code.\n");
	}

	if (pGuid == NULL)
	{
		return EFI_INVALID_PARAMETER;
	}

	if (table != NULL)
	{
		// FIXME
		//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorGuid = *pGuid;
		//((EFI_CONFIGURATION_TABLE_64 *)gST->ConfigurationTable)[i].VendorTable = (EFI_PTR64)table;

		//++gST->NumberOfTableEntries;

		Node *tableNode = DT__AddChild(gEfiConfigurationTableNode, mallocStringForGuid(pGuid));

		// Use the pointer to the GUID we just stuffed into the system table
		DT__AddProperty(tableNode, "guid", sizeof(EFI_GUID), (void*)pGuid);

		// The "table" property is the 32-bit (in our implementation) physical address of the table
		DT__AddProperty(tableNode, "table", sizeof(void*) * 2, table);

		// Assume the alias pointer is a global or static piece of data
		if (alias != NULL)
		{
			DT__AddProperty(tableNode, "alias", strlen(alias)+1, (char*)alias);
		}

		return EFI_SUCCESS;
	}
	return EFI_UNSUPPORTED;
}
Beispiel #4
0
void
DT__Initialize(void)
{
    DPRINTF("DT__Initialize\n");
    
    freeNodes = 0;
    allocedNodes = 0;
    freeProperties = 0;
    allocedProperties = 0;
    
    DTInfo.numNodes = 0;
    DTInfo.numProperties = 0;
    DTInfo.totalPropertySize = 0;
    
    rootNode = DT__AddChild(NULL, "/");
    DPRINTF("DT__Initialize done\n");
}
Beispiel #5
0
Node *
DT__FindNode(const char *path, bool createIfMissing)
{
    Node *node, *child;
    DTPropertyNameBuf nameBuf;
    char *bp;
    int i;

    DPRINTF("DT__FindNode('%s', %d)\n", path, createIfMissing);
    
    // Start at root
    node = rootNode;
    DPRINTF("root = 0x%x\n", rootNode);

    while (node) {
        // Skip leading slash
        while (*path == '/') path++;

        for (i=0, bp = nameBuf; ++i < kDTMaxEntryNameLength && *path && *path != '/'; bp++, path++) *bp = *path;
        *bp = '\0';

        if (nameBuf[0] == '\0') {
            // last path entry
            break;
        }
        DPRINTF("Node '%s'\n", nameBuf);

        for (child = node->children; child != 0; child = child->next) {
            DPRINTF("Child 0x%x\n", child);
            if (strcmp(DT__GetName(child), nameBuf) == 0) {
                break;
            }
        }
        if (child == 0 && createIfMissing) {
            DPRINTF("Creating node\n");
            char *str = malloc(strlen(nameBuf) + 1);
            // XXX this will leak
            strcpy(str, nameBuf);

            child = DT__AddChild(node, str);
        }
        node = child;
    }
    return node;
}
Beispiel #6
0
static void WalkDeviceTreeNodeChildren(TagPtr tag, Node * parent)
{
    TagPtr next;

    if (!tag)
        panic("no tag");

    if (!tag->tag)
        panic("no tag");

    if (!(tag->type == kTagTypeArray))
        panic("tag is not array");

    next = tag->tag;

    while (next) {
        Node *new_node;

        new_node = DT__AddChild(parent, NULL);
        PopulateDeviceTreeNode(next, new_node);

        next = next->tagNext;
    }
}
Beispiel #7
0
void setupEfiDeviceTree(void)
{
	EFI_CHAR8*	 ret = 0;
	EFI_CHAR16*	 ret16 = 0;
	size_t		 len = 0;
	Node		*node;
	
	node = DT__FindNode("/", false);

	if (node == 0) stop("Couldn't get root node");

	// We could also just do DT__FindNode("/efi/platform", true)
	// But I think eventually we want to fill stuff in the efi node
	// too so we might as well create it so we have a pointer for it too.
	node = DT__AddChild(node, "efi");

	if (archCpuType == CPU_TYPE_I386)
	{
		DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_32_PROP_VALUE), (char*)FIRMWARE_ABI_32_PROP_VALUE);
	}
	else
	{
		DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_64_PROP_VALUE), (char*)FIRMWARE_ABI_64_PROP_VALUE);
	}
	
	DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
	DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);

	// TODO: Fill in other efi properties if necessary

	// Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
	// is set up.  That is, name and table properties
	Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");

	if (archCpuType == CPU_TYPE_I386)
	{
		// The value of the table property is the 32-bit physical address for the RuntimeServices table.
		// Since the EFI system table already has a pointer to it, we simply use the address of that pointer
		// for the pointer to the property data.  Warning.. DT finalization calls free on that but we're not
		// the only thing to use a non-malloc'd pointer for something in the DT
		
		DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST32->RuntimeServices);
	}
	else
	{
		DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST64->RuntimeServices);
	}

	// Set up the /efi/configuration-table node which will eventually have several child nodes for
	// all of the configuration tables needed by various kernel extensions.
	gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");

	// Now fill in the /efi/platform Node
	Node *efiPlatformNode = DT__AddChild(node, "platform");

	// NOTE WELL: If you do add FSB Frequency detection, make sure to store
	// the value in the fsbFrequency global and not an malloc'd pointer
	// because the DT_AddProperty function does not copy its args.

	if (Platform.CPU.FSBFrequency != 0)
		DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
	
	// Export TSC and CPU frequencies for use by the kernel or KEXTs
	if (Platform.CPU.TSCFrequency != 0)
		DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);

	if (Platform.CPU.CPUFrequency != 0)
		DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);

	// Export system-id. Can be disabled with SystemId=No in com.apple.Boot.plist
	if ((ret=getSystemID()))
		DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, UUID_LEN, (EFI_UINT32*) ret);

	// Export SystemSerialNumber if present
	if ((ret16=getSmbiosChar16("SMserial", &len)))
		DT__AddProperty(efiPlatformNode, SYSTEM_SERIAL_PROP, len, ret16);

	// Export Model if present
	if ((ret16=getSmbiosChar16("SMproductname", &len)))
		DT__AddProperty(efiPlatformNode, MODEL_PROP, len, ret16);

	// Fill /efi/device-properties node.
	setupDeviceProperties(node);
}
Beispiel #8
0
void
setupEfiDeviceTree(void)
{
    Node *node;
    const char * sz_system_id=0;
    EFI_CHAR8* ret=0;
    node = DT__FindNode("/", false);
    if (node == 0) {
        stop("Couldn't get root node");
    }

    /* We could also just do DT__FindNode("/efi/platform", true)
     * But I think eventually we want to fill stuff in the efi node
     * too so we might as well create it so we have a pointer for it too.
    */
    node = DT__AddChild(node, "efi");

    DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
    DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE);
    DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);

    /* TODO: Fill in other efi properties if necessary */

    /* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
     * is set up.  That is, name and table properties */
    Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");

    /* The value of the table property is the 32-bit physical address for the RuntimeServices table.
     * Sice the EFI system table already has a pointer to it, we simply use the address of that pointer
     * for the pointer to the property data.  Warning.. DT finalization calls free on that but we're not
     * the only thing to use a non-malloc'd pointer for something in the DT
     */
    DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices);

    /* Set up the /efi/configuration-table node which will eventually have several child nodes for
     * all of the configuration tables needed by various kernel extensions.
     */
    gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");

    /* Now fill in the /efi/platform Node */
    Node *efiPlatformNode = DT__AddChild(node, "platform");

    /* NOTE WELL: If you do add FSB Frequency detection, make sure to store
     * the value in the fsbFrequency global and not an malloc'd pointer
     * because the DT_AddProperty function does not copy its args.
     */
    if(fsbFrequency != 0)
        DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &fsbFrequency);

    // rek: Give the user a chance to set a fixed/reproduceable system UUID from the bootConfig
    sz_system_id = newStringForKey("SystemID", &bootInfo->bootConfig);
    ret =  getUUIDFromString(sz_system_id); 
    if (sz_system_id)
    {
      if (ret) {
	verbose("Customizing SystemID with : %s\n", sz_system_id);
	DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, sizeof(SYSTEM_ID), (EFI_UINT32*) ret);
      }
      free((void*) sz_system_id);
    }
    else
      // unable to determine UUID for host. Error: 35 fix
      DT__AddProperty(efiPlatformNode, SYSTEM_ID_PROP, sizeof(SYSTEM_ID), (EFI_UINT32*)&SYSTEM_ID);

	/* Export TSC and CPU frequencies for use by the kernel or KEXTs
     */
    if(tscFrequency != 0)
        DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &tscFrequency);
    if(cpuFrequency != 0)
        DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &cpuFrequency);

    /* Fill /efi/device-properties node.
     */
    setupDeviceProperties(node);
}
Beispiel #9
0
static void setupEfiDeviceTree(void)
{
	Node		*node;
	const char	*value;
	int		len;
	bool		doit;

	if ((node = DT__FindNode("/", false)) == NULL) {
		stop("Couldn't find EFI root node");
	}

	/* Export system-type. Allowed values are:
	 * 0x01 for desktop computer (default)
	 * 0x02 for portable computers
	 */
	SystemType[0] = 1;
	if (getValueForKey(kSystemType, &value, &len, &bootInfo->bootConfig) && value != NULL) {
		SystemType[0] = (unsigned char) strtoul(value, NULL, 10);
		if (SystemType[0] != 1 && SystemType[0] != 2) {
			verbose("Error: system-type must be 1 (desktop) or 2 (portable). Defaulting to 1!\n");
			SystemType[0] = 1;
		}
	}
	verbose("Using system-type=0x%02x\n", SystemType[0]);
	DT__AddProperty(node, SystemType_prop, sizeof(SystemType), &SystemType);

	/* We could also just do DT__FindNode("/efi/platform", true)
	 * But I think eventually we want to fill stuff in the efi node
	 * too so we might as well create it so we have a pointer for it too.
	 */
	node = DT__AddChild(node, "efi");

	DT__AddProperty(node, FIRMWARE_REVISION_PROP, sizeof(FIRMWARE_REVISION), (EFI_UINT32*)&FIRMWARE_REVISION);
	DT__AddProperty(node, FIRMWARE_ABI_PROP, sizeof(FIRMWARE_ABI_PROP_VALUE), (char*)FIRMWARE_ABI_PROP_VALUE);
	DT__AddProperty(node, FIRMWARE_VENDOR_PROP, sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*)FIRMWARE_VENDOR);

	/* TODO: Fill in other efi properties if necessary */

	/* Set up the /efi/runtime-services table node similar to the way a child node of configuration-table
	 * is set up.  That is, name and table properties
	 */
	Node *runtimeServicesNode = DT__AddChild(node, "runtime-services");

	/* The value of the table property is the 32-bit physical address for the RuntimeServices table.
	 * Sice the EFI system table already has a pointer to it, we simply use the address of that pointer
	 * for the pointer to the property data.  Warning.. DT finalization calls free on that but we're not
	 * the only thing to use a non-malloc'd pointer for something in the DT
	 */
	DT__AddProperty(runtimeServicesNode, "table", sizeof(uint64_t), &gST->RuntimeServices);

	/* Set up the /efi/configuration-table node which will eventually have several child nodes for
	 * all of the configuration tables needed by various kernel extensions.
	 */
	gEfiConfigurationTableNode = DT__AddChild(node, "configuration-table");

	/* Now fill in the /efi/platform Node */
	Node *efiPlatformNode = DT__AddChild(node, "platform");

	/* NOTE WELL: If you do add FSB Frequency detection, make sure to store
	 * the value in the fsbFrequency global and not an malloc'd pointer
	 * because the DT_AddProperty function does not copy its args.
	 */
	if(Platform.CPU.FSBFrequency != 0) {
		DT__AddProperty(efiPlatformNode, FSB_Frequency_prop, sizeof(uint64_t), &Platform.CPU.FSBFrequency);
	}

	/* Export TSC and CPU frequencies for use by the kernel or KEXTs */
	if(Platform.CPU.TSCFrequency != 0) {
		DT__AddProperty(efiPlatformNode, TSC_Frequency_prop, sizeof(uint64_t), &Platform.CPU.TSCFrequency);
	}
	if(Platform.CPU.CPUFrequency != 0) {
		DT__AddProperty(efiPlatformNode, CPU_Frequency_prop, sizeof(uint64_t), &Platform.CPU.CPUFrequency);
	}

	/* Export system-id. Can be disabled with system-id=No in com.apple.Boot.plist */
	doit = true;
	getBoolForKey(kSystemID, &doit, &bootInfo->bootConfig);
	if (doit) {
		DT__AddProperty(efiPlatformNode, SystemID_prop, sizeof(SystemID), &SystemID);
	}
	/* Export SystemSerialNumber if present */
	if (SystemSerialLength > 0) {
		DT__AddProperty(efiPlatformNode, SystemSerial_prop, SystemSerialLength, &SystemSerial);
	}
	/* Export Model if present */
	if (ModelLength > 0) {
		DT__AddProperty(efiPlatformNode, Model_prop, ModelLength, &Model);
	}

	/* Fill /efi/device-properties node */
	setupDeviceProperties(node);
}
Beispiel #10
0
void initEFITree(void)
{
	_EFI_DEBUG_DUMP("Entering initEFITree(%x)\n", gPlatform.ACPI.Guid.Data1);

	static char ACPI[] = "ACPI";

	// The required information should be added to private_data.h
	static EFI_CHAR16 const MODEL_NAME[]			= STATIC_MODEL_NAME;
	static EFI_CHAR16 const SYSTEM_SERIAL_NUMBER[]	= STATIC_SYSTEM_SERIAL_NUMBER;

	DT__Initialize(); // Add and initialize gPlatform.DT.RootNode

	/*
	 * The root node is available until the call to DT__Finalize, or the first call 
	 * to DT__AddChild with NULL as first argument. Which we don't do and thus we 
	 * can use it in the meantime, instead of defining a local / global variable.
	 */

	DT__AddProperty(gPlatform.DT.RootNode, "model", 5, ACPI);
	DT__AddProperty(gPlatform.DT.RootNode, "compatible", 5, ACPI);
	
	Node * efiNode = DT__AddChild(gPlatform.DT.RootNode, "efi");

	DT__AddProperty(efiNode, "firmware-abi", 6, (gPlatform.ArchCPUType == CPU_TYPE_X86_64) ? "EFI64" : "EFI32");
	DT__AddProperty(efiNode, "firmware-revision", sizeof(FIRMWARE_REVISION), (EFI_UINT32*) &FIRMWARE_REVISION);
	DT__AddProperty(efiNode, "firmware-vendor", sizeof(FIRMWARE_VENDOR), (EFI_CHAR16*) FIRMWARE_VENDOR);

	// Initialize a global var, used by function setupEFITables later on, to
	// add the address to the boot arguments (done to speed up the process).
	gPlatform.EFI.Nodes.RuntimeServices = DT__AddChild(efiNode, "runtime-services");

	// Initialize a global var, used by function addConfigurationTable later on, 
	// to add the SMBIOS and ACPI tables (done to speed up the process).
	gPlatform.EFI.Nodes.ConfigurationTable = DT__AddChild(efiNode, "configuration-table");

	Node * platformNode = DT__AddChild(efiNode, "platform");

	gPlatform.EFI.Nodes.Platform = platformNode;

	// Satisfying AppleACPIPlatform.kext
	static EFI_UINT8 const DEVICE_PATHS_SUPPORTED[] = { 0x01, 0x00, 0x00, 0x00 };

	DT__AddProperty(platformNode, "DevicePathsSupported", sizeof(DEVICE_PATHS_SUPPORTED), (EFI_UINT8*) &DEVICE_PATHS_SUPPORTED);

	// The use of sizeof() here is mandatory (to prevent breakage).
	DT__AddProperty(platformNode, "Model", sizeof(MODEL_NAME), (EFI_CHAR16*) MODEL_NAME);
	DT__AddProperty(platformNode, "SystemSerialNumber", sizeof(SYSTEM_SERIAL_NUMBER), (EFI_CHAR16*) SYSTEM_SERIAL_NUMBER);

	if (gPlatform.CPU.FSBFrequency)
	{
		_EFI_DEBUG_DUMP("Adding FSBFrequency property (%dMHz)\n", (gPlatform.CPU.FSBFrequency / 1000));
		DT__AddProperty(platformNode, "FSBFrequency", sizeof(uint64_t), &gPlatform.CPU.FSBFrequency);
	}

	Node * chosenNode = DT__AddChild(gPlatform.DT.RootNode, "chosen");

	if (chosenNode == 0)
	{
		stop("Couldn't create /chosen node"); // Mimics boot.efi
	}

	gPlatform.EFI.Nodes.MemoryMap = DT__AddChild(chosenNode, "memory-map");

	// Adding the root path for kextcache.
	DT__AddProperty(chosenNode, "boot-device-path", 38, "\\System\\Library\\CoreServices\\boot.efi");

	/* static EFI_UINT8 const BOOT_DEVICE_PATH[] =
	{
		0x02, 0x01, 0x0C, 0x00, 0xD0, 0x41, 0x08, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x00,
		0x02, 0x1F, 0x03, 0x12, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x2A, 0x00,
		0x02, 0x00, 0x00, 0x00, 0x28, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0B, 0x63, 0x34,
		0x00, 0x00, 0x00, 0x00, 0x65, 0x8C, 0x53, 0x3F, 0x1B, 0xCA, 0x83, 0x38, 0xA9, 0xD0, 0xF0, 0x46,
		0x19, 0x14, 0x8E, 0x31, 0x02, 0x02, 0x7F, 0xFF, 0x04, 0x00
	};

	DT__AddProperty(chosenNode, "boot-device-path", sizeof(BOOT_DEVICE_PATH), &BOOT_DEVICE_PATH); */

	// Adding the default kernel name (mach_kernel) for kextcache.
	DT__AddProperty(chosenNode, "boot-file", sizeof(bootInfo->bootFile), bootInfo->bootFile);

#if APPLE_STYLE_EFI

	static EFI_UINT8 const BOOT_FILE_PATH[] =
	{
		0x04, 0x04, 0x50, 0x00, 0x5c, 0x00, 0x53, 0x00, 0x79, 0x00, 0x73, 0x00, 0x74, 0x00, 0x65, 0x00, 
		0x6d, 0x00, 0x5c, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x62, 0x00, 0x72, 0x00, 0x61, 0x00, 0x72, 0x00,
		0x79, 0x00, 0x5c, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, 0x00, 0x53, 0x00, 0x65, 0x00,
		0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x5c, 0x00, 0x62, 0x00, 
		0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 
		0x7f, 0xff, 0x04, 0x00
	};

	DT__AddProperty(chosenNode, "boot-file-path", sizeof(BOOT_FILE_PATH), (EFI_UINT8*) &BOOT_FILE_PATH);

	static EFI_UINT8 const BOOT_ARGS[] = { 0x00 };

	DT__AddProperty(chosenNode, "boot-args", sizeof(BOOT_ARGS), (EFI_UINT8*) &BOOT_ARGS);

	/* Adding kIOHibernateMachineSignatureKey (IOHibernatePrivate.h).
	 *
	 * This 'Hardware Signature' (offset 8 in the FACS table) is calculated by the BIOS on a best effort 
	 * basis to indicate the base hardware configuration of the system such that different base hardware 
	 * configurations  can have different hardware signature values. OSPM uses this information in waking 
	 * from an S4 state, by comparing the current hardware signature to the signature values saved in the 
	 * non-volatile sleep image. If the values are not the same, OSPM assumes that the saved non-volatile 
	 * image is from a different hardware configuration and cannot be restored.
	 */
	
	static EFI_UINT8 const MACHINE_SIGNATURE[] = { 0x00, 0x00, 0x00, 0x00 };

	DT__AddProperty(chosenNode, "machine-signature", sizeof(MACHINE_SIGNATURE), (EFI_UINT8*) &MACHINE_SIGNATURE);

#if ((MAKE_TARGET_OS & LION) == LION)

	// Used by boot.efi - cosmetic only node/properties on hacks.
	Node * kernelCompatNode = DT__AddChild(efiNode, "kernel-compatibility");

	static EFI_UINT8 const COMPAT_MODE[] = { 0x01, 0x00, 0x00, 0x00 };

	DT__AddProperty(kernelCompatNode, "i386", sizeof(COMPAT_MODE), (EFI_UINT8*) &COMPAT_MODE);
	DT__AddProperty(kernelCompatNode, "x86_64", sizeof(COMPAT_MODE), (EFI_UINT8*) &COMPAT_MODE);
#endif

	// Adding the options node breaks AppleEFINVRAM (missing hardware UUID).
	// Node *optionsNode = DT__AddChild(gPlatform.DT.RootNode, "options");
	// DT__AddProperty(optionsNode, "EFICapsuleResult", 4, "STAR"); // 53 54 41 52

#endif

	// DT__AddProperty(chosenNode, "boot-kernelcache-adler32", sizeof(uint64_t), adler32);

	gPlatform.EFI.Nodes.Chosen = chosenNode;

#if INJECT_EFI_DEVICE_PROPERTIES

	static EFI_UINT8 const EFI_DEVICE_PROPERTIES[] = 
	{
		STATIC_EFI_DEVICE_PROPERTIES
	};

	_EFI_DEBUG_DUMP("Injecting EFI device-properties\n");

	DT__AddProperty(efiNode, "device-properties", sizeof(EFI_DEVICE_PROPERTIES), (EFI_CHAR8*) &EFI_DEVICE_PROPERTIES);
#endif

	_EFI_DEBUG_DUMP("Exiting initEFITree()\n");
	_EFI_DEBUG_SLEEP(5);
}