boot/efi: rework address-cells and size-cells handling

see Devicetree Specification,
section 2.3.5 #address-cells and #size-cells

The #address-cells and #size-cells properties may be used in any
device node that has children in the devicetree hierarchy and
describes how child device nodes should be addressed.

The #address-cells and #size-cells properties are not inherited from
ancestors in the devicetree. They shall be explicitly defined.

If missing, a client program should assume a default value of 2
for #address-cells, and a value of 1 for #size-cells.

Change-Id: Iafed49358540f8ac7aa673c3dc0191c9b580250b
Reviewed-on: https://review.haiku-os.org/c/haiku/+/5144
Tested-by: Commit checker robot <[email protected]>
Reviewed-by: Alex von Gluck IV <[email protected]>
This commit is contained in:
David Karoly
2022-03-24 13:24:22 +00:00
committed by waddlesplash
parent f5ea62c478
commit 9d65dbf1cb
5 changed files with 53 additions and 28 deletions
@@ -9,7 +9,7 @@
#include <SupportDefs.h>
void arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells);
void arch_handle_fdt(const void* fdt, int node);
void arch_dtb_set_kernel_args(void);
@@ -31,7 +31,7 @@ const struct supported_interrupt_controllers {
void
arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
arch_handle_fdt(const void* fdt, int node)
{
const char* deviceType = (const char*)fdt_getprop(fdt, node,
"device_type", NULL);
@@ -66,10 +66,8 @@ arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells
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);
dtb_get_reg(fdt, node, 0, interrupt_controller.regs1);
dtb_get_reg(fdt, node, 1, interrupt_controller.regs2);
}
}
}
@@ -27,7 +27,7 @@ static addr_range sClint = {0};
void
arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
arch_handle_fdt(const void* fdt, int node)
{
const char* deviceType = (const char*)fdt_getprop(fdt, node,
"device_type", NULL);
@@ -73,13 +73,13 @@ arch_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells
return;
if (dtb_has_fdt_string(compatible, compatibleLen, "riscv,clint0")) {
dtb_get_reg(fdt, node, addressCells, sizeCells, 0, sClint);
dtb_get_reg(fdt, node, 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);
dtb_get_reg(fdt, node, 0, sPlic);
int propSize;
if (uint32* prop = (uint32*)fdt_getprop(fdt, node, "interrupts-extended", &propSize)) {
dprintf("PLIC contexts\n");
+45 -18
View File
@@ -291,9 +291,48 @@ dtb_has_fdt_string(const char* prop, int size, const char* pattern)
}
bool
dtb_get_reg(const void* fdt, int node, uint32 addressCells, uint32 sizeCells, size_t idx, addr_range& range)
uint32
dtb_get_address_cells(const void* fdt, int node)
{
uint32 res = 2;
int parent = fdt_parent_offset(fdt, node);
if (parent < 0)
return res;
uint32 *prop = (uint32*)fdt_getprop(sDtbTable, parent, "#address-cells", NULL);
if (prop == NULL)
return res;
res = fdt32_to_cpu(*prop);
return res;
}
uint32
dtb_get_size_cells(const void* fdt, int node)
{
uint32 res = 1;
int parent = fdt_parent_offset(fdt, node);
if (parent < 0)
return res;
uint32 *prop = (uint32*)fdt_getprop(sDtbTable, parent, "#size-cells", NULL);
if (prop == NULL)
return res;
res = fdt32_to_cpu(*prop);
return res;
}
bool
dtb_get_reg(const void* fdt, int node, size_t idx, addr_range& range)
{
uint32 addressCells = dtb_get_address_cells(fdt, node);
uint32 sizeCells = dtb_get_size_cells(fdt, node);
int propSize;
const uint8* prop = (const uint8*)fdt_getprop(fdt, node, "reg", &propSize);
if (prop == NULL)
@@ -400,9 +439,9 @@ dtb_get_clock_frequency(const void* fdt, int node)
static void
dtb_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
dtb_handle_fdt(const void* fdt, int node)
{
arch_handle_fdt(fdt, node, addressCells, sizeCells);
arch_handle_fdt(fdt, node);
int compatibleLen;
const char* compatible = (const char*)fdt_getprop(fdt, node,
@@ -423,7 +462,7 @@ dtb_handle_fdt(const void* fdt, int node, uint32 addressCells, uint32 sizeCells)
memcpy(uart.kind, kSupportedUarts[i].kind,
sizeof(uart.kind));
dtb_get_reg(fdt, node, addressCells, sizeCells, 0, uart.regs);
dtb_get_reg(fdt, node, 0, uart.regs);
uart.irq = dtb_get_interrupt(fdt, node);
uart.clock = dtb_get_clock_frequency(fdt, node);
@@ -472,20 +511,8 @@ dtb_init()
int node = -1;
int depth = -1;
uint32 addressCells = 0;
uint32 sizeCells = 0;
while ((node = fdt_next_node(sDtbTable, node, &depth)) >= 0 && depth >= 0) {
if (addressCells == 0) {
uint32* prop = (uint32*)fdt_getprop(sDtbTable, node, "#address-cells", NULL);
addressCells = fdt32_to_cpu(*prop);
INFO("Address cells at %p: %u\n", prop, addressCells);
}
if (sizeCells == 0) {
uint32* prop = (uint32*)fdt_getprop(sDtbTable, node, "#size-cells", NULL);
sizeCells = fdt32_to_cpu(*prop);
INFO("Size cells at %p: %u\n", prop, sizeCells);
}
dtb_handle_fdt(sDtbTable, node, addressCells, sizeCells);
dtb_handle_fdt(sDtbTable, node);
}
break;
}
+1 -1
View File
@@ -15,7 +15,7 @@
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_get_reg(const void* fdt, int node, size_t idx, addr_range& range);
bool dtb_has_fdt_string(const char* prop, int size, const char* pattern);