Punch list §25 item 0.3 NOT complete. - Added `starkernel/fdt.h` and `fdt.c` for minimal read-only devicetree parsing: sufficient for boot-time lookups such as `timebase-frequency`. - Bootloader now captures the devicetree blob (DTB) from `EFI_DTB_TABLE_GUID` into `BootInfo::dtb`. - RISC-V timer subsystem now uses the `time` CSR as the primary timestamp source, abandoning the hardcoded `cycle` frequency assumption. - Timer rate is read from `timebase-frequency` in the DTB when accessible; otherwise, a fallback value is used with a RELATIVE trust level. - Integrated the SBI TIME extension for one-shot timer deadlines, ensuring re-arming occurs after each tick to avoid missing heartbeats. Verified: riscv64 builds clean, boots to the ok> prompt with no regression; `riscv64/timer.c` reports accurate frequencies on QEMU's default firmware. Signed-off-by: Robert Allan James <robert.allan.james@gmail.com>
66 lines
2.4 KiB
C
66 lines
2.4 KiB
C
/*
|
||
StarForth — Steady-State Virtual Machine Runtime
|
||
Copyright (c) 2023–2025 Robert A. James. All rights reserved.
|
||
Licensed under the StarForth License, Version 1.0.
|
||
*/
|
||
|
||
/**
|
||
* fdt.h - Minimal flattened-devicetree reader
|
||
*
|
||
* Just enough of the Devicetree Specification v0.4 §5 to pull values out of
|
||
* the blob the UEFI firmware publishes under EFI_DTB_TABLE_GUID. Read-only,
|
||
* no allocation, no tree construction — it walks the structure block each
|
||
* call, which is fine for the handful of boot-time lookups the kernel needs.
|
||
*
|
||
* Deliberately not a general devicetree library. Added for punch-list item
|
||
* 0.3 (riscv64 timebase-frequency); item 0.6 will need node-scoped `reg`
|
||
* lookups for the aarch64 GIC and may extend this.
|
||
*/
|
||
|
||
#ifndef STARKERNEL_FDT_H
|
||
#define STARKERNEL_FDT_H
|
||
|
||
#include <stdint.h>
|
||
|
||
/**
|
||
* @brief Test whether @p fdt points at a valid flattened devicetree.
|
||
*
|
||
* Checks the 0xd00dfeed magic and that the structure and strings blocks lie
|
||
* inside totalsize. Does not validate the token stream.
|
||
*
|
||
* @param fdt Candidate blob; NULL is safe and returns 0.
|
||
* @return 1 if the header is usable, 0 otherwise.
|
||
*/
|
||
int fdt_valid(const void* fdt);
|
||
|
||
/**
|
||
* @brief Find the first property with @p name anywhere in the tree.
|
||
*
|
||
* Scans the structure block in document order and returns the first match
|
||
* regardless of which node it belongs to. That is sufficient for properties
|
||
* which are uniform across a machine (timebase-frequency being the case this
|
||
* was written for) and is *not* sufficient for anything node-scoped.
|
||
*
|
||
* @param fdt Blob, already checked with @c fdt_valid().
|
||
* @param name Property name, NUL-terminated.
|
||
* @param len_out Receives the property length in bytes; may be NULL.
|
||
* @return Pointer to the property value inside @p fdt, or NULL if not found.
|
||
* The value is big-endian as stored in the blob.
|
||
*/
|
||
const void* fdt_find_prop(const void* fdt, const char* name, uint32_t* len_out);
|
||
|
||
/**
|
||
* @brief Read a single-cell (32-bit) property by name.
|
||
*
|
||
* Convenience over @c fdt_find_prop() that also handles the big-endian
|
||
* conversion. Fails if the property is absent or not exactly 4 bytes.
|
||
*
|
||
* @param fdt Blob, already checked with @c fdt_valid().
|
||
* @param name Property name, NUL-terminated.
|
||
* @param out Receives the host-order value on success; untouched on failure.
|
||
* @return 1 on success, 0 on failure.
|
||
*/
|
||
int fdt_prop_u32(const void* fdt, const char* name, uint32_t* out);
|
||
|
||
#endif /* STARKERNEL_FDT_H */
|