boot/efi: introduce arch_dtb
Change-Id: Iff9e4198aca706097889faf51e9559fe551126ad Reviewed-on: https://review.haiku-os.org/c/haiku/+/4782 Tested-by: Commit checker robot <[email protected]> Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
committed by
Alex von Gluck IV
parent
f4df72a061
commit
023a36024d
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2021 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef KERNEL_BOOT_PLATFORM_EFI_ARCH_DTB_H
|
||||
#define KERNEL_BOOT_PLATFORM_EFI_ARCH_DTB_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
void arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells);
|
||||
void arch_dtb_set_kernel_args(void);
|
||||
|
||||
|
||||
#endif /* KERNEL_BOOT_PLATFORM_EFI_ARCH_DTB_H */
|
||||
@@ -2,6 +2,8 @@ SubDir HAIKU_TOP src system boot platform efi arch arm ;
|
||||
|
||||
SubDirHdrs $(HAIKU_TOP) src system boot platform efi ;
|
||||
|
||||
UseLibraryHeaders [ FDirName libfdt ] ;
|
||||
|
||||
UsePrivateHeaders [ FDirName kernel platform ] ;
|
||||
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
|
||||
|
||||
@@ -19,6 +21,7 @@ for platform in [ MultiBootSubDirSetup efi ] {
|
||||
crt0-efi-$(TARGET_ARCH).S
|
||||
entry.S
|
||||
relocation_func.cpp
|
||||
arch_dtb.cpp
|
||||
arch_mmu.cpp
|
||||
arch_smp.cpp
|
||||
arch_start.cpp
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <[email protected]>
|
||||
*/
|
||||
|
||||
#include <arch_cpu_defs.h>
|
||||
#include <arch_dtb.h>
|
||||
#include <arch_smp.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libfdt.h>
|
||||
}
|
||||
|
||||
#include "dtb.h"
|
||||
|
||||
|
||||
const struct supported_interrupt_controllers {
|
||||
const char* dtb_compat;
|
||||
const char* kind;
|
||||
} kSupportedInterruptControllers[] = {
|
||||
{ "arm,cortex-a9-gic", INTC_KIND_GICV1 },
|
||||
{ "arm,cortex-a15-gic", INTC_KIND_GICV2 },
|
||||
{ "ti,omap3-intc", INTC_KIND_OMAP3 },
|
||||
{ "marvell,pxa-intc", INTC_KIND_PXA },
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
{
|
||||
const char* deviceType = (const char*)fdt_getprop(fdt, node,
|
||||
"device_type", NULL);
|
||||
|
||||
if (deviceType != NULL) {
|
||||
if (strcmp(deviceType, "cpu") == 0) {
|
||||
platform_cpu_info* info;
|
||||
arch_smp_register_cpu(&info);
|
||||
if (info == NULL)
|
||||
return;
|
||||
info->id = fdt32_to_cpu(*(uint32*)fdt_getprop(fdt, node,
|
||||
"reg", NULL));
|
||||
dprintf("cpu\n");
|
||||
dprintf(" id: %" B_PRIu32 "\n", info->id);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int compatibleLen;
|
||||
const char* compatible = (const char*)fdt_getprop(fdt, node,
|
||||
"compatible", &compatibleLen);
|
||||
|
||||
if (compatible == NULL)
|
||||
return;
|
||||
|
||||
intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller;
|
||||
if (interrupt_controller.kind[0] == 0) {
|
||||
for (uint32 i = 0; i < B_COUNT_OF(kSupportedInterruptControllers); i++) {
|
||||
if (dtb_has_fdt_string(compatible, compatibleLen,
|
||||
kSupportedInterruptControllers[i].dtb_compat)) {
|
||||
|
||||
memcpy(interrupt_controller.kind, kSupportedInterruptControllers[i].kind,
|
||||
sizeof(interrupt_controller.kind));
|
||||
|
||||
dtb_get_reg(fdt, node, addressCells, sizeCells, 0,
|
||||
interrupt_controller.regs1);
|
||||
dtb_get_reg(fdt, node, addressCells, sizeCells, 1,
|
||||
interrupt_controller.regs2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_dtb_set_kernel_args(void)
|
||||
{
|
||||
intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller;
|
||||
dprintf("Chosen interrupt controller:\n");
|
||||
if (interrupt_controller.kind[0] == 0) {
|
||||
dprintf("kind: None!\n");
|
||||
} else {
|
||||
dprintf(" kind: %s\n", interrupt_controller.kind);
|
||||
dprintf(" regs: %#" B_PRIx64 ", %#" B_PRIx64 "\n",
|
||||
interrupt_controller.regs1.start,
|
||||
interrupt_controller.regs1.size);
|
||||
dprintf(" %#" B_PRIx64 ", %#" B_PRIx64 "\n",
|
||||
interrupt_controller.regs2.start,
|
||||
interrupt_controller.regs2.size);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ SubDir HAIKU_TOP src system boot platform efi arch riscv64 ;
|
||||
|
||||
SubDirHdrs $(HAIKU_TOP) src system boot platform efi ;
|
||||
|
||||
UseLibraryHeaders [ FDirName libfdt ] ;
|
||||
|
||||
UsePrivateHeaders [ FDirName kernel platform ] ;
|
||||
UsePrivateHeaders [ FDirName kernel boot platform efi ] ;
|
||||
|
||||
@@ -13,9 +15,10 @@ for platform in [ MultiBootSubDirSetup efi ] {
|
||||
crt0-efi-$(TARGET_ARCH).S
|
||||
entry.S
|
||||
relocation_func.cpp
|
||||
arch_start.cpp
|
||||
arch_smp.cpp
|
||||
arch_dtb.cpp
|
||||
arch_mmu.cpp
|
||||
arch_smp.cpp
|
||||
arch_start.cpp
|
||||
arch_timer.cpp
|
||||
arch_traps.cpp
|
||||
arch_traps_asm.S
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2019-2021 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV <[email protected]>
|
||||
*/
|
||||
|
||||
#include <arch_cpu_defs.h>
|
||||
#include <arch_dtb.h>
|
||||
#include <arch_smp.h>
|
||||
#include <boot/platform.h>
|
||||
#include <boot/stage2.h>
|
||||
|
||||
extern "C" {
|
||||
#include <libfdt.h>
|
||||
}
|
||||
|
||||
#include "dtb.h"
|
||||
|
||||
|
||||
uint32 gBootHart = 0;
|
||||
static uint64 sTimerFrequency = 10000000;
|
||||
|
||||
static addr_range sPlic = {0};
|
||||
static addr_range sClint = {0};
|
||||
|
||||
|
||||
void
|
||||
arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
{
|
||||
const char* deviceType = (const char*)fdt_getprop(fdt, node,
|
||||
"device_type", NULL);
|
||||
|
||||
const char* name = fdt_get_name(fdt, node, NULL);
|
||||
if (strcmp(name, "chosen") == 0) {
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "boot-hartid", NULL))
|
||||
gBootHart = fdt32_to_cpu(*prop);
|
||||
} else if (strcmp(name, "cpus") == 0) {
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "timebase-frequency", NULL))
|
||||
sTimerFrequency = fdt32_to_cpu(*prop);
|
||||
}
|
||||
|
||||
if (deviceType != NULL) {
|
||||
if (strcmp(deviceType, "cpu") == 0) {
|
||||
// TODO: improve incompatible CPU detection
|
||||
if (!(fdt_getprop(fdt, node, "mmu-type", NULL) != NULL))
|
||||
return;
|
||||
|
||||
platform_cpu_info* info;
|
||||
arch_smp_register_cpu(&info);
|
||||
if (info == NULL)
|
||||
return;
|
||||
info->id = fdt32_to_cpu(*(uint32*)fdt_getprop(fdt, node,
|
||||
"reg", NULL));
|
||||
dprintf("cpu\n");
|
||||
dprintf(" id: %" B_PRIu32 "\n", info->id);
|
||||
|
||||
int subNode = fdt_subnode_offset(fdt, node, "interrupt-controller");
|
||||
if (subNode < 0) {
|
||||
dprintf(" [!] no interrupt controller\n");
|
||||
} else {
|
||||
info->phandle = fdt_get_phandle(fdt, subNode);
|
||||
dprintf(" phandle: %" B_PRIu32 "\n", info->phandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
int compatibleLen;
|
||||
const char* compatible = (const char*)fdt_getprop(fdt, node,
|
||||
"compatible", &compatibleLen);
|
||||
|
||||
if (compatible == NULL)
|
||||
return;
|
||||
|
||||
if (dtb_has_fdt_string(compatible, compatibleLen, "riscv,clint0")) {
|
||||
dtb_get_reg(fdt, node, addressCells, sizeCells, 0, sClint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dtb_has_fdt_string(compatible, compatibleLen, "riscv,plic0")
|
||||
|| dtb_has_fdt_string(compatible, compatibleLen, "sifive,plic-1.0.0")) {
|
||||
dtb_get_reg(fdt, node, addressCells, sizeCells, 0, sPlic);
|
||||
int propSize;
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "interrupts-extended", &propSize)) {
|
||||
dprintf("PLIC contexts\n");
|
||||
uint32 contextId = 0;
|
||||
for (uint32 *it = prop; (uint8_t*)it - (uint8_t*)prop < propSize; it += 2) {
|
||||
uint32 phandle = fdt32_to_cpu(*it);
|
||||
uint32 interrupt = fdt32_to_cpu(*(it + 1));
|
||||
if (interrupt == sExternInt) {
|
||||
platform_cpu_info* cpuInfo = arch_smp_find_cpu(phandle);
|
||||
dprintf(" context %" B_PRIu32 ": %" B_PRIu32 "\n", contextId, phandle);
|
||||
if (cpuInfo != NULL) {
|
||||
cpuInfo->plicContext = contextId;
|
||||
dprintf(" cpu id: %" B_PRIu32 "\n", cpuInfo->id);
|
||||
}
|
||||
}
|
||||
contextId++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arch_dtb_set_kernel_args(void)
|
||||
{
|
||||
dprintf("bootHart: %" B_PRIu32 "\n", gBootHart);
|
||||
dprintf("timerFrequency: %" B_PRIu64 "\n", sTimerFrequency);
|
||||
gKernelArgs.arch_args.timerFrequency = sTimerFrequency;
|
||||
|
||||
// gKernelArgs.arch_args.htif = {.start = 0x40008000, .size = 0x10};
|
||||
gKernelArgs.arch_args.htif = {.start = 0, .size = 0};
|
||||
gKernelArgs.arch_args.plic = sPlic;
|
||||
gKernelArgs.arch_args.clint = sClint;
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
// TODO: split arch-depending code to per-arch source
|
||||
|
||||
#include <arch_cpu_defs.h>
|
||||
#include <arch_dtb.h>
|
||||
#include <arch_smp.h>
|
||||
#include <arch/generic/debug_uart_8250.h>
|
||||
#if defined(__riscv)
|
||||
@@ -41,14 +42,6 @@ extern "C" {
|
||||
static void* sDtbTable = NULL;
|
||||
static uint32 sDtbSize = 0;
|
||||
|
||||
// TODO: gBootHart is riscy, move
|
||||
uint32 gBootHart = 0;
|
||||
static uint64 sTimerFrequency = 10000000;
|
||||
|
||||
static addr_range sPlic = {0};
|
||||
static addr_range sClint = {0};
|
||||
|
||||
|
||||
static void WriteString(const char *str) {dprintf("%s", str);}
|
||||
static void WriteLn() {dprintf("\n");}
|
||||
static void WriteHex(uint64_t val, int n) {dprintf("%08" B_PRIx64, val);}
|
||||
@@ -77,19 +70,6 @@ const struct supported_uarts {
|
||||
};
|
||||
|
||||
|
||||
#ifdef __ARM__
|
||||
const struct supported_interrupt_controllers {
|
||||
const char* dtb_compat;
|
||||
const char* kind;
|
||||
} kSupportedInterruptControllers[] = {
|
||||
{ "arm,cortex-a9-gic", INTC_KIND_GICV1 },
|
||||
{ "arm,cortex-a15-gic", INTC_KIND_GICV2 },
|
||||
{ "ti,omap3-intc", INTC_KIND_OMAP3 },
|
||||
{ "marvell,pxa-intc", INTC_KIND_PXA },
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static void WriteStringList(const char* prop, size_t size)
|
||||
{
|
||||
bool first = true;
|
||||
@@ -295,8 +275,8 @@ static void DumpFdt(const void *fdt)
|
||||
|
||||
|
||||
|
||||
static bool
|
||||
HasFdtString(const char* prop, int size, const char* pattern)
|
||||
bool
|
||||
dtb_has_fdt_string(const char* prop, int size, const char* pattern)
|
||||
{
|
||||
int patternLen = strlen(pattern);
|
||||
const char* propEnd = prop + size;
|
||||
@@ -310,8 +290,8 @@ HasFdtString(const char* prop, int size, const char* pattern)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
GetReg(const void* fdt, int node, uint32 addressCells, uint32 sizeCells, size_t idx, addr_range& range)
|
||||
bool
|
||||
dtb_get_reg(const void* fdt, int node, uint32 addressCells, uint32 sizeCells, size_t idx, addr_range& range)
|
||||
{
|
||||
int propSize;
|
||||
const uint8* prop = (const uint8*)fdt_getprop(fdt, node, "reg", &propSize);
|
||||
@@ -339,7 +319,7 @@ GetReg(const void* fdt, int node, uint32 addressCells, uint32 sizeCells, size_t
|
||||
|
||||
|
||||
static uint32
|
||||
GetInterruptParent(const void* fdt, int node)
|
||||
dtb_get_interrupt_parent(const void* fdt, int node)
|
||||
{
|
||||
while (node >= 0) {
|
||||
uint32* prop;
|
||||
@@ -357,9 +337,9 @@ GetInterruptParent(const void* fdt, int node)
|
||||
|
||||
|
||||
static uint32
|
||||
GetInterruptCells(const void* fdt, int node)
|
||||
dtb_get_interrupt_cells(const void* fdt, int node)
|
||||
{
|
||||
uint32 intc_node = GetInterruptParent(fdt, node);
|
||||
uint32 intc_node = dtb_get_interrupt_parent(fdt, node);
|
||||
if (intc_node > 0) {
|
||||
uint32* prop = (uint32*)fdt_getprop(fdt, intc_node, "#interrupt-cells", NULL);
|
||||
if (prop != NULL) {
|
||||
@@ -372,9 +352,9 @@ GetInterruptCells(const void* fdt, int node)
|
||||
|
||||
|
||||
static uint32
|
||||
GetInterrupt(const void* fdt, int node)
|
||||
dtb_get_interrupt(const void* fdt, int node)
|
||||
{
|
||||
uint32 interruptCells = GetInterruptCells(fdt, node);
|
||||
uint32 interruptCells = dtb_get_interrupt_cells(fdt, node);
|
||||
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "interrupts-extended", NULL)) {
|
||||
return fdt32_to_cpu(*(prop + 1));
|
||||
@@ -392,7 +372,7 @@ GetInterrupt(const void* fdt, int node)
|
||||
|
||||
|
||||
static int64
|
||||
GetClockFrequency(const void* fdt, int node)
|
||||
dtb_get_clock_frequency(const void* fdt, int node)
|
||||
{
|
||||
uint32* prop;
|
||||
int len = 0;
|
||||
@@ -419,43 +399,9 @@ GetClockFrequency(const void* fdt, int node)
|
||||
|
||||
|
||||
static void
|
||||
HandleFdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
dtb_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
{
|
||||
const char* name = fdt_get_name(fdt, node, NULL);
|
||||
if (strcmp(name, "chosen") == 0) {
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "boot-hartid", NULL))
|
||||
gBootHart = fdt32_to_cpu(*prop);
|
||||
} else if (strcmp(name, "cpus") == 0) {
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "timebase-frequency", NULL))
|
||||
sTimerFrequency = fdt32_to_cpu(*prop);
|
||||
}
|
||||
|
||||
const char* deviceType = (const char*)fdt_getprop(fdt, node,
|
||||
"device_type", NULL);
|
||||
|
||||
if (deviceType != NULL) {
|
||||
if (strcmp(deviceType, "cpu") == 0) {
|
||||
// TODO: improve incompatible CPU detection
|
||||
if (!(fdt_getprop(fdt, node, "mmu-type", NULL) != NULL))
|
||||
return;
|
||||
platform_cpu_info* info;
|
||||
arch_smp_register_cpu(&info);
|
||||
if (info == NULL)
|
||||
return;
|
||||
info->id = fdt32_to_cpu(*(uint32*)fdt_getprop(fdt, node,
|
||||
"reg", NULL));
|
||||
dprintf("cpu\n");
|
||||
dprintf(" id: %" B_PRIu32 "\n", info->id);
|
||||
|
||||
int subNode = fdt_subnode_offset(fdt, node, "interrupt-controller");
|
||||
if (subNode < 0) {
|
||||
dprintf(" [!] no interrupt controller\n");
|
||||
} else {
|
||||
info->phandle = fdt_get_phandle(fdt, subNode);
|
||||
dprintf(" phandle: %" B_PRIu32 "\n", info->phandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
arch_handle_fdt(fdt, node, addressCells, sizeCells);
|
||||
|
||||
int compatibleLen;
|
||||
const char* compatible = (const char*)fdt_getprop(fdt, node,
|
||||
@@ -464,50 +410,21 @@ HandleFdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
if (compatible == NULL)
|
||||
return;
|
||||
|
||||
if (HasFdtString(compatible, compatibleLen, "riscv,clint0")) {
|
||||
GetReg(fdt, node, addressCells, sizeCells, 0, sClint);
|
||||
return;
|
||||
}
|
||||
|
||||
if (HasFdtString(compatible, compatibleLen, "riscv,plic0")
|
||||
|| HasFdtString(compatible, compatibleLen, "sifive,plic-1.0.0")) {
|
||||
GetReg(fdt, node, addressCells, sizeCells, 0, sPlic);
|
||||
int propSize;
|
||||
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "interrupts-extended", &propSize)) {
|
||||
dprintf("PLIC contexts\n");
|
||||
uint32 contextId = 0;
|
||||
for (uint32 *it = prop; (uint8_t*)it - (uint8_t*)prop < propSize; it += 2) {
|
||||
uint32 phandle = fdt32_to_cpu(*it);
|
||||
uint32 interrupt = fdt32_to_cpu(*(it + 1));
|
||||
if (interrupt == sExternInt) {
|
||||
platform_cpu_info* cpuInfo = arch_smp_find_cpu(phandle);
|
||||
dprintf(" context %" B_PRIu32 ": %" B_PRIu32 "\n", contextId, phandle);
|
||||
if (cpuInfo != NULL) {
|
||||
cpuInfo->plicContext = contextId;
|
||||
dprintf(" cpu id: %" B_PRIu32 "\n", cpuInfo->id);
|
||||
}
|
||||
}
|
||||
contextId++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: We should check for the "chosen" uart and prioritize that one
|
||||
|
||||
// check for a uart if we don't have one
|
||||
uart_info &uart = gKernelArgs.arch_args.uart;
|
||||
if (uart.kind[0] == 0) {
|
||||
for (uint32 i = 0; i < B_COUNT_OF(kSupportedUarts); i++) {
|
||||
if (HasFdtString(compatible, compatibleLen,
|
||||
if (dtb_has_fdt_string(compatible, compatibleLen,
|
||||
kSupportedUarts[i].dtb_compat)) {
|
||||
|
||||
memcpy(uart.kind, kSupportedUarts[i].kind,
|
||||
sizeof(uart.kind));
|
||||
|
||||
GetReg(fdt, node, addressCells, sizeCells, 0, uart.regs);
|
||||
uart.irq = GetInterrupt(fdt, node);
|
||||
uart.clock = GetClockFrequency(fdt, node);
|
||||
dtb_get_reg(fdt, node, addressCells, sizeCells, 0, uart.regs);
|
||||
uart.irq = dtb_get_interrupt(fdt, node);
|
||||
uart.clock = dtb_get_clock_frequency(fdt, node);
|
||||
|
||||
gUART = kSupportedUarts[i].uart_driver_init(uart.regs.start,
|
||||
uart.clock);
|
||||
@@ -517,25 +434,6 @@ HandleFdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
|
||||
if (gUART != NULL)
|
||||
gUART->InitEarly();
|
||||
}
|
||||
|
||||
#if defined(__ARM__)
|
||||
intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller;
|
||||
if (interrupt_controller.kind[0] == 0) {
|
||||
for (uint32 i = 0; i < B_COUNT_OF(kSupportedInterruptControllers); i++) {
|
||||
if (HasFdtString(compatible, compatibleLen,
|
||||
kSupportedInterruptControllers[i].dtb_compat)) {
|
||||
|
||||
memcpy(interrupt_controller.kind, kSupportedInterruptControllers[i].kind,
|
||||
sizeof(interrupt_controller.kind));
|
||||
|
||||
GetReg(fdt, node, addressCells, sizeCells, 0,
|
||||
interrupt_controller.regs1);
|
||||
GetReg(fdt, node, addressCells, sizeCells, 1,
|
||||
interrupt_controller.regs2);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -574,7 +472,7 @@ dtb_init()
|
||||
int node = -1;
|
||||
int depth = -1;
|
||||
while ((node = fdt_next_node(sDtbTable, node, &depth)) >= 0 && depth >= 0) {
|
||||
HandleFdt(sDtbTable, node, 2, 2);
|
||||
dtb_handle_fdt(sDtbTable, node, 2, 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -586,7 +484,6 @@ dtb_set_kernel_args()
|
||||
{
|
||||
// pack into proper location if the architecture cares
|
||||
if (sDtbTable != NULL) {
|
||||
#if defined(__ARM__) || defined(__riscv)
|
||||
// libfdt requires 8-byte alignment
|
||||
gKernelArgs.arch_args.fdt = (void*)(addr_t)kernel_args_malloc(sDtbSize, 8);
|
||||
|
||||
@@ -594,20 +491,8 @@ dtb_set_kernel_args()
|
||||
memcpy(gKernelArgs.arch_args.fdt, sDtbTable, sDtbSize);
|
||||
else
|
||||
ERROR("unable to malloc for fdt!\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __riscv
|
||||
dprintf("bootHart: %" B_PRIu32 "\n", gBootHart);
|
||||
dprintf("timerFrequency: %" B_PRIu64 "\n", sTimerFrequency);
|
||||
gKernelArgs.arch_args.timerFrequency = sTimerFrequency;
|
||||
|
||||
// gKernelArgs.arch_args.htif = {.start = 0x40008000, .size = 0x10};
|
||||
gKernelArgs.arch_args.htif = {.start = 0, .size = 0};
|
||||
gKernelArgs.arch_args.plic = sPlic;
|
||||
gKernelArgs.arch_args.clint = sClint;
|
||||
#endif
|
||||
#if defined(__ARM__) || defined(__riscv)
|
||||
uart_info &uart = gKernelArgs.arch_args.uart;
|
||||
dprintf("Chosen UART:\n");
|
||||
if (uart.kind[0] == 0) {
|
||||
@@ -619,20 +504,6 @@ dtb_set_kernel_args()
|
||||
dprintf(" irq: %" B_PRIu32 "\n", uart.irq);
|
||||
dprintf(" clock: %" B_PRIu64 "\n", uart.clock);
|
||||
}
|
||||
#endif
|
||||
#if defined(__ARM__)
|
||||
intc_info &interrupt_controller = gKernelArgs.arch_args.interrupt_controller;
|
||||
dprintf("Chosen interrupt controller:\n");
|
||||
if (interrupt_controller.kind[0] == 0) {
|
||||
dprintf("kind: None!\n");
|
||||
} else {
|
||||
dprintf(" kind: %s\n", interrupt_controller.kind);
|
||||
dprintf(" regs: %#" B_PRIx64 ", %#" B_PRIx64 "\n",
|
||||
interrupt_controller.regs1.start,
|
||||
interrupt_controller.regs1.size);
|
||||
dprintf(" %#" B_PRIx64 ", %#" B_PRIx64 "\n",
|
||||
interrupt_controller.regs2.start,
|
||||
interrupt_controller.regs2.size);
|
||||
}
|
||||
#endif
|
||||
|
||||
arch_dtb_set_kernel_args();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
extern void dtb_init();
|
||||
extern void dtb_set_kernel_args();
|
||||
|
||||
bool dtb_get_reg(const void* fdt, int node, uint32 addressCells, uint32 sizeCells, size_t idx, addr_range& range);
|
||||
bool dtb_has_fdt_string(const char* prop, int size, const char* pattern);
|
||||
|
||||
|
||||
#endif /* !_ASSEMBLER */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user