Repository navigation
rpi-hal 0.11.0
Added
-
PCIe and NVMe on the Pi 5's external connector. New
pciemodule:
Pcie::init(PCIE1, LinkSpeed, &timer)resets the BCM2712'spcie1
root complex, programs its windows, trains the link and numbers the bus
behind it (the firmware leaves this controller in reset, so no
config.txtline is needed);functions()lists what answered and
enable()assigns a function's memory BARs and turns on decoding and
bus mastering. Newnvmemodule:Nvme::new(&function, &mut Memory, &timer)brings up a controller with one polled I/O queue pair, then
read_blocks/write_blocks/flush/shutdownon namespace 1, any
4-byte-aligned buffer anywhere in RAM moved directly, others through a
bounce page. The MMU now maps the first gigabyte ofpcie1's outbound
window (0x1b_0000_0000), newpac::PCIE1token, and thenvme
example reads, times and round-trips a block on the SSD. With the
resident-fatfeature,NvmeBlockDevicewraps anNvmeas that
crate'sBlockDevice, so a FAT32 volume on the SSD mounts like the SD
card's; drives formatted with 512-byte blocks only, anything else is
nvme::Error::BlockSize. -
ADMA2 for the Pi 5's SD card, off by default.
Sd::set_adma(true)
has the controller moveread_blocks' andwrite_blocks' data over its
own DMA, from a table of 64-bit descriptors, for any 4-byte-aligned
buffer anywhere in RAM (the controller sees RAM at its physical
addresses). Same data both ways insd_speed, reads in every mode and
a 1 MiB write; no faster, since the FIFO already keeps up with the bus,
and about 1% slower at 1 MiB a command for the cache maintenance, hence
off. What it frees is the CPU, for a transfer that doesn't block, which
isn't here yet. NewSd::adma. Internally, the cache-maintenance
helpers now take any address, including above 4 GiB. -
multicoreon the Pi 5.Core1::spawnand its siblings start
cores 1-3 on the BCM2712 through the firmware's PSCICPU_ONcall
(smc), which is how the Pi 5's ARM Trusted Firmware holds them; the
spin-table the other AArch64 boards use does not exist there, and its
address is inside the firmware's own reserved memory.spawnpanics
with the PSCI error code if the firmware refuses. The four multicore
examples build for the Pi 5 unchanged, andmulticore_idruns there. -
pwmon the Pi 5, over RP1's two PWM blocks.Pwm::<PWM0 | PWM1>::init(block, clock_divisor)runs the block from the 50MHz
crystal;channel(&gpio, pin, range)hands back aChannel
implementingembedded_hal::pwm::SetDutyCycle, withset_inverted/
clr_inverted. Pins are the header's GPIO12/13/18/19 (Pwm0Pin) and
the fan connector's GPIO45 (Pwm1Pin).Pwm::<PWM1>::fan_rpmreads the
fan's speed. Newpac::PWM0/PWM1tokens, and thepwm_fanexample,
which steps the fan from off to full and prints its RPM. -
fault-reporton the Pi 5. The handler needed no changes; the
compile_error!is gone, and the report goes out on RP1's UART0 like
any other console write. Thefault_reportexample reads 8 GiB there
to fault (the BCM2712 maps its whole low 4 GiB as RAM, so the other
boards'0xf000_0000is an ordinary read). -
memon the Pi 5.mem::heap_regionandmem::image_endare
built for the BCM2712, where they had been compiled out with the rest
of the not-yet-ported modules though nothing in them is chip-specific.
rpi-kickstart'sheapneeds them, so a Pi 5 board can have a heap
through it.heap_allocbuilds for the Pi 5. -
High-speed SD on the Pi 5. After the 4-bit bus,
Sd::initasks
the card for high speed withCMD6and, if it has it, switches the
card, the host's high-speed bit and the clock from 25 to 50MHz, so a
multi-block read goes from 12.0 to 23.9 MB/s. Best-effort like the
4-bit bus: a card without it, or a failed switch, stays at default
speed. The other chips stay at default speed for now. New
sd::BusMode,Sd::bus_mode, andSd::init_withto cap the mode, and
thesd_speedexample, which reads the same data in every mode and
reports each one's throughput and the cost of a command. -
UHS-I SD on the Pi 5: SDR50 and SDR104.
Sd::initnow asks a
card for 1.8V signalling, switches it (CMD11, Host Control 2's 1.8V
bit and the I/O rail's always-on GPIO line), then switches it to
SDR104 at 200MHz or SDR50 at 100MHz (CMD6) and tunes the sampling
point (CMD19). A multi-block read goes from 23.9 MB/s at high speed to
47.4 (SDR50) and 72.8 (SDR104), every mode reading the same data. A
failed step powers the card off and starts again one mode lower, down
to high speed. NewBusMode::Sdr50andBusMode::Sdr104;initasks
forSdr104. Taking the clock down fully and rewritingSD_PIN_SELon
every clock change, and selecting the delay-line PHY, follow Linux's
sdhci-brcmstbfor this chip. -
All of a Pi 5's RAM. The firmware reports only the first gigabyte
to the ARM, whatever the board's size, and that is allheap_region
covers. Newmem::ram_bytesgives the board's whole RAM from its
revision code, andmem::high_ram_regionthe rest above 1 GiB, with
what lies past 4 GiB mapped first by the new
mmu::map_ram_above_4g(1 GiB blocks, after boot, since the boot-time
map can't know how far the RAM goes). On an 8 GB board that is
0x4000_0000..0x2_0000_0000, 7 GiB on top of the 1014 MiB heap. The
high_ramexample writes all of it with values made from each word's
address and reads them back.mem::ErrorgainsUnknownRam.
Fixed
-
cpu::core_idreturned 0 on every Pi 5 core. The Cortex-A76 puts
the core number inMPIDR's Aff1 field, not Aff0.core_id, the boot
stub's core-0 check and the secondary-core trampoline now read Aff1 on
the BCM2712. -
Nothing on RP1 worked with a Pi 5 bootloader from 2024-10-10 or
later. Those bootloaders start PCIe memory at 2 GiB, which moves
pcie2's window onto RP1 from CPU0x1f_0000_0000to0x1c_0000_0000,
so the first access throughpac::RP1_BASE(the console UART, GPIO,
I2C, PWM) stalled the core with no fault. Newrp1::initmoves the
window back toRP1_BASE, keeping the PCIe address the bootloader
assigned RP1, andrt's boot sequence calls it beforekmain, through
a new per-chiprpi_hal_soc_inithook inboot64.s. A program with its
own boot sequence callsrp1::inititself, before its first RP1 access.