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


Reply via email to