Unit PlatformRPi4

From Ultibo.org
Revision as of 05:33, 19 June 2021 by Ultibo (Talk | contribs)

Jump to: navigation, search

Return to Unit Reference


Description


Ultibo Platform interface unit for Raspberry Pi 4

Note: The RPi4B has the Activity LED connected to GPIO Pin 42 (Power LED is only accessible via the GPIO expander driver)

Detecting the GIC or legacy interrupt controller

The Raspberry Pi 4 contains a new GIC interrupt controller which includes modern features like the ability to service interrupts on all available cores, a full set of software generated processor to processor interrupts and complete FIQ handling for all interrupt sources.

The Pi 4 also retains and expands the legacy interrupt controller used on earlier Pi models with support for routing interrupts to any core and FIQ handling for all interrupt sources.

The documentation at https://www.raspberrypi.org/documentation/configuration/config-txt/boot.md states that the setting enable_gic=0 or 1 can be used to select between the legacy and GIC interrupt controllers and that the GIC (enable_gic=1) is the default.

Testing however shows this is not completely correct, if no config.txt file exists and no device tree DTB files are present then the current firmware appears to enable the legacy interrupt controller by default.

If device tree DTB files containing a compatible GIC node are available on the SD card during boot the firmware will enable the GIC, this appears to happen regardless of the setting in config.txt and a value of enable_gic=0 will be ignored in favour of the device tree setting.

If the legacy interrupt controller is enabled and Ultibo configures the GIC controller during boot it will receive no interrupts and appear to hang (four color screen).

While it might be possible to read the SD card during boot, check for a config.txt and parse it to determine the value of the enable_gic setting, to be fully functional this process would also need to parse the device tree information (if available) and check for a compatible GIC node. Even then that doesn't account for booting from USB, network or some other source and all of that would have to happen very early in the boot sequence to be usable.

To make matters worse there doesn't appear to be a documented way to detect which interrupt controller is enabled by reading a register value, the GIC even behaves as though it is working when the legacy controller is enabled but no interrupts are received.

To ensure a level of reliability regardless of what firmware and files and configuration settings are present Ultibo implements drivers for both the GIC and legacy interrupt controllers and includes a detection mechanism during early stage boot.

In simple terms the boot process configures the GIC and then installs an interrupt handler for the generic virtual timer and configures the timer to fire in 1ms before enabling interrupts. It then waits 2ms and disables interrupts, unconfigures the timer and deregisters the interrupt handler.

If the test worked the local variable GICAvailable will have been set by the handler to RPI4_GIC_AVAILABLE, if not the variable will remain at RPI4_GIC_UNAVAILABLE and the boot process will proceed to configure the legacy interrupt controller for use.

This is not an ideal mechanism and could potentially fail for other reasons (although it is carefully constructed to avoid many potential failures) but at present is the best option for allowing the boot process to succeed regardless of the firmware behavior.

Constants


To be documented

Type definitions


To be documented

Public variables



RPi4 specific Ultibo variables

RPi4Initialized:Boolean;
RPi4CNTVOFFLow:LongWord = 0; The low 32 bits of the Virtual Counter Offset register at boot time (CPU0 only) (Set by Startup) Must be initialized to remain in .data or else rewritten to zero with .bss
RPi4CNTVOFFHigh:LongWord = 0; The high 32 bits of the Virtual Counter Offset register at boot time (CPU0 only) (Set by Startup) Must be initialized to remain in .data or else rewritten to zero with .bss

Timer register

TimerRegisters:PBCM2838SystemTimerRegisters;

Mailbox register

Mailbox0Registers:PBCM2838Mailbox0Registers;
Mailbox1Registers:PBCM2838Mailbox1Registers;

Interrupt device

GICDevice:PGICDevice;
GICAvailable:LongWord = RPI4_GIC_AVAILABLE; The status of the GIC interrupt controller, determined during boot.

System call

SystemCallEntries:array[0..RPI4_SWI_COUNT - 1] of TSystemCallEntry;

Watchdog register

WatchdogRegisters:PBCM2838PMWatchdogRegisters;

ARM local register

ARMLocalRegisters:PBCM2838ARMLocalRegisters;

Virtual GPIO

VirtualGPIOBuffer:TBCM2838VirtualGPIOBuffer;


Function declarations


To be documented


Return to Unit Reference