From: Bin Meng <bin.meng@processmission.com>
To: QEMU <qemu-devel@nongnu.org>
Cc: Peter Maydell <peter.maydell@linaro.org>, qemu-arm@nongnu.org
Subject: [PATCH 16/33] hw/arm: phytium: Integrate the Phytium E2000 PBR
Date: Thu, 3 Sep 2026 19:24:56 +0800 [thread overview]
Message-ID: <20260903112532.3276678-17-bin.meng@processmission.com> (raw)
In-Reply-To: <20260903112532.3276678-1-bin.meng@processmission.com>
Instantiate PBR in the Phytium Pi machine, map its status and boot
memories, provide the heterogeneous MPIDR topology, and connect all
CPU objects for reset-time handoff.
Use SD0 as the board firmware backend. Explicitly reject the unsupported
-bios and pflash interfaces.
Signed-off-by: Bin Meng <bin.meng@processmission.com>
---
hw/arm/phytium_e2000.c | 97 +++++++++++++++++++++++++++++++++++++++---
1 file changed, 92 insertions(+), 5 deletions(-)
diff --git a/hw/arm/phytium_e2000.c b/hw/arm/phytium_e2000.c
index c6d789bb04..e74a0328fe 100644
--- a/hw/arm/phytium_e2000.c
+++ b/hw/arm/phytium_e2000.c
@@ -13,6 +13,7 @@
#include "qemu/error-report.h"
#include "qemu/units.h"
#include "qapi/error.h"
+#include "exec/cpu-common.h"
#include "system/address-spaces.h"
#include "system/kvm.h"
#include "system/system.h"
@@ -20,6 +21,7 @@
#include "hw/arm/boot.h"
#include "hw/arm/bsa.h"
#include "hw/arm/machines-qom.h"
+#include "hw/block/flash.h"
#include "hw/char/pl011.h"
#include "hw/core/boards.h"
#include "hw/core/qdev-properties.h"
@@ -27,6 +29,7 @@
#include "hw/intc/arm_gicv3_its_common.h"
#include "hw/misc/phytium_e2000_ddr.h"
#include "hw/misc/phytium_e2000_mhu.h"
+#include "hw/misc/phytium_e2000_pbr.h"
#include "hw/misc/unimp.h"
#include "hw/net/cadence_gem.h"
#include "hw/pci/pci.h"
@@ -96,8 +99,10 @@ struct PhytiumE2000State {
struct arm_boot_info bootinfo;
DeviceState *gic;
DeviceState *qspi;
+ PhytiumE2000PBRState *pbr;
PhytiumE2000MciState *mci[PHYTIUM_E2000_NUM_MCIS];
CadenceGEMState *gem[PHYTIUM_E2000_NUM_GEMS];
+ CPUState *cpu[PHYTIUM_E2000_NUM_CPUS];
MemoryRegion scp_sram;
MemoryRegion ram_low;
MemoryRegion ram_high;
@@ -208,6 +213,17 @@ phytium_e2000_cpu_config[PHYTIUM_E2000_NUM_CPUS] = {
},
};
+static uint64_t phytium_e2000_cpu_mp_affinity(unsigned int cpu)
+{
+ /*
+ * E2000Q exposes one core in each of the first two clusters and two cores
+ * in the third cluster. Firmware stores these MPIDRs in its parameter
+ * tables, so a linear CPU index is not a valid affinity value.
+ */
+ g_assert(cpu < ARRAY_SIZE(phytium_e2000_cpu_config));
+ return phytium_e2000_cpu_config[cpu].mp_affinity;
+}
+
static void phytium_e2000_create_its(PhytiumE2000State *s)
{
DeviceState *dev = qdev_new(its_class_name());
@@ -410,6 +426,15 @@ static void phytium_e2000_create_pcie(PhytiumE2000State *s)
}
}
+static void phytium_e2000_reject_legacy_firmware(MachineState *ms)
+{
+ if (ms->firmware || drive_get(IF_PFLASH, 0, 0)) {
+ error_report("phytium-pi: -bios and pflash firmware are not "
+ "supported; use an if=sd,index=0 image");
+ exit(1);
+ }
+}
+
static BlockBackend *phytium_e2000_sd_blk(int index)
{
DriveInfo *dinfo = drive_get(IF_SD, 0, index);
@@ -471,6 +496,47 @@ static void phytium_e2000_create_qspi(PhytiumE2000State *s)
phytium_e2000_memmap[PHYTIUM_E2000_QSPI_DIRECT].base, 2);
}
+static bool phytium_e2000_create_pbr(PhytiumE2000State *s)
+{
+ MachineState *ms = MACHINE(s);
+ DeviceState *dev = qdev_new(TYPE_PHYTIUM_E2000_PBR);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ BlockBackend *boot_blk = NULL;
+ uint64_t cpu_mpidrs[PHYTIUM_E2000_NUM_CPUS];
+ int i;
+
+ if (!ms->kernel_filename) {
+ boot_blk = phytium_e2000_sd_blk(0);
+ }
+
+ for (i = 0; i < ms->smp.cpus; i++) {
+ cpu_mpidrs[i] = phytium_e2000_cpu_mp_affinity(i);
+ }
+
+ qdev_prop_set_string(dev, "boot-mode",
+ PHYTIUM_E2000_PBR_BOOT_MODE_SD0);
+ phytium_e2000_pbr_configure(PHYTIUM_E2000_PBR(dev), boot_blk,
+ phytium_e2000_memmap[
+ PHYTIUM_E2000_RAM].base,
+ ms->ram_size, cpu_mpidrs, ms->smp.cpus);
+
+ /*
+ * PBR owns the status snapshot and both boot memories. The status block
+ * overlaps the broad board-control placeholder and therefore needs the
+ * higher mapping priority used by the previous status-only device.
+ */
+ object_property_add_child(OBJECT(s), "pbr", OBJECT(dev));
+ sysbus_realize_and_unref(sbd, &error_fatal);
+ sysbus_mmio_map_overlap(sbd, 0, PHYTIUM_E2000_PBR_STATUS_BASE, 2);
+ sysbus_mmio_map(sbd, 1,
+ phytium_e2000_memmap[PHYTIUM_E2000_BOOT_SRAM].base);
+ sysbus_mmio_map(sbd, 2,
+ phytium_e2000_memmap[PHYTIUM_E2000_BOOT_IACC].base);
+ s->pbr = PHYTIUM_E2000_PBR(dev);
+
+ return phytium_e2000_pbr_firmware_loaded(s->pbr);
+}
+
static void phytium_e2000_create_ddr_status(PhytiumE2000State *s)
{
DeviceState *dev = qdev_new(TYPE_PHYTIUM_E2000_DDR);
@@ -570,7 +636,8 @@ static void phytium_e2000_create_ram(PhytiumE2000State *s)
phytium_e2000_memmap[PHYTIUM_E2000_RAM_HIGH].base, &s->ram_high);
}
-static void phytium_e2000_create_cpus(PhytiumE2000State *s)
+static void phytium_e2000_create_cpus(PhytiumE2000State *s,
+ bool firmware_loaded)
{
MachineState *ms = MACHINE(s);
const CPUArchIdList *possible_cpus;
@@ -587,18 +654,30 @@ static void phytium_e2000_create_cpus(PhytiumE2000State *s)
&error_abort);
object_property_set_int(cpuobj, "cntfrq", PHYTIUM_E2000_GTIMER_HZ,
&error_abort);
- if (object_property_find(cpuobj, "has_el3")) {
+ if (!firmware_loaded && object_property_find(cpuobj, "has_el3")) {
/*
* The generic-loader U-Boot path starts after the EL3 firmware
* stages that normally provide the Phytium SMC services.
*/
object_property_set_bool(cpuobj, "has_el3", false, &error_abort);
}
+ /*
+ * PBR releases only the primary MPIDR named in the firmware parameter
+ * header. Secondary CPUs remain powered off for later firmware or
+ * PSCI bring-up.
+ */
+ if (firmware_loaded &&
+ i != phytium_e2000_pbr_primary_cpu(s->pbr)) {
+ object_property_set_bool(cpuobj, "start-powered-off", true,
+ &error_abort);
+ }
object_property_set_link(cpuobj, "memory", OBJECT(get_system_memory()),
&error_abort);
cs = CPU(cpuobj);
cs->cpu_index = i;
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
+ s->cpu[i] = cs;
+ phytium_e2000_pbr_connect_cpu(s->pbr, i, cs);
object_unref(cpuobj);
}
}
@@ -606,6 +685,7 @@ static void phytium_e2000_create_cpus(PhytiumE2000State *s)
static void phytium_pi_init(MachineState *ms)
{
PhytiumE2000State *s = PHYTIUM_PI(ms);
+ bool firmware_loaded;
int i;
if (kvm_enabled()) {
@@ -626,12 +706,15 @@ static void phytium_pi_init(MachineState *ms)
exit(1);
}
+ phytium_e2000_reject_legacy_firmware(ms);
+
phytium_e2000_create_ram(s);
phytium_e2000_create_unimplemented();
phytium_e2000_create_qspi(s);
+ firmware_loaded = phytium_e2000_create_pbr(s);
- phytium_e2000_create_cpus(s);
+ phytium_e2000_create_cpus(s, firmware_loaded);
phytium_e2000_create_gic(s);
phytium_e2000_create_scp_sram(s);
@@ -654,7 +737,7 @@ static void phytium_pi_init(MachineState *ms)
s->bootinfo.board_id = -1;
s->bootinfo.loader_start = phytium_e2000_memmap[PHYTIUM_E2000_RAM].base;
s->bootinfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
- s->bootinfo.firmware_loaded = false;
+ s->bootinfo.firmware_loaded = firmware_loaded;
arm_load_kernel(ARM_CPU(first_cpu), ms, &s->bootinfo);
}
@@ -701,7 +784,11 @@ static void phytium_pi_class_init(ObjectClass *oc, const void *data)
mc->valid_cpu_types = valid_cpu_types;
mc->max_cpus = PHYTIUM_E2000_NUM_CPUS;
mc->default_cpus = PHYTIUM_E2000_NUM_CPUS;
- mc->default_ram_size = 1 * GiB;
+ /*
+ * PBF/BL1 relocates to 0xf8c40000, which is outside a 1 GiB RAM window
+ * starting at 0x80000000. Two GiB is the minimum useful firmware default.
+ */
+ mc->default_ram_size = 2 * GiB;
mc->default_ram_id = "phytium-e2000.ram";
mc->minimum_page_bits = 12;
mc->block_default_type = IF_SD;
--
2.53.0
next prev parent reply other threads:[~2026-09-03 11:27 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-03 11:24 [PATCH 00/33] hw/arm: Add Phytium E2000Q SoC and board support Bin Meng
2026-09-03 11:24 ` [PATCH 01/33] target/arm: Add Phytium FTC310 and FTC664 CPU models Bin Meng
2026-09-03 14:45 ` Alex Bennée
2026-09-05 3:39 ` Bin Meng
2026-09-03 11:24 ` [PATCH 02/33] hw/arm: Add basic Phytium Pi machine Bin Meng
2026-09-03 16:56 ` Philippe Mathieu-Daudé
2026-09-04 7:57 ` Bin Meng
2026-09-04 10:15 ` Philippe Mathieu-Daudé
2026-09-04 10:25 ` Daniel P. Berrangé
2026-09-04 10:28 ` Peter Maydell
2026-09-04 10:36 ` Daniel P. Berrangé
2026-09-04 10:47 ` Peter Maydell
2026-09-04 11:24 ` Philippe Mathieu-Daudé
2026-09-04 11:40 ` Daniel P. Berrangé
2026-09-04 10:25 ` Peter Maydell
2026-09-03 11:24 ` [PATCH 03/33] hw/arm: phytium: Add Phytium E2000 PCIe host Bin Meng
2026-09-03 11:24 ` [PATCH 05/33] hw/sd: Add Phytium E2000 MCI controller Bin Meng
2026-09-03 11:24 ` [PATCH 06/33] hw/arm: phytium: Connect Phytium E2000 MCI controllers Bin Meng
2026-09-03 11:24 ` [PATCH 08/33] hw/arm: phytium: Connect Phytium E2000 GEM controllers Bin Meng
2026-09-03 11:24 ` [PATCH 09/33] hw/misc: Add Phytium E2000 DDR status Bin Meng
2026-09-03 11:24 ` [PATCH 10/33] hw/arm: phytium: Connect the " Bin Meng
2026-09-03 11:24 ` [PATCH 11/33] hw/misc: Add Phytium E2000 MHU doorbell Bin Meng
2026-09-03 11:24 ` [PATCH 12/33] hw/arm: phytium: Connect the Phytium E2000 MHU Bin Meng
2026-09-03 11:24 ` [PATCH 13/33] hw/ssi: Add Phytium E2000 QSPI controller Bin Meng
2026-09-03 11:24 ` [PATCH 14/33] hw/arm: phytium: Connect the " Bin Meng
2026-09-03 11:24 ` [PATCH 15/33] hw/misc: Add Phytium E2000 PBR model Bin Meng
2026-09-03 11:24 ` Bin Meng [this message]
2026-09-03 11:24 ` [PATCH 17/33] hw/arm: phytium: Add Phytium E2000 control region placeholders Bin Meng
2026-09-03 11:24 ` [PATCH 18/33] hw/misc: Support Phytium E2000 SCMI CPU power control Bin Meng
2026-09-03 11:24 ` [PATCH 19/33] hw/arm: phytium: Select the Phytium E2000 PBR boot medium Bin Meng
2026-09-03 11:25 ` [PATCH 20/33] hw/arm: phytium: Connect the Phytium E2000 I2C controller Bin Meng
2026-09-03 11:25 ` [PATCH 21/33] hw/arm: phytium: Add Phytium E2000 xHCI controllers Bin Meng
2026-09-03 11:25 ` [PATCH 22/33] hw/misc: Model the Phytium E2000 random generator Bin Meng
2026-09-03 11:25 ` [PATCH 23/33] hw/arm: phytium: Connect " Bin Meng
2026-09-03 11:25 ` [PATCH 24/33] hw/arm: phytium: Support Phytium E2000 direct Linux boot Bin Meng
2026-09-03 11:25 ` [PATCH 25/33] hw/arm: phytium: Add Phytium E2000Q COMe machine Bin Meng
2026-09-03 11:25 ` [PATCH 27/33] hw/arm: phytium: Connect the Phytium E2000Q COMe QSPI flash Bin Meng
2026-09-03 11:25 ` [PATCH 28/33] hw/arm: phytium: Add Phytium E2000 AHCI controllers Bin Meng
2026-09-03 11:25 ` [PATCH 29/33] hw/arm: Add Phytium E2000 Linux SCMI channel Bin Meng
2026-09-03 11:25 ` [PATCH 30/33] hw/arm: phytium: Connect the Phytium E2000 SMMUv3 Bin Meng
2026-09-03 11:25 ` [PATCH 31/33] docs/system/arm: Document Phytium E2000 machines Bin Meng
2026-09-03 11:25 ` [PATCH 32/33] tests/functional/aarch64: Add Phytium Pi boot tests Bin Meng
2026-09-03 14:38 ` Alex Bennée
2026-09-04 8:52 ` Bin Meng
2026-09-04 14:23 ` Alex Bennée
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=20260903112532.3276678-17-bin.meng@processmission.com \
--to=bin.meng@processmission.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox