[PATCH 3/3] platform: generic: spacemit: k3: wake A100 core 8 for ESOS/RPMI services
Valentin Haudiquet
valentin.haudiquet at canonical.com
Mon Aug 31 13:07:52 PDT 2026
The K3 SoC has two asymmetric CPU complexes: X100 (harts 0-7) and A100
(harts 8-15). ESOS -- the rcpu-side firmware already loaded in SPI NOR --
runs on A100 core 8 and provides RPMI services (clock, voltage, device
power, system reset, suspend) that the X100 side depends on during boot.
Without waking core 8, all RPMI mailbox transactions time out and the
system hangs early during Linux boot (at basic.target or
cryptsetup.target, depending on which earlier fixes are present).
Wake hart 8 during pre_init by writing its RVBADDR to a minimal assembly
entry (_spacemit_k3_dummy_start) that does A100-specific CSR setup,
restores C2 RVBADDR to the normal warm-boot entry, and enters WFI. The
HSM can later start hart 8 normally -- the HSM hart_start happens
post-boot from Linux, so there is no race with the dummy path writing
RVBADDR concurrently.
Add A100 performance CSR definitions (VEC_L1BYPASS, L2_PERF_DIST,
CIU_CHR2_DEPD_DIS, CIU_CHR2_MER_DIS) to k3.h and the
_spacemit_k3_dummy_start entry to k3_asm.S.
Signed-off-by: Valentin Haudiquet <valentin.haudiquet at canonical.com>
---
platform/generic/include/spacemit/k3.h | 11 ++++
platform/generic/include/spacemit/k3_asm.h | 1 +
platform/generic/spacemit/k3.c | 19 ++++++
platform/generic/spacemit/k3_asm.S | 75 ++++++++++++++++++++++
4 files changed, 106 insertions(+)
diff --git a/platform/generic/include/spacemit/k3.h b/platform/generic/include/spacemit/k3.h
index ed1637b9..b50e9b1b 100644
--- a/platform/generic/include/spacemit/k3.h
+++ b/platform/generic/include/spacemit/k3.h
@@ -129,4 +129,15 @@
#define DMASYS_CLK_EN (0xd8440000 + 0x234)
#define DMASYS_RESET_DEASSERT BIT(0)
#define DMASYS_CLK_EN_BIT BIT(0)
+/*
+ * A100 core performance CSRs. CIU_CHR2_DEPD_DIS and CIU_CHR2_MER_DIS
+ * are bitfields of CSR_ML2HINT (0x7f7), named after the hardware manual's
+ * CIU_CHR2 register description.
+ */
+#define CSR_PERF_CTRL 0x7d0
+#define VEC_L1BYPASS (_UL(1) << 32)
+#define CSR_PREFETCH_CTRL 0x7d1
+#define L2_PERF_DIST (_UL(3) << 10)
+#define CIU_CHR2_DEPD_DIS (_UL(1) << 3)
+#define CIU_CHR2_MER_DIS (_UL(1) << 2)
#endif /* __RISCV_SPACEMIT_K3_H__ */
diff --git a/platform/generic/include/spacemit/k3_asm.h b/platform/generic/include/spacemit/k3_asm.h
index 70c00478..3f06b20e 100644
--- a/platform/generic/include/spacemit/k3_asm.h
+++ b/platform/generic/include/spacemit/k3_asm.h
@@ -11,6 +11,7 @@
#ifndef __ASSEMBLY__
void _spacemit_k3_warm_start(void);
+void _spacemit_k3_dummy_start(void);
#endif
#endif /* __RISCV_SPACEMIT_K3_ASM_H__ */
diff --git a/platform/generic/spacemit/k3.c b/platform/generic/spacemit/k3.c
index f134427d..650e9f98 100644
--- a/platform/generic/spacemit/k3.c
+++ b/platform/generic/spacemit/k3.c
@@ -128,6 +128,25 @@ static void spacemit_k3_pre_init(void)
for (i = 0; i < array_size(cci_map); i++)
cci_enable_snoop_dvm_reqs(cci_map, i);
+
+ /*
+ * Wake hart 8 (first A100 core, cluster 2) so that ESOS -- already
+ * loaded in SPI NOR -- can provide RPMI services (clock, voltage,
+ * device power, system reset, suspend). Without this, all RPMI
+ * mailbox transactions time out.
+ *
+ * Core 8 jumps to _spacemit_k3_dummy_start which does minimal A100
+ * setup, restores C2 RVBADDR to the normal warm-boot entry, and
+ * enters WFI. The K3 HSM can later start it normally -- the HSM
+ * hart_start for hart 8 happens much later (post-boot, from Linux),
+ * so there is no window where both the dummy path and HSM could
+ * write RVBADDR concurrently.
+ */
+ writel((u32)(unsigned long)&_spacemit_k3_dummy_start,
+ (void *)(unsigned long)C2_RVBADDR_LO_ADDR);
+ writel((u32)((unsigned long)&_spacemit_k3_dummy_start >> 32),
+ (void *)(unsigned long)C2_RVBADDR_HI_ADDR);
+ writel(BIT(8), (void *)(unsigned long)PMU_CAP_CORE8_WAKEUP);
}
static int spacemit_k3_early_init(bool cold_boot)
diff --git a/platform/generic/spacemit/k3_asm.S b/platform/generic/spacemit/k3_asm.S
index 2da58857..9d1ea5c5 100644
--- a/platform/generic/spacemit/k3_asm.S
+++ b/platform/generic/spacemit/k3_asm.S
@@ -50,3 +50,78 @@ _spacemit_k3_warm_start:
.word 0x62000073 /* hfence.gvma */
1:
j _start_warm
+
+/*
+ * Minimal entry point for the initial wake of an A100 core (hart 8) on
+ * cluster 2. Its sole purpose is to power up the cluster so that ESOS
+ * -- already loaded in SPI NOR -- can provide RPMI services (clock, voltage,
+ * device power, system reset, suspend). After setup the core enters WFI;
+ * the K3 HSM can later start it normally via the warm-boot vector.
+ *
+ * The PMA/L2/cache setup below mirrors _spacemit_k3_warm_start, plus
+ * A100-specific performance CSRs that ESOS needs. These are applied
+ * only here because upstream K3 support targets X100 harts (0-7) for
+ * Linux; A100 harts (8-15) are used solely for ESOS. When the HSM
+ * later starts hart 8 from Linux, it enters warm_start -- the perf CSR
+ * settings persist from this initial wake since it is a WFI exit, not
+ * a cold reset.
+ *
+ * The C2 RVBADDR is restored to _spacemit_k3_warm_start so that the next
+ * wake (from HSM hart_start) enters the standard OpenSBI warm-boot path.
+ */
+ .align 3
+ .globl _spacemit_k3_dummy_start
+_spacemit_k3_dummy_start:
+ /* Disable all interrupts. */
+ csrw 0x304, zero /* CSR_MIE */
+
+ /* Program PMA attributes before enabling the caches. */
+ li t0, (PMACFG0_AUDIO_BUF_FIELD_MASK << \
+ PMACFG0_AUDIO_BUF_FIELD_SHIFT)
+ csrc CSR_PMACFG0, t0
+ li t0, (PMACFG0_AUDIO_BUF_ATTR_CACHEABLE << \
+ PMACFG0_AUDIO_BUF_FIELD_SHIFT)
+ csrs CSR_PMACFG0, t0
+ li t0, PMACFG0_XIP_FIELD_CLEAR
+ csrc CSR_PMACFG0, t0
+ li t0, PMACFG0_XIP_ATTR_IO
+ csrs CSR_PMACFG0, t0
+ sfence.vma
+
+ /* A100-specific performance CSRs. */
+ li t0, VEC_L1BYPASS
+ csrs CSR_PERF_CTRL, t0
+ li t0, L2_PERF_DIST
+ csrs CSR_PREFETCH_CTRL, t0
+ li t0, CIU_CHR2_DEPD_DIS
+ csrc CSR_ML2HINT, t0
+ li t0, CIU_CHR2_MER_DIS
+ csrs CSR_ML2HINT, t0
+
+ /* Enable L1 snooping and L2 prefetch for this hart. */
+ csrr t0, mhartid
+ andi t0, t0, (PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
+ li t1, 1
+ sll t1, t1, t0
+ li t2, (ML2SETUP_IPRF | ML2SETUP_TPRF)
+ or t1, t1, t2
+ csrs CSR_ML2SETUP, t1
+ li t0, ML2HINT_TRACE_TOP_ICGEN
+ csrs CSR_ML2HINT, t0
+
+ /* Enable caches. */
+ li t0, MSETUP_BOOT_FLAGS
+ csrs CSR_MSETUP, t0
+ fence iorw, iorw /* A100 needs explicit fence after MSETUP */
+
+ /* Restore C2 RVBADDR to the normal warm-boot entry. */
+ lla t0, _spacemit_k3_warm_start
+ li t1, C2_RVBADDR_LO_ADDR
+ sw t0, 0(t1)
+ li t1, C2_RVBADDR_HI_ADDR
+ srli t0, t0, 32
+ sw t0, 0(t1)
+
+ /* Enter WFI until the HSM starts this hart. */
+1: wfi
+ j 1b
--
2.53.0
More information about the opensbi
mailing list