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: 52+ 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 04/33] hw/sd: Add Synopsys DesignWare MCI controller Bin Meng
2026-09-03 15:07 ` Philippe Mathieu-Daudé
2026-09-04 11:42 ` Bin Meng
2026-09-03 11:24 ` [PATCH 05/33] hw/sd: Add Phytium E2000 " 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 07/33] tests/qtest: Add Synopsys DesignWare MCI coverage 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 26/33] hw/block: m25p80: Add GigaDevice GD25Q128 flash 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
2026-09-03 11:25 ` [PATCH 33/33] MAINTAINERS: Add Phytium E2000Q machines Bin Meng
2026-09-03 15:08 ` Philippe Mathieu-Daudé
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 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.