All of lore.kernel.org
 help / color / mirror / Atom feed
From: opensource@fvhovell.nl
To: qemu-devel@nongnu.org
Cc: qemu-arm@nongnu.org, "Peter Maydell" <peter.maydell@linaro.org>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	"Frederik van Hövell" <frederik@fvhovell.nl>
Subject: [PATCH 3/4] hw/arm/raspi: implement booting firmware at 0x0 using -bios on boards 3ap, 3b and 4b
Date: Wed, 19 Aug 2026 14:27:01 +0200	[thread overview]
Message-ID: <20260819122702.54173-4-opensource@fvhovell.nl> (raw)
In-Reply-To: <20260819122702.54173-1-opensource@fvhovell.nl>

From: Frederik van Hövell <frederik@fvhovell.nl>

Signed-off-by: Frederik van Hövell <frederik@fvhovell.nl>
---
 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



  parent reply	other threads:[~2026-08-19 12:43 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-19 12:26 [PATCH 0/4] Support booting modern EDK2 on raspi3b board opensource
2026-08-19 12:26 ` [PATCH 1/4] hw/misc/bcm2835_property: fix RPI_FWREQ_FRAMEBUFFER_ALLOCATE response opensource
2026-08-19 12:27 ` [PATCH 2/4] hw/misc/bcm2835_property: fix RPI_FWREQ_GET_FIRMWARE_REVISION response opensource
2026-08-19 12:27 ` opensource [this message]
2026-08-19 12:27 ` [PATCH 4/4] tests/functional/aarch64/test_raspi3: update firmware to v1.52 opensource

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260819122702.54173-4-opensource@fvhovell.nl \
    --to=opensource@fvhovell.nl \
    --cc=f4bug@amsat.org \
    --cc=frederik@fvhovell.nl \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.