efi/dtb: Find potential FDT on UEFI

* Makes our UEFI bootloader somewhat FDT/DTB aware on all
  architectures.
* Will report when an FDT is found, and provide it to kernels
  that want it.

Change-Id: I90324fc0579a9c835e60568fa9b654c2df0aba27
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3543
Reviewed-by: Fredrik Holmqvist <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
Alexander von Gluck IV
2020-12-23 13:51:25 +00:00
committed by Alex von Gluck IV
parent a0f0cb5a9d
commit 569564c02d
6 changed files with 99 additions and 0 deletions
@@ -30,6 +30,7 @@ typedef struct {
// needed for UEFI, otherwise kernel acpi support can't find ACPI root
FixedWidthPointer<void> acpi_root;
FixedWidthPointer<void> fdt;
} _PACKED arch_kernel_args;
#endif /* KERNEL_ARCH_ARM_KERNEL_ARGS_H */
@@ -68,6 +68,9 @@
{0xeb9d2d31, 0x2d88, 0x11d3, {0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d}}
#define SMBIOS3_TABLE_GUID \
{0xf2fd1544, 0x9794, 0x4a2c, {0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94}}
#define DEVICE_TREE_GUID \
{0xb1b621d5, 0xf19c, 0x41a5, {0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0}}
typedef struct {
uint64_t Signature;
+1
View File
@@ -23,6 +23,7 @@ local platform_src =
mmu.cpp
heap.cpp
acpi.cpp
dtb.cpp
timer.cpp
menu.cpp
devices.cpp
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright 2019-2020 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Alexander von Gluck IV <[email protected]>
*/
#include <boot/addr_range.h>
#include <boot/platform.h>
#include <boot/stage2.h>
#include <kernel/kernel.h>
#include <ByteOrder.h>
#include "efi_platform.h"
#define INFO(x...) dprintf("efi/fdt: " x)
#define ERROR(x...) dprintf("efi/fdt: " x)
static bool
fdt_valid(void* fdt, uint32* size)
{
if (fdt == NULL)
return false;
uint32* words = (uint32*)fdt;
if (B_BENDIAN_TO_HOST_INT32(words[0]) != 0xd00dfeed)
return false;
*size = B_BENDIAN_TO_HOST_INT32(words[1]);
if (size == 0)
return false;
return true;
}
void
dtb_init()
{
efi_configuration_table *table = kSystemTable->ConfigurationTable;
size_t entries = kSystemTable->NumberOfTableEntries;
INFO("Probing for device trees from UEFI...\n");
// Try to find an FDT
for (uint32 i = 0; i < entries; i++) {
if (!table[i].VendorGuid.equals(DEVICE_TREE_GUID))
continue;
void* dtbPtr = (void*)(table[i].VendorTable);
uint32 fdtSize = 0;
if (!fdt_valid(dtbPtr, &fdtSize)) {
ERROR("Invalid FDT from UEFI table %d\n", i);
break;
}
INFO("Valid FDT from UEFI table %d (%d)\n", i, fdtSize);
// pack into proper location if the architecture cares
#ifdef __ARM__
gKernelArgs.arch_args.fdt = kernel_args_malloc(fdtSize);
if (gKernelArgs.arch_args.fdt != NULL) {
memcpy(gKernelArgs.arch_args.fdt, dtbPtr, fdtSize);
} else
ERROR("unable to malloc for fdt!\n");
#endif
}
}
+20
View File
@@ -0,0 +1,20 @@
/*
* Copyright 2019-2020, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef DTB_H
#define DTB_H
#ifndef _ASSEMBLER
#include "efi_platform.h"
#include <util/FixedWidthPointer.h>
extern void dtb_init();
#endif /* !_ASSEMBLER */
#endif /* DTB_H */
+2
View File
@@ -24,6 +24,7 @@
#include "acpi.h"
#include "console.h"
#include "cpu.h"
#include "dtb.h"
#include "efi_platform.h"
#include "mmu.h"
#include "quirks.h"
@@ -213,6 +214,7 @@ efi_main(efi_handle image, efi_system_table *systemTable)
cpu_init();
acpi_init();
dtb_init();
timer_init();
smp_init();