diff --git a/headers/private/kernel/boot/platform/efi/arch_dtb.h b/headers/private/kernel/boot/platform/efi/arch_dtb.h index 2644919772..4a7fc2a52a 100644 --- a/headers/private/kernel/boot/platform/efi/arch_dtb.h +++ b/headers/private/kernel/boot/platform/efi/arch_dtb.h @@ -9,7 +9,7 @@ #include -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); diff --git a/src/system/boot/platform/efi/arch/arm/arch_dtb.cpp b/src/system/boot/platform/efi/arch/arm/arch_dtb.cpp index e4f45c2dc4..b95c34b283 100644 --- a/src/system/boot/platform/efi/arch/arm/arch_dtb.cpp +++ b/src/system/boot/platform/efi/arch/arm/arch_dtb.cpp @@ -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); } } } diff --git a/src/system/boot/platform/efi/arch/riscv64/arch_dtb.cpp b/src/system/boot/platform/efi/arch/riscv64/arch_dtb.cpp index a609625b4a..f34a68db9c 100644 --- a/src/system/boot/platform/efi/arch/riscv64/arch_dtb.cpp +++ b/src/system/boot/platform/efi/arch/riscv64/arch_dtb.cpp @@ -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"); diff --git a/src/system/boot/platform/efi/dtb.cpp b/src/system/boot/platform/efi/dtb.cpp index 60f9e13a68..8e5c610ec1 100644 --- a/src/system/boot/platform/efi/dtb.cpp +++ b/src/system/boot/platform/efi/dtb.cpp @@ -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; } diff --git a/src/system/boot/platform/efi/dtb.h b/src/system/boot/platform/efi/dtb.h index 8257bbc742..b79e265bba 100644 --- a/src/system/boot/platform/efi/dtb.h +++ b/src/system/boot/platform/efi/dtb.h @@ -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);