From: Frederik van Hövell <[email protected]>
Signed-off-by: Frederik van Hövell <[email protected]>
---
docs/system/arm/raspi.rst | 12 ++++++++++++
hw/arm/raspi.c | 17 +++++++++++------
tests/functional/aarch64/test_raspi3.py | 12 ++++++++++++
3 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/docs/system/arm/raspi.rst b/docs/system/arm/raspi.rst
index 44eec3f1c33..fb912da129b 100644
--- a/docs/system/arm/raspi.rst
+++ b/docs/system/arm/raspi.rst
@@ -43,3 +43,15 @@ Missing devices
* Pulse Width Modulation (PWM)
* PCIE Root Port (raspi4b)
* GENET Ethernet Controller (raspi4b)
+
+Boot options
+------------
+
+The Raspberry Pi models support booting via either a Linux kernel (``-kernel``)
+or UEFI/EDK2 firmware images (``-bios rpi_efi.fd``).
+
+When booting Raspberry Pi 3 (``raspi3b``, ``raspi3ap``) and Raspberry Pi 4
(``raspi4b``)
+boards with EDK2 firmware via ``-bios``, the firmware image is loaded at
physical
+memory address ``0x0``, matching the platform expectations. Older 32-bit models
+(``raspi0``, ``raspi1ap``, ``raspi2b``) load firmware at their respective
legacy addresses
+(``0x8000``).
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
index 3f99e87428c..c0b177f8cb1 100644
--- a/hw/arm/raspi.c
+++ b/hw/arm/raspi.c
@@ -33,8 +33,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(RaspiMachineState, RASPI_MACHINE)
#define SMPBOOT_ADDR 0x300 /* this should leave enough space for ATAGS */
#define MVBAR_ADDR 0x400 /* secure vectors */
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
-#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
-#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
+#define KERNEL_ADDR_PI2 0x8000 /* Pi 2 loads kernel.img here by default */
#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
struct RaspiMachineState {
@@ -193,7 +192,7 @@ static void setup_boot(MachineState *machine, ARMCPU *cpu,
RaspiProcessorId processor_id, size_t ram_size)
{
RaspiBaseMachineState *s = RASPI_BASE_MACHINE(machine);
- int r;
+ ssize_t r;
s->binfo.ram_size = ram_size;
@@ -226,9 +225,15 @@ static void setup_boot(MachineState *machine, ARMCPU *cpu,
* the normal Linux boot process
*/
if (machine->firmware) {
- hwaddr firmware_addr = processor_id <= PROCESSOR_ID_BCM2836
- ? FIRMWARE_ADDR_2 : FIRMWARE_ADDR_3;
- /* load the firmware image (typically kernel.img) */
+ hwaddr firmware_addr;
+ if (processor_id <= PROCESSOR_ID_BCM2836) {
+ // For RPi 0/1/2 (arm, 32 bit mode) support kernel.img loading at
default address
+ firmware_addr = KERNEL_ADDR_PI2;
+ } else {
+ // For RPi 3 or newer boards (aarch64), support edk2 firmware
+ firmware_addr = 0x0;
+ }
+ /* Load the firmware image (typically kernel.img or edk2 firmware) */
r = load_image_targphys(machine->firmware, firmware_addr,
ram_size - firmware_addr, NULL);
if (r < 0) {
diff --git a/tests/functional/aarch64/test_raspi3.py
b/tests/functional/aarch64/test_raspi3.py
index ae9eed3589f..709c7221fa4 100755
--- a/tests/functional/aarch64/test_raspi3.py
+++ b/tests/functional/aarch64/test_raspi3.py
@@ -29,6 +29,18 @@ def test_aarch64_raspi3_atf(self):
self.vm.launch()
self.wait_for_console_pattern('version UEFI Firmware v1.15')
+ def test_aarch64_raspi3_bios(self):
+ efi_name = 'RPI_EFI.fd'
+ efi_fd = self.archive_extract(self.ASSET_RPI3_UEFI, member=efi_name)
+
+ self.set_machine('raspi3b')
+ self.vm.set_console(console_index=1)
+ self.vm.add_args('-cpu', 'cortex-a53',
+ '-nodefaults',
+ '-bios', efi_fd)
+ self.vm.launch()
+ self.wait_for_console_pattern('version UEFI Firmware v1.15')
+
if __name__ == '__main__':
LinuxKernelTest.main()
--
2.55.0