Difference between revisions of "Unit PlatformRPi4"

From Ultibo.org
Jump to: navigation, search
 
(11 intermediate revisions by the same user not shown)
Line 5: Line 5:
 
----
 
----
  
'''Ultibo Platform interface unit for Raspberry Pi 4'''
+
'''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)
 
Note: The RPi4B has the Activity LED connected to GPIO Pin 42 (Power LED is only accessible via the GPIO expander driver)
Line 38: Line 38:
 
----
 
----
  
''To be documented''
+
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi ARM physical to VC IO mapping''' <code> RPI4_VCIO_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_VCIO_ALIAS = BCM2838_VCIO_ALIAS;</code>
 +
| style="width: 50%;"|The VCIO Alias (For ARM Physcial to VC IO translation)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi ARM physical to VC bus mapping''' <code> RPI4_VCBUS_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_VCBUS_ALIAS = BCM2838_VCBUS_C_ALIAS;</code>
 +
| style="width: 50%;"|The currently selected VCBUS Alias (For ARM Physcial to VC Bus translation)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi secure world boot''' <code> RPI4_SECURE_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_SECURE_BOOT = $00000001;</code>
 +
| style="width: 50%;"|If 1 then startup will attempt to switch back to secure world during boot process (Moved to ARMSecureBoot)
 +
|-
 +
| <code>RPI4_SECURE_BOOT_OFFSET = $000000D4;</code>
 +
| The address of the Secure Boot marker in the ARM boot stub
 +
|-
 +
| <code>RPI4_SECURE_BOOT_MARKER = $58495052;</code>
 +
| The Secure Boot marker (ASCII "RPIX")
 +
|-
 +
| <code>RPI4_SECURE_BOOT_CIRCLE = $53514946;</code>
 +
| The alternate Secure Boot marker (ASCII "FIQS") (As used by Circle)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi address of StartupHandler on reset''' <code> RPI4_STARTUP_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_STARTUP_ADDRESS = $00008000;</code>
 +
| style="width: 50%;"|Obtain from linker
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi page directory address and size''' <code> RPI4_PAGE_DIRECTORY_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_PAGE_DIRECTORY_BASE = $00002000;</code>
 +
| style="width: 50%;"|Place the first level Page Directory after the interrupt vectors at 0x00001000 and before the first level Page Table at 0x00004000
 +
|-
 +
| <code>RPI4_PAGE_DIRECTORY_SIZE = SIZE_4K;</code>
 +
| ARM Cortex A72 first level Page Table is up to 4KB in size (512 64 bit (8 byte) entries)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi page table address and size''' <code> RPI4_PAGE_TABLE_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_PAGE_TABLE_BASE = $00004000;</code>
 +
| style="width: 50%;"|Place the second level Page Table after the first level Page Directory at 0x00002000 and before the code start at 0x00008000
 +
|-
 +
| <code>RPI4_PAGE_TABLE_SIZE = SIZE_16K;</code>
 +
| ARM Cortex A72 second level Page Table is exactly 16KB in size (4 x 512 64 bit (8 byte) entries)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi vector table address and size''' <code> RPI4_VECTOR_TABLE_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_VECTOR_TABLE_BASE = $00001000;</code>
 +
| style="width: 50%;"|Place the Interrupt Vector Table at 0x00001000 before the code start at 0x00008000
 +
|-
 +
| <code>RPI4_VECTOR_TABLE_SIZE = SIZE_64;</code>
 +
| The Interrupt Vector Table is exactly 64 bytes (16 32 bit (4 byte) entries)
 +
|-
 +
| <code>RPI4_VECTOR_TABLE_COUNT = 8;</code>
 +
| The Interrupt Vector Table contains 8 entries on an ARMv7 device
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi CPU count''' <code> RPI4_CPU_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_CPU_COUNT = BCM2838_CPU_COUNT;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>RPI4_CPU_BOOT = CPU_ID_0;</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|<code>RPI4_CPU_MASK = CPU_AFFINITY_0 or CPU_AFFINITY_1 or CPU_AFFINITY_2 or CPU_AFFINITY_3;</code>
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi SWI''' <code> RPI4_SWI_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_SWI_COUNT = 256;</code>
 +
| style="width: 50%;"|Number of available SWI entries
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi interrupt''' <code> RPI4_GIC_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_GIC_UNAVAILABLE = 0;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>RPI4_GIC_AVAILABLE = 1;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi core timer''' <code> RPI4_CORE_TIMER_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_CORE_TIMER_PRESCALER = $25ED098;</code>
 +
| style="width: 50%;"|Divide the Crystal Clock by 54 to give a 1MHz Core Timer
 +
|-
 +
| <code>RPI4_CORE_TIMER_FREQUENCY = 1000000;</code>
 +
| The Core Timer frequency from the prescaler setting above
 +
|-
 +
| <code>RPI4_GENERIC_TIMER_FREQUENCY = 1000000;</code>
 +
| The ARM Generic Timer frequency from the prescaler setting above
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>RPI4_CORE_TIMER_PRESCALER = $80000000;</code>
 +
| Divide the Crystal Clock by 1 to give a 54MHz Core Timer
 +
|-
 +
| <code>RPI4_CORE_TIMER_FREQUENCY = 54000000;</code>
 +
| The Core Timer frequency from the prescaler setting above
 +
|-
 +
| <code>RPI4_GENERIC_TIMER_FREQUENCY = 54000000;</code>
 +
| The ARM Generic Timer frequency from the prescaler setting above
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi kernel image name''' <code> RPI4_KERNEL_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_KERNEL_NAME = 'kernel7l.img';</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
| <code>RPI4_KERNEL_NAME = 'kernel8.img';</code>
 +
| &nbsp;
 +
|-
 +
| <code>RPI4_KERNEL_CONFIG = 'config.txt';</code>
 +
| &nbsp;
 +
|-
 +
| <code>RPI4_KERNEL_COMMAND = 'cmdline.txt';</code>
 +
| &nbsp;
 +
|-
 +
|colspan="2"|<code>RPI4_FIRMWARE_FILES = 'start4.elf,fixup4.dat,armstub32-rpi4.bin,armstub64-rpi4.bin';</code>
 +
|-
 +
|colspan="2"|<code>RPI4_DTB_FILES = 'bcm2711-rpi-4-b.dtb,bcm2711-rpi-400.dtb,bcm2711-rpi-cm4.dtb,bcm2711-rpi-cm4s.dtb';</code>
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi GPIO activity LED (GPIO Pin 42)''' <code> RPI4_GPIO_ACTLED_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPFSEL = BCM2838_GPFSEL4;</code>
 +
| style="width: 50%;"|GPFSEL register for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPSET = BCM2838_GPSET1;</code>
 +
| GPSET register for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPCLR = BCM2838_GPCLR1;</code>
 +
| GPCLR register for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPPUD = BCM2838_GPPUD2;</code>
 +
| GPPUD register for ACT LED
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPFSHIFT = 6;</code>
 +
| GPFSEL register shift for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPFMASK = BCM2838_GPFSEL_MASK;</code>
 +
| GPFSEL register mask for ACT LED
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPSHIFT = (42 - 32);</code>
 +
| GPSET/GPCLR register shift for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPMASK = BCM2838_GPSET_MASK;</code>
 +
| GPSET/GPCLR register mask for ACT LED
 +
|-
 +
|colspan="2"|&nbsp;
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPPUDSHIFT = 20;</code>
 +
| GPPUD register shift for ACT LED
 +
|-
 +
| <code>RPI4_GPIO_ACTLED_GPPUDMASK = BCM2838_GPPUD_MASK;</code>
 +
| GPPUD register mask for ACT LED
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi mailbox timeout''' <code> RPI4_MAILBOX_TIMEOUT_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_MAILBOX_TIMEOUT = 100;</code>
 +
| style="width: 50%;"|Default timeout to wait for mailbox calls to complete (Milliseconds)
 +
|-
 +
| <code>RPI4_MAILBOX_TIMEOUT_EX = 1000;</code>
 +
| Extended timeout to wait for mailbox calls to complete (Milliseconds)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi local mailbox''' <code> RPI4_LOCAL_MAILBOX_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_LOCAL_MAILBOX_TIMEOUT = 100;</code>
 +
| style="width: 50%;"|Default timeout to wait for local mailbox calls to complete (Milliseconds)
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 20px; padding-bottom: 15px;">
 +
<div style="font-size: 14px; padding-left: 12px;">'''RPi framebuffer''' <code> RPI4_FRAMEBUFFER_* </code></div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
| <code>RPI4_FRAMEBUFFER_DESCRIPTION = 'BCM2838 Framebuffer';</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
  
 
=== Type definitions ===
 
=== Type definitions ===
 
----
 
----
  
''To be documented''
+
 
 +
'''RPi4 framebuffer'''
 +
 
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial;">
 +
<code>PRPi4Framebuffer = ^TRPi4Framebuffer;</code>
 +
 
 +
<code>TRPi4Framebuffer = record</code>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
|colspan="2"|''Framebuffer Properties''
 +
|-
 +
| <code>Framebuffer:TFramebufferDevice;</code>
 +
| style="width: 50%;"|&nbsp;
 +
|-
 +
|colspan="2"|''RPi4 Properties''
 +
|-
 +
| <code>MultiDisplay:LongBool;</code>
 +
| &nbsp;
 +
|-
 +
| <code>DisplayNum:LongWord;</code>
 +
| &nbsp;
 +
|-
 +
| <code>DisplaySettings:TDisplaySettings;</code>
 +
| &nbsp;
 +
|-
 +
|}
 +
</div></div>
 +
<br />
  
 
=== Public variables ===
 
=== Public variables ===
Line 479: Line 778:
 
| Data = first 28 bits, Channel = last 4 bits
 
| Data = first 28 bits, Channel = last 4 bits
 
Data pointer must be 16 byte aligned to allow for the 4 bit channel number
 
Data pointer must be 16 byte aligned to allow for the 4 bit channel number
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">function RPi4MailboxPropertyTag(Tag:LongWord; Data:Pointer; Size:LongWord):LongWord;</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Request a property tag (Get/Set) from the mailbox property channel</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Data
 +
| Data does not need to include mailbox property channel header or footer. Data pointer does not need any specific alignment or caching attributes.
 +
|-
 +
! Size
 +
| Size must be a multiple of 4 bytes. Size must include the size of the request and response which use the same buffer.
 
|-
 
|-
 
|}
 
|}
Line 509: Line 823:
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<pre style="border: 0; padding-bottom:0px;">function RPi4RequestExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;</pre>
 
<pre style="border: 0; padding-bottom:0px;">function RPi4RequestExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;</pre>
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Request registration of the supplied extended handler to the specified FIQ number/div>
+
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Request registration of the supplied extended handler to the specified FIQ number</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
{| class="wikitable" style="font-size: 14px; background: white;"
 
{| class="wikitable" style="font-size: 14px; background: white;"
Line 822: Line 1,136:
 
<pre style="border: 0; padding-bottom:0px;">function RPi4BoardGetMACAddress:String;</pre>
 
<pre style="border: 0; padding-bottom:0px;">function RPi4BoardGetMACAddress:String;</pre>
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Board MAC Address from the Mailbox property tags channel</div>
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Board MAC Address from the Mailbox property tags channel</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Note
 +
| None documented
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">function RPi4ChipGetRevision:LongWord;</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get the Chip Revision from the revision register</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
{| class="wikitable" style="font-size: 14px; background: white;"
 
{| class="wikitable" style="font-size: 14px; background: white;"
Line 1,506: Line 1,832:
 
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;</pre>
 
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;</pre>
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Palette from the Mailbox property tags channel</div>
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Palette from the Mailbox property tags channel</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Note
 +
| None documented
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferGetLayer(var Layer:LongInt):LongWord;</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Get Framebuffer Layer from the Mailbox property tags channel</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Note
 +
| None documented
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferSetLayer(var Layer:LongInt):LongWord;</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Set Framebuffer Layer from the Mailbox property tags channel</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Note
 +
| None documented
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferTestLayer(var Layer:LongInt):LongWord;</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Test Framebuffer Layer from the Mailbox property tags channel</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
{| class="wikitable" style="font-size: 14px; background: white;"
 
{| class="wikitable" style="font-size: 14px; background: white;"
Line 1,936: Line 2,298:
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;</pre>
 
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;</pre>
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
{| class="wikitable" style="font-size: 14px; background: white;"
 
|-
 
! Note
 
| None documented
 
|-
 
|}
 
</div></div>
 
<br />
 
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 
<pre style="border: 0; padding-bottom:0px;">function RPi4FramebufferDeviceSetProperties(Framebuffer:PFramebufferDevice;Properties:PFramebufferProperties):LongWord;</pre>
 
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div>
 
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' To be documented</div>
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
Line 2,029: Line 2,379:
 
! Note
 
! Note
 
| None documented
 
| None documented
 +
|-
 +
|}
 +
</div></div>
 +
<br />
 +
<div class="toccolours mw-collapsible mw-collapsed" style="border: 1; font-family: arial; padding-top: 0px; padding-bottom: 15px;">
 +
<pre style="border: 0; padding-bottom:0px;">procedure RPi4BootOutput(Value:LongWord);</pre>
 +
<div style="font-size: 14px; padding-left: 12px;">'''Description:''' Output characters to UART0 without dependency on any other RTL setup</div>
 +
<div class="mw-collapsible-content" style="text-align: left; padding-left: 5px;">
 +
{| class="wikitable" style="font-size: 14px; background: white;"
 +
|-
 +
! Note
 +
| This function is primarily intended for testing QEMU boot because it doesn't initialize the UART and won't work on real hardware.
 +
Based on hexstrings() function by dwelch67 (https://github.com/dwelch67)
 
|-
 
|-
 
|}
 
|}

Latest revision as of 05:08, 23 November 2022

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



RPi ARM physical to VC IO mapping RPI4_VCIO_*
RPI4_VCIO_ALIAS = BCM2838_VCIO_ALIAS; The VCIO Alias (For ARM Physcial to VC IO translation)


RPi ARM physical to VC bus mapping RPI4_VCBUS_*
RPI4_VCBUS_ALIAS = BCM2838_VCBUS_C_ALIAS; The currently selected VCBUS Alias (For ARM Physcial to VC Bus translation)


RPi secure world boot RPI4_SECURE_*
RPI4_SECURE_BOOT = $00000001; If 1 then startup will attempt to switch back to secure world during boot process (Moved to ARMSecureBoot)
RPI4_SECURE_BOOT_OFFSET = $000000D4; The address of the Secure Boot marker in the ARM boot stub
RPI4_SECURE_BOOT_MARKER = $58495052; The Secure Boot marker (ASCII "RPIX")
RPI4_SECURE_BOOT_CIRCLE = $53514946; The alternate Secure Boot marker (ASCII "FIQS") (As used by Circle)


RPi address of StartupHandler on reset RPI4_STARTUP_*
RPI4_STARTUP_ADDRESS = $00008000; Obtain from linker


RPi page directory address and size RPI4_PAGE_DIRECTORY_*
RPI4_PAGE_DIRECTORY_BASE = $00002000; Place the first level Page Directory after the interrupt vectors at 0x00001000 and before the first level Page Table at 0x00004000
RPI4_PAGE_DIRECTORY_SIZE = SIZE_4K; ARM Cortex A72 first level Page Table is up to 4KB in size (512 64 bit (8 byte) entries)


RPi page table address and size RPI4_PAGE_TABLE_*
RPI4_PAGE_TABLE_BASE = $00004000; Place the second level Page Table after the first level Page Directory at 0x00002000 and before the code start at 0x00008000
RPI4_PAGE_TABLE_SIZE = SIZE_16K; ARM Cortex A72 second level Page Table is exactly 16KB in size (4 x 512 64 bit (8 byte) entries)


RPi vector table address and size RPI4_VECTOR_TABLE_*
RPI4_VECTOR_TABLE_BASE = $00001000; Place the Interrupt Vector Table at 0x00001000 before the code start at 0x00008000
RPI4_VECTOR_TABLE_SIZE = SIZE_64; The Interrupt Vector Table is exactly 64 bytes (16 32 bit (4 byte) entries)
RPI4_VECTOR_TABLE_COUNT = 8; The Interrupt Vector Table contains 8 entries on an ARMv7 device


RPi CPU count RPI4_CPU_*
RPI4_CPU_COUNT = BCM2838_CPU_COUNT;  
RPI4_CPU_BOOT = CPU_ID_0;  
RPI4_CPU_MASK = CPU_AFFINITY_0 or CPU_AFFINITY_1 or CPU_AFFINITY_2 or CPU_AFFINITY_3;


RPi SWI RPI4_SWI_*
RPI4_SWI_COUNT = 256; Number of available SWI entries


RPi interrupt RPI4_GIC_*
RPI4_GIC_UNAVAILABLE = 0;  
RPI4_GIC_AVAILABLE = 1;  


RPi core timer RPI4_CORE_TIMER_*
RPI4_CORE_TIMER_PRESCALER = $25ED098; Divide the Crystal Clock by 54 to give a 1MHz Core Timer
RPI4_CORE_TIMER_FREQUENCY = 1000000; The Core Timer frequency from the prescaler setting above
RPI4_GENERIC_TIMER_FREQUENCY = 1000000; The ARM Generic Timer frequency from the prescaler setting above
 
RPI4_CORE_TIMER_PRESCALER = $80000000; Divide the Crystal Clock by 1 to give a 54MHz Core Timer
RPI4_CORE_TIMER_FREQUENCY = 54000000; The Core Timer frequency from the prescaler setting above
RPI4_GENERIC_TIMER_FREQUENCY = 54000000; The ARM Generic Timer frequency from the prescaler setting above


RPi kernel image name RPI4_KERNEL_*
RPI4_KERNEL_NAME = 'kernel7l.img';  
RPI4_KERNEL_NAME = 'kernel8.img';  
RPI4_KERNEL_CONFIG = 'config.txt';  
RPI4_KERNEL_COMMAND = 'cmdline.txt';  
RPI4_FIRMWARE_FILES = 'start4.elf,fixup4.dat,armstub32-rpi4.bin,armstub64-rpi4.bin';
RPI4_DTB_FILES = 'bcm2711-rpi-4-b.dtb,bcm2711-rpi-400.dtb,bcm2711-rpi-cm4.dtb,bcm2711-rpi-cm4s.dtb';


RPi GPIO activity LED (GPIO Pin 42) RPI4_GPIO_ACTLED_*
RPI4_GPIO_ACTLED_GPFSEL = BCM2838_GPFSEL4; GPFSEL register for ACT LED
RPI4_GPIO_ACTLED_GPSET = BCM2838_GPSET1; GPSET register for ACT LED
RPI4_GPIO_ACTLED_GPCLR = BCM2838_GPCLR1; GPCLR register for ACT LED
RPI4_GPIO_ACTLED_GPPUD = BCM2838_GPPUD2; GPPUD register for ACT LED
 
RPI4_GPIO_ACTLED_GPFSHIFT = 6; GPFSEL register shift for ACT LED
RPI4_GPIO_ACTLED_GPFMASK = BCM2838_GPFSEL_MASK; GPFSEL register mask for ACT LED
 
RPI4_GPIO_ACTLED_GPSHIFT = (42 - 32); GPSET/GPCLR register shift for ACT LED
RPI4_GPIO_ACTLED_GPMASK = BCM2838_GPSET_MASK; GPSET/GPCLR register mask for ACT LED
 
RPI4_GPIO_ACTLED_GPPUDSHIFT = 20; GPPUD register shift for ACT LED
RPI4_GPIO_ACTLED_GPPUDMASK = BCM2838_GPPUD_MASK; GPPUD register mask for ACT LED


RPi mailbox timeout RPI4_MAILBOX_TIMEOUT_*
RPI4_MAILBOX_TIMEOUT = 100; Default timeout to wait for mailbox calls to complete (Milliseconds)
RPI4_MAILBOX_TIMEOUT_EX = 1000; Extended timeout to wait for mailbox calls to complete (Milliseconds)


RPi local mailbox RPI4_LOCAL_MAILBOX_*
RPI4_LOCAL_MAILBOX_TIMEOUT = 100; Default timeout to wait for local mailbox calls to complete (Milliseconds)


RPi framebuffer RPI4_FRAMEBUFFER_*
RPI4_FRAMEBUFFER_DESCRIPTION = 'BCM2838 Framebuffer';  


Type definitions



RPi4 framebuffer

PRPi4Framebuffer = ^TRPi4Framebuffer;

TRPi4Framebuffer = record

Framebuffer Properties
Framebuffer:TFramebufferDevice;  
RPi4 Properties
MultiDisplay:LongBool;  
DisplayNum:LongWord;  
DisplaySettings:TDisplaySettings;  


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



Initialization functions

procedure RPi4Init;
Description: To be documented
Note None documented


procedure RPi4SecondarySwitch;
Description: Secondary CPU switch from HYP mode handler
Note None documented


procedure RPi4SecondarySecure;
Description: Secondary CPU switch to secure mode handler
Note None documented


procedure RPi4SecondaryHandler;
Description: Secondary CPU startup handler routine
Note None documented


RPi4 platform functions

procedure RPi4SMPInit;
Description: To be documented
Note None documented


procedure RPi4BoardInit;
Description: To be documented
Note None documented


procedure RPi4MemoryInit;
Description: To be documented
Note None documented


procedure RPi4ClockInit;
Description: To be documented
Note None documented


procedure RPi4PowerInit;
Description: To be documented
Note None documented


procedure RPi4MailboxInit;
Description: To be documented
Note None documented


procedure RPi4InterruptInit;
Description: To be documented
Note None documented


procedure RPi4PeripheralInit;
Description: To be documented
Note None documented


procedure RPi4FramebufferInit;
Description: To be documented
Note None documented


procedure RPi4PageTableInit;
Description: Initialize the Hardware Page Tables before enabling the MMU (LPAE version)
Note None documented


procedure RPi4PageTableInitLegacy;
Description: Initialize the Hardware Page Tables before enabling the MMU (Legacy version)
Note None documented


procedure RPi4PowerLEDEnable;
Description: To be documented
Note None documented


procedure RPi4PowerLEDOn;
Description: To be documented
Note None documented


procedure RPi4PowerLEDOff;
Description: To be documented
Note None documented


procedure RPi4ActivityLEDEnable;
Description: To be documented
Note None documented


procedure RPi4ActivityLEDOn;
Description: To be documented
Note None documented


procedure RPi4ActivityLEDOff;
Description: To be documented
Note None documented


function RPi4MailboxReceive(Mailbox,Channel:LongWord):LongWord;
Description: Receive from specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits


procedure RPi4MailboxSend(Mailbox,Channel,Data:LongWord);
Description: Send to specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits


function RPi4MailboxCall(Mailbox,Channel,Data:LongWord; var Response:LongWord):LongWord;
Description: Perform a transaction (Send/Receive) to specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits

Data pointer must be 16 byte aligned to allow for the 4 bit channel number


function RPi4MailboxCallEx(Mailbox,Channel,Data:LongWord; var Response:LongWord; Timeout:LongWord):LongWord;
Description: Perform a transaction (Send/Receive) to specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits

Data pointer must be 16 byte aligned to allow for the 4 bit channel number


function RPi4MailboxPropertyCall(Mailbox,Channel:LongWord; Data:Pointer; var Response:LongWord):LongWord;
Description: Perform a property tag transaction (Send/Receive) to specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits

Data pointer must be 16 byte aligned to allow for the 4 bit channel number


function RPi4MailboxPropertyCallEx(Mailbox,Channel:LongWord; Data:Pointer; var Response:LongWord; Timeout:LongWord):LongWord;
Description: Perform a property tag transaction (Send/Receive) to specified mailbox on specified channel
Note Data = first 28 bits, Channel = last 4 bits

Data pointer must be 16 byte aligned to allow for the 4 bit channel number


function RPi4MailboxPropertyTag(Tag:LongWord; Data:Pointer; Size:LongWord):LongWord;
Description: Request a property tag (Get/Set) from the mailbox property channel
Data Data does not need to include mailbox property channel header or footer. Data pointer does not need any specific alignment or caching attributes.
Size Size must be a multiple of 4 bytes. Size must include the size of the request and response which use the same buffer.


function RPi4RequestExIRQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
Description: Request registration of the supplied extended handler to the specified IRQ number
Note None documented


function RPi4ReleaseExIRQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
Description: Request deregistration of the supplied extended handler from the specified IRQ number
Note None documented


function RPi4RequestExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
Description: Request registration of the supplied extended handler to the specified FIQ number
Note None documented


function RPi4ReleaseExFIQ(CPUID,Number:LongWord; Handler:TInterruptHandler; HandlerEx:TInterruptExHandler; Parameter:Pointer):LongWord;
Description: Request deregistration of the supplied extended handler from the specified FIQ number
Note None documented


function RPi4RequestIPI(CPUID,Number:LongWord; Handler:TIPIHandler; Parameter:Pointer):LongWord;
Description: Request registration of the supplied handler to the specified IPI number
Note None documented


function RPi4ReleaseIPI(CPUID,Number:LongWord; Handler:TIPIHandler; Parameter:Pointer):LongWord;
Description: Request deregistration of the supplied handler from the specified IPI number
Note None documented


function RPi4RegisterInterrupt(Number,Mask,Priority,Flags:LongWord; Handler:TSharedInterruptHandler; Parameter:Pointer):LongWord;
Description: Request registration of the supplied handler to the specified interrupt number (Where Applicable)
Number The interrupt number to register the hanlder for
Mask The mask of CPUs to register the handler for (eg CPU_MASK_0, CPU_MASK_1) (Where Applicable)
Priority The priroty level of the interrupt to be registered (eg INTERRUPT_PRIORITY_MAXIMUM) (Where Applicable)
Flags The flags to control the registration of the interrupt (eg INTERRUPT_FLAG_SHARED) (Where Applicable)
Handler The shared interrupt handler to be called when the interrupt occurs
Parameter A pointer to be passed to the handler when the interrupt occurs (Optional)
Return ERROR_SUCCESS if the callback was scheduled successfully or another error code on failure


function RPi4DeregisterInterrupt(Number,Mask,Priority,Flags:LongWord; Handler:TSharedInterruptHandler; Parameter:Pointer):LongWord;
Description: Request deregistration of the supplied handler from the specified interrupt number (Where Applicable)
Number The interrupt number to deregister the hanlder for
Mask The mask of CPUs to deregister the handler for (eg CPU_MASK_0, CPU_MASK_1) (Where Applicable)
Priority The priroty level of the interrupt to be deregistered (eg INTERRUPT_PRIORITY_MAXIMUM) (Where Applicable)
Flags The flags to control the deregistration of the interrupt (eg INTERRUPT_FLAG_SHARED, INTERRUPT_FLAG_LOCAL, INTERRUPT_FLAG_FIQ) (Where Applicable)
Handler The shared interrupt handler to be called when the interrupt occurs
Parameter A pointer to be passed to the handler when the interrupt occurs (Optional)
Return ERROR_SUCCESS if the callback was scheduled successfully or another error code on failure


function RPi4RegisterSystemCallEx(CPUID,Number:LongWord; Handler:TSystemCallHandler; HandlerEx:TSystemCallExHandler):LongWord;
Description: Request registration of the supplied extended handler to the specified System Call number
CPUID The CPU ID to register the System Call against (or CPU_ID_ALL)
Number The System Call number to be registered
Handler The handler function to be registered
HandlerEx The extended handler function to be registered
Note Only one of Handler or HandlerEx can be specified


function RPi4DeregisterSystemCallEx(CPUID,Number:LongWord; Handler:TSystemCallHandler; HandlerEx:TSystemCallExHandler):LongWord;
Description: Request deregistration of the supplied extended handler from the specified System Call number
CPUID The CPU ID to deregister the System Call from (or CPU_ID_ALL)
Number The System Call number to be deregistered
Handler The handler function to be deregistered
HandlerEx The extended handler function to be deregistered
Note Only one of Handler or HandlerEx can be specified


function RPi4GetInterruptEntry(Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
Description: Get the interrupt entry for the specified interrupt number and instance
Note None documented


function RPi4GetLocalInterruptEntry(CPUID,Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
Description: Get the local interrupt entry for the specified interrupt number and instance
Note None documented


function RPi4GetSoftwareInterruptEntry(CPUID,Number,Instance:LongWord; var Interrupt:TInterruptEntry):LongWord;
Description: Get the software interrupt entry for the specified interrupt number and instance
Note None documented


function RPi4GetSystemCallEntry(Number:LongWord):TSystemCallEntry;
Description: Get the system call entry for the specified system call number
Note None documented


function RPi4SystemRestart(Delay:LongWord):LongWord;
Description: To be documented
Note None documented


function RPi4SystemShutdown(Delay:LongWord):LongWord;
Description: To be documented
Note None documented


function RPi4SystemGetCommandLine:String;
Description: Get the Command Line from the Mailbox property tags channel
Note None documented


function RPi4CPUGetMemory(var Address:PtrUInt; var Length:UInt64):LongWord;
Description: Get the CPU Memory from the Mailbox property tags channel
Note None documented


function RPi4GPUGetState:LongWord;
Description: To be documented
Note None documented


function RPi4GPUGetMemory(var Address:PtrUInt; var Length:UInt64):LongWord;
Description: Get the GPU Memory from the Mailbox property tags channel
Note None documented


function RPi4BoardGetModel:LongWord;
Description: Get the Board Model from the Mailbox property tags channel
Note None documented


function RPi4BoardGetSerial:Int64;
Description: Get the Board Serial from the Mailbox property tags channel
Note None documented


function RPi4BoardGetRevision:LongWord;
Description: Get the Board Revision from the Mailbox property tags channel
Note None documented


function RPi4BoardGetMACAddress:String;
Description: Get the Board MAC Address from the Mailbox property tags channel
Note None documented


function RPi4ChipGetRevision:LongWord;
Description: Get the Chip Revision from the revision register
Note None documented


function RPi4FirmwareGetRevision:LongWord;
Description: Get the Firmware Revision from the Mailbox property tags channel
Note None documented


function RPi4FirmwareGetThrottled:LongWord;
Description: Get the Firmware Throttling state from the Mailbox property tags channel
Note None documented


function RPi4PowerGetWait(PowerId:LongWord):LongWord;
Description: Get the Power Wait from the Mailbox property tags channel
Note None documented


function RPi4PowerGetState(PowerId:LongWord):LongWord;
Description: Get the Power State from the Mailbox property tags channel
Note None documented


function RPi4PowerSetState(PowerId,State:LongWord; Wait:Boolean):LongWord;
Description: Set the Power State in the Mailbox property tags channel
Note Power Lock not required due to Mailbox Property Call serialization


function RPi4ClockGetCount:LongWord;
Description: Gets the current system clock count (32 least significant bits of total)
Note On the Raspberry Pi this comes from the System Timer free running counter which runs at 1MHz and therefore overflows every 4295 seconds


function RPi4ClockGetTotal:Int64;
Description: Gets the total system clock count
Note On the Raspberry Pi this comes from the System Timer free running counter which runs at 1MHz, the clock interrupt also uses this timer to increment the clock every second and therefore keep time.


function RPi4ClockGetRate(ClockId:LongWord):LongWord;
Description: Get the Clock Rate from the Mailbox property tags channel
Note None documented


function RPi4ClockSetRate(ClockId,Rate:LongWord; Turbo:Boolean):LongWord;
Description: Set the Clock Rate in the Mailbox property tags channel
Note None documented


function RPi4ClockGetState(ClockId:LongWord):LongWord;
Description: Get the Clock State from the Mailbox property tags channel
Note None documented


function RPi4ClockSetState(ClockId,State:LongWord):LongWord;
Description: Set the Clock State in the Mailbox property tags channel
Note None documented


function RPi4ClockGetMinRate(ClockId:LongWord):LongWord;
Description: Get the Clock Min Rate from the Mailbox property tags channel
Note None documented


function RPi4ClockGetMaxRate(ClockId:LongWord):LongWord;
Description: Get the Clock Max Rate from the Mailbox property tags channel
Note None documented


function RPi4TurboGetState(TurboId:LongWord):LongWord;
Description: Get the Turbo State from the Mailbox property tags channel
Note None documented


function RPi4TurboSetState(TurboId,State:LongWord):LongWord;
Description: Set the Turbo State in the Mailbox property tags channel
Note None documented


function RPi4VoltageGetValue(VoltageId:LongWord):LongWord;
Description: Get the Voltage Value from the Mailbox property tags channel
Note None documented


function RPi4VoltageSetValue(VoltageId,Value:LongWord):LongWord;
Description: Set the Voltage Value in the Mailbox property tags channel
Note None documented


function RPi4VoltageGetMinValue(VoltageId:LongWord):LongWord;
Description: Get the Voltage Min Value from the Mailbox property tags channel
Note None documented


function RPi4VoltageGetMaxValue(VoltageId:LongWord):LongWord;
Description: Get the Voltage Max Value from the Mailbox property tags channel
Note None documented


function RPi4TemperatureGetCurrent(TemperatureId:LongWord):LongWord;
Description: Get the Temperature Current from the Mailbox property tags channel
Note None documented


function RPi4TemperatureGetMaximum(TemperatureId:LongWord):LongWord;
Description: Get the Temperature Maximum Model from the Mailbox property tags channel
Note None documented


function RPi4GPUMemoryAllocate(Length,Alignment,Flags:LongWord):THandle;
Description: Allocate GPU Memory from the Mailbox property tags channel
Note None documented


function RPi4GPUMemoryRelease(Handle:THandle):LongWord;
Description: Release GPU Memory from the Mailbox property tags channel
Note None documented


function RPi4GPUMemoryLock(Handle:THandle):LongWord;
Description: Lock GPU Memory from the Mailbox property tags channel
Note None documented


function RPi4GPUMemoryUnlock(Handle:THandle):LongWord;
Description: Unlock GPU Memory from the Mailbox property tags channel
Note None documented


function RPi4GPUExecuteCode(Address:Pointer; R0,R1,R2,R3,R4,R5:LongWord):LongWord;
Description: Execute GPU Code from the Mailbox property tags channel
Note None documented


function RPi4DispmanxHandleGet(Resource:THandle):THandle;
Description: Get Dispmanx Memory Handle from the Mailbox property tags channel
Note None documented


function RPi4EDIDBlockGet(Block:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
Description: Get EDID Block from the Mailbox property tags channel
Note None documented


function RPi4FramebufferAllocate(Alignment:LongWord; var Address,Length:LongWord):LongWord;
Description: Allocate Framebuffer from the Mailbox property tags channel
Note None documented


function RPi4FramebufferRelease:LongWord;
Description: Release Framebuffer from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetState(State:LongWord):LongWord;
Description: Set Framebuffer State (Blank Screen) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetDimensions(var Width,Height,Top,Bottom,Left,Right:LongWord):LongWord;
Description: Get Framebuffer Dimensions from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetPhysical(var Width,Height:LongWord):LongWord;
Description: Get Framebuffer Physical size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetPhysical(var Width,Height:LongWord):LongWord;
Description: Set Framebuffer Physical size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestPhysical(var Width,Height:LongWord):LongWord;
Description: Test Framebuffer Physical size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetVirtual(var Width,Height:LongWord):LongWord;
Description: Get Framebuffer Virtual size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetVirtual(var Width,Height:LongWord):LongWord;
Description: Set Framebuffer Virtual size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestVirtual(var Width,Height:LongWord):LongWord;
Description: Test Framebuffer Virtual size from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetDepth(var Depth:LongWord):LongWord;
Description: Get Framebuffer Depth (Bits per pixel) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetDepth(var Depth:LongWord):LongWord;
Description: Set Framebuffer Depth (Bits per pixel) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestDepth(var Depth:LongWord):LongWord;
Description: Test Framebuffer Depth (Bits per pixel) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetPixelOrder(var Order:LongWord):LongWord;
Description: Get Framebuffer Pixel Order (RGB) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetPixelOrder(var Order:LongWord):LongWord;
Description: Set Framebuffer Pixel Order (RGB) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestPixelOrder(var Order:LongWord):LongWord;
Description: Test Framebuffer Pixel Order (RGB) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetAlphaMode(var Mode:LongWord):LongWord;
Description: Get Framebuffer Alpha Mode from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetAlphaMode(var Mode:LongWord):LongWord;
Description: Set Framebuffer Alpha Mode from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestAlphaMode(var Mode:LongWord):LongWord;
Description: Test Framebuffer Alpha Mode from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetPitch:LongWord;
Description: Get Framebuffer Pitch (Bytes per line) from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetOffset(var X,Y:LongWord):LongWord;
Description: Get Framebuffer Virtual Offset from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetOffset(var X,Y:LongWord):LongWord;
Description: Set Framebuffer Virtual Offset from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestOffset(var X,Y:LongWord):LongWord;
Description: Test Framebuffer Virtual Offset from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
Description: Get Framebuffer Overscan from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
Description: Set Framebuffer Overscan from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestOverscan(var Top,Bottom,Left,Right:LongWord):LongWord;
Description: Test Framebuffer Overscan from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetPalette(Buffer:Pointer;Length:LongWord):LongWord;
Description: Get Framebuffer Palette from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
Description: Set Framebuffer Palette from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestPalette(Start,Count:LongWord; Buffer:Pointer; Length:LongWord):LongWord;
Description: Test Framebuffer Palette from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetLayer(var Layer:LongInt):LongWord;
Description: Get Framebuffer Layer from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetLayer(var Layer:LongInt):LongWord;
Description: Set Framebuffer Layer from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestLayer(var Layer:LongInt):LongWord;
Description: Test Framebuffer Layer from the Mailbox property tags channel
Note None documented


function RPi4FramebufferTestVsync:LongWord;
Description: Test Framebuffer Vertical Sync from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetVsync:LongWord;
Description: Set Framebuffer Vertical Sync from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetBacklight(Brightness:LongWord):LongWord;
Description: Set Framebuffer Backlight Brightness from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetNumDisplays(var NumDisplays:LongWord):LongWord;
Description: Get the number of displays from the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetDisplayId(DisplayNum:LongWord):LongWord;
Description: Get the display id for the specified display number from the Mailbox property tags channel
Note None documented


function RPi4FramebufferSetDisplayNum(DisplayNum:LongWord):LongWord;
Description: Get the display number that all framebuffer requests will refer to using the Mailbox property tags channel
Note None documented


function RPi4FramebufferGetDisplaySettings(DisplayNum:LongWord; var DisplaySettings:TDisplaySettings):LongWord;
Description: Get the display settings for the specified display number from the Mailbox property tags channel
Note None documented


function RPi4FramebufferDisplayIdToName(DisplayId:LongWord):String;
Description: Get the name for the specified display id
Note None documented


function RPi4TouchGetBuffer(var Address:PtrUInt):LongWord;
Description: Get the Touchscreen buffer from the Mailbox property tags channel
Note On current firmware versions calling TouchGetBuffer will allocate a buffer from GPU memory and render subsequent calls to TouchSetBuffer ineffective.

After an initial call to TouchSetBuffer calls to TouchGetBuffer will always return the CPU allocated buffer.


function RPi4TouchSetBuffer(Address:PtrUInt):LongWord;
Description: Set the Touchscreen buffer in the Mailbox property tags channel
Note None documented


function RPi4VirtualGPIOGetBuffer(var Address:PtrUInt):LongWord;
Description: Get the Virtual GPIO buffer from the Mailbox property tags channel
Note None documented


function RPi4VirtualGPIOSetBuffer(Address:PtrUInt):LongWord;
Description: Set the Virtual GPIO buffer in the Mailbox property tags channel
Note None documented


function RPi4CursorSetDefault:LongWord;
Description: Set Cursor Default (Pixels) from the Mailbox property tags channel
Note None documented


function RPi4CursorSetInfo(Width,Height,HotspotX,HotspotY:LongWord; Pixels:Pointer; Length:LongWord):LongWord;
Description: Set Cursor Info (Pixels) from the Mailbox property tags channel
Note None documented


function RPi4CursorSetState(Enabled:Boolean; X,Y:LongWord; Relative:Boolean):LongWord;
Description: Set Cursor State (Enable, X, Y) from the Mailbox property tags channel
Relative X, Y is relative to Display (Virtual) not Framebuffer (Physical)


function RPi4DMAGetChannels:LongWord;
Description: Get the available DMA Channels from the Mailbox property tags channel
Note None documented


function RPi4VirtualGPIOInputGet(Pin:LongWord):LongWord;
Description: To be documented
Note None documented


function RPi4VirtualGPIOOutputSet(Pin,Level:LongWord):LongWord;
Description: To be documented
Note None documented


function RPi4VirtualGPIOFunctionSelect(Pin,Mode:LongWord):LongWord;
Description: To be documented
Note None documented


RPi4 thread functions

procedure RPi4SchedulerInit;
Description: Initialize the scheduler interrupt on the boot CPU
Note None documented


procedure RPi4SchedulerStart(CPUID:LongWord);
Description: Initialize the scheduler interrupt on the specified secondary CPU
Note None documented


procedure RPi4SecondaryBoot(CPUID:LongWord);
Description: To be documented
Note None documented


RPi4 SWI functions

function RPi4DispatchSWI(CPUID:LongWord; Thread:TThreadHandle; Request:PSystemCallRequest):TThreadHandle;
Description: Process an SWI request
Note Called by ARMv7/8SoftwareInterruptHandler in PlatformARMv7/8

A DataMemoryBarrier is executed before and after calling this function.


RPi4 clock functions

procedure RPi4ClockInterrupt(Parameter:Pointer);
Description: Interrupt handler function for the clock interrupt
Note This schedules another clock interrupt to occur CLOCK_CYCLES_PER_TICK in the future, then updates ClockTicks and ClockSeconds and checks for timers to trigger.


procedure RPi4ClockUpdate(Cycles:LongWord; var Last:LongWord);
Description: Setup a clock interrupt to trigger after the specified number of clock cycles
Cycles Number of cycles after which the timer interrupt is to be triggered
Note This refers to native clock cycles as specified by CLOCK_FREQUENCY


RPi4 scheduler functions

function RPi4SchedulerInterrupt(CPUID:LongWord; Thread:TThreadHandle; Parameter:Pointer):TThreadHandle;
Description: Interrupt handler function for the scheduler interrupt
Note This schedules another scheduler interrupt to occur SCHEDULER_CLOCKS_PER_INTERRUPT in the future, then checks for threads to wakeup or timeout and the next thread to schedule.


procedure RPi4SchedulerUpdate(Cycles:LongWord; var Last:LongWord);
Description: Setup a scheduler interrupt to trigger after the specified number of clock cycles
Cycles Number of cycles after which the scheduler interrupt is to be triggered
Note This refers to native clock cycles as specified by RPI4_GENERIC_TIMER_FREQUENCY


procedure RPi4SchedulerSystemCall(Request:PSystemCallRequest);
Description: System Call handler for the scheduler
Note This is registered to receive requests for the SYSTEM_CALL_CONTEXT_SWITCH and will perform a context switch from within an SWI


RPi4 framebuffer functions

function RPi4FramebufferDeviceAllocate(Framebuffer:PFramebufferDevice; Properties:PFramebufferProperties):LongWord;
Description: Allocate a framebuffer using the Mailbox Property Tags
Note None documented


function RPi4FramebufferDeviceAllocateAlt(Framebuffer:PFramebufferDevice; Properties:PFramebufferProperties):LongWord;
Description: Allocate a framebuffer using a simple Mailbox Call
Note None documented


function RPi4FramebufferDeviceRelease(Framebuffer:PFramebufferDevice):LongWord;
Description: To be documented
Note None documented


function RPi4FramebufferDeviceBlank(Framebuffer:PFramebufferDevice; Blank:Boolean):LongWord;
Description: To be documented
Note None documented


function RPi4FramebufferDeviceCommit(Framebuffer:PFramebufferDevice; Address:PtrUInt; Size,Flags:LongWord):LongWord;
Description: To be documented
Note None documented


function RPi4FramebufferDeviceSetBacklight(Framebuffer:PFramebufferDevice; Brightness:LongWord):LongWord;
Description: To be documented
Note None documented


RPi4 helper functions

procedure RPi4Wait;
Description: To be documented
Note None documented


procedure RPi4LongWait;
Description: To be documented
Note None documented


procedure RPi4ShortWait;
Description: To be documented
Note None documented


procedure RPi4SlowBlink;
Description: To be documented
Note None documented


procedure RPi4FastBlink;
Description: To be documented
Note None documented


procedure RPi4BootBlink;
Description: Blink the Activity LED without dependency on any other RTL setup
Note None documented


procedure RPi4BootOutput(Value:LongWord);
Description: Output characters to UART0 without dependency on any other RTL setup
Note This function is primarily intended for testing QEMU boot because it doesn't initialize the UART and won't work on real hardware.

Based on hexstrings() function by dwelch67 (https://github.com/dwelch67)


procedure RPi4BootConsoleStart;
Description: To be documented
Note None documented


procedure RPi4BootConsoleWrite(const Value:String);
Description: To be documented
Note None documented


procedure RPi4BootConsoleWriteEx(const Value:String; X,Y:LongWord);
Description: To be documented
Note None documented


function RPi4BootConsoleGetX:LongWord;
Description: To be documented
Note None documented


function RPi4BootConsoleGetY:LongWord;
Description: To be documented
Note None documented


function RPi4ConvertPowerIdRequest(PowerId:LongWord):LongWord;
Description: Convert Ultibo Power Id to BCM2838 Power Id
Note None documented


function RPi4ConvertPowerStateRequest(PowerState:LongWord):LongWord;
Description: Convert Ultibo Power State to BCM2838 Power State
Note None documented


function RPi4ConvertPowerStateResponse(PowerState:LongWord):LongWord;
Description: Convert BCM2838 Power State to Ultibo Power State
Note None documented


function RPi4ConvertClockIdRequest(ClockId:LongWord):LongWord;
Description: Convert Ultibo Clock Id to BCM2838 Clock Id
Note None documented


function RPi4ConvertClockStateRequest(ClockState:LongWord):LongWord;
Description: Convert Ultibo Clock State to BCM2838 Clock State
Note None documented


function RPi4ConvertClockStateResponse(ClockState:LongWord):LongWord;
Description: Convert BCM2838 Clock State to Ultibo Clock State
Note None documented


function RPi4ConvertVoltageIdRequest(VoltageId:LongWord):LongWord;
Description: Convert Ultibo Voltage Id to BCM2838 Voltage Id
Note None documented


function RPi4ConvertTemperatureIdRequest(TemperatureId:LongWord):LongWord;
Description: Convert Ultibo Temperature Id to BCM2838 Temperature Id
Note None documented


Return to Unit Reference