Files
LithosAnanake/src/starkernel/arch/aarch64/rpi5_dtb.c
T
Robert Allan JamesandClaude Sonnet 5 ca52ce8243
Build / build-amd64-iso (push) Waiting to run
Build / build-aarch64-iso (push) Waiting to run
Build / build-riscv64-img (push) Waiting to run
rpi5_dtb.c: wire fdt.c's node-scoped lookup into the Pi 5 UART/mailbox addresses
New include/starkernel/rpi5_dtb.h / src/starkernel/arch/aarch64/rpi5_dtb.c:
rpi5_uart_base()/rpi5_mailbox_base(), each finding their peripheral by
compatible string ("arm,pl011" / "brcm,bcm2835-mbox") via fdt_find_node_by_
compatible() then reading its "reg" via fdt_find_prop_in_node().

Found and fixed a real translation gap before it could have silently
produced a wrong address: confirmed directly against bcm2712.dtsi
(raspberrypi/linux) that both peripherals live under one "soc"
simple-bus node whose ranges property adds a fixed 0x10_0000_0000
offset to every child reg value. fdt.c's reader deliberately doesn't
apply ranges translation generally (not a general devicetree
library); this file applies that one, fixed, SoC-wide offset
explicitly, documented with the exact devicetree excerpt that
confirmed it.

Compile-only verification -- no caller wired in yet, these two
functions are what the still-open entry-stub and mailbox-framebuffer-
driver punch-list items will call. Verified 3-arch boot to ok>
(amd64/aarch64/riscv64, each in the foreground; rpi5_dtb.o confirmed
built on aarch64, the only arch that compiles this file).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
2026-09-04 13:36:08 -04:00

94 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
StarForth — Steady-State Virtual Machine Runtime
Copyright (c) 20232025 Robert A. James. All rights reserved.
Licensed under the StarForth License, Version 1.0.
*/
/**
* rpi5_dtb.c - Raspberry Pi 5 (BCM2712) devicetree-based peripheral
* discovery (FABRIC-3.md §IV.3, 2026-09-04).
*
* Confirmed directly against `bcm2712.dtsi` (raspberrypi/linux,
* rpi-6.12.y) before writing this, not assumed:
*
* soc: soc@107c000000 {
* compatible = "simple-bus";
* ranges = <0x0 0x10 0x0 0x80000000>;
* #address-cells = <1>;
* #size-cells = <1>;
* ...
* uart10: serial@7d001000 {
* compatible = "arm,pl011", "arm,primecell";
* reg = <0x7d001000 0x200>;
* };
* mailbox: mailbox@7c013880 {
* compatible = "brcm,bcm2835-mbox";
* reg = <0x7c013880 0x40>;
* };
* };
*
* Every peripheral this file cares about lives under this one "soc"
* node, which applies exactly one translation to every child `reg`
* value: child address 0 maps to parent (CPU-physical) address
* 0x10_0000_0000 (`ranges`'s own `<0x0 0x10 0x0 ...>` — child cell 0,
* parent cells `0x10 0x0`, i.e. `0x10 << 32`). The child side's own
* `#address-cells = <1>` confirms each `reg` value's first cell is the
* whole child address (32-bit, no cell-splitting needed) before adding
* the offset. `fdt.c`'s reader deliberately does not parse `ranges`
* generally (it is "not a general devicetree library," per its own
* header comment) — this one, fixed, SoC-wide offset is applied here
* by name instead, since it is a single known hardware fact, not a
* general mechanism this codebase needs elsewhere yet.
*/
#include "starkernel/rpi5_dtb.h"
#include "starkernel/fdt.h"
/* soc@107c000000's own `ranges` offset -- see this file's own doc
* comment above for where it was confirmed. */
#define BCM2712_SOC_RANGES_OFFSET 0x1000000000ULL
/**
* @brief Read a devicetree `reg` property's first cell as big-endian.
*
* `fdt.c` keeps its own `be32()` helper file-local (freestanding, no
* shared byte-swap utility to reuse) -- duplicated here rather than
* exposing it, same "a few lines is simpler than a new shared
* dependency" precedent `tools/pkcs8_ed25519.c` already set in this
* codebase.
*/
static uint32_t reg_first_cell_be32(const unsigned char* b)
{
return ((uint32_t) b[0] << 24) | ((uint32_t) b[1] << 16) |
((uint32_t) b[2] << 8) | (uint32_t) b[3];
}
/**
* @brief Find @p compatible's node, read its `reg` base address, and
* apply the one fixed BCM2712 `soc`-node translation offset.
*/
static uint64_t rpi5_peripheral_base(const void* dtb, const char* compatible)
{
const void* node;
const void* val;
uint32_t len;
node = fdt_find_node_by_compatible(dtb, compatible);
if (!node) return 0;
val = fdt_find_prop_in_node(dtb, node, "reg", &len);
if (!val || len < 4) return 0;
return BCM2712_SOC_RANGES_OFFSET + reg_first_cell_be32((const unsigned char*) val);
}
uint64_t rpi5_uart_base(const void* dtb)
{
return rpi5_peripheral_base(dtb, "arm,pl011");
}
uint64_t rpi5_mailbox_base(const void* dtb)
{
return rpi5_peripheral_base(dtb, "brcm,bcm2835-mbox");
}