rpi-hal 0.7.0

Hardware abstraction layer for bare-metal Raspberry Pi: BCM2836/BCM2837 (Pi 2, Pi 3), with preliminary BCM2711 (Pi 4) and BCM2835 (Pi 1, Pi Zero) support
Documentation
// AArch64 entry point for the `fault-report` feature: the strong
// `__unhandled_exception` that overrides the weak one in vectors64.s.
//
// Assembly rather than a `#[no_mangle]` Rust function because of the
// stack. There are no banked stacks on this architecture -- an exception
// taken at EL1h keeps using SP_EL1 -- so a handler entered because the
// stack overflowed is a handler whose own first push faults again. That
// second fault is taken with the vectors still installed, so it lands
// back here, and the result is a silent loop at the exact moment the
// report was worth the most.
//
// So `sp` moves to a small dedicated region below before anything else
// happens. The faulting `sp` is captured first and passed on, since it
// is the number that says how far past the end the overflow got.
//
// ELR_EL1/FAR_EL1/ESR_EL1 are read on the Rust side instead: they are
// ordinary system registers that survive a stack switch, and none of
// them is clobbered by anything between here and there.
.section ".text.fault"
.global __unhandled_exception
__unhandled_exception:
    // x0 is already the vector index, set by the stub in vectors64.s.
    mov     x1, sp
    adrp    x2, __rpi_hal_fault_stack_top
    add     x2, x2, #:lo12:__rpi_hal_fault_stack_top
    mov     sp, x2
    // Tail call: nothing here is resumable, and the Rust side never
    // returns.
    b       rpi_hal_fault_report

// The stack the report is built on.
//
// 4 KiB, which is enough for the formatting below it and deliberately
// not enough to hide a problem: nothing here recurses, allocates, or
// calls into a driver beyond writing bytes to a UART.
//
// In .bss rather than .data so it costs nothing in the kernel image --
// an image that on this project is routinely shipped over a 115200 baud
// UART -- and it is never read before it is written.
//
// One region for every core, which is the same trade boot.s makes for
// the AArch32 banked stacks: two cores faulting at once overwrite each
// other's frame. The alternative is a region per core sized at build
// time for a number of cores nothing else here needs to know, to make a
// simultaneous double fault legible. The second report is the one to
// trust.
.section ".bss.fault", "aw", %nobits
.align 4
__rpi_hal_fault_stack:
    .space 4096
__rpi_hal_fault_stack_top: