target/arm/cpregs-omap-stub.c | 10 ++++ target/arm/cpregs-omap.c | 88 +++++++++++++++++++++++++++++++++++ target/arm/helper.c | 79 +------------------------------ target/arm/internals.h | 2 + target/arm/meson.build | 2 + 5 files changed, 103 insertions(+), 78 deletions(-) create mode 100644 target/arm/cpregs-omap-stub.c create mode 100644 target/arm/cpregs-omap.c
The OMAP CP15 registers are only relevant to system-mode emulation
of OMAP SoCs. Move them out of the monolithic helper.c into a
dedicated file, following the pattern of cpregs-pmu.c and
cpregs-gcs.c. This reduces the size of helper.c and compiles
the OMAP-specific code out of CONFIG_USER_ONLY builds.
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Alessandro Ratti <alessandro@0x65c.net>
---
target/arm/cpregs-omap-stub.c | 10 ++++
target/arm/cpregs-omap.c | 88 +++++++++++++++++++++++++++++++++++
target/arm/helper.c | 79 +------------------------------
target/arm/internals.h | 2 +
target/arm/meson.build | 2 +
5 files changed, 103 insertions(+), 78 deletions(-)
create mode 100644 target/arm/cpregs-omap-stub.c
create mode 100644 target/arm/cpregs-omap.c
diff --git a/target/arm/cpregs-omap-stub.c b/target/arm/cpregs-omap-stub.c
new file mode 100644
index 0000000000..e0fe32632e
--- /dev/null
+++ b/target/arm/cpregs-omap-stub.c
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "internals.h"
+
+void define_omap_cp_regs(ARMCPU *cpu)
+{
+ g_assert_not_reached();
+}
diff --git a/target/arm/cpregs-omap.c b/target/arm/cpregs-omap.c
new file mode 100644
index 0000000000..5fa6b70150
--- /dev/null
+++ b/target/arm/cpregs-omap.c
@@ -0,0 +1,88 @@
+/*
+ * QEMU ARM OMAP CP15 register definitions
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "cpregs.h"
+#include "internals.h"
+
+static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ env->cp15.c15_ticonfig = value & 0xe7;
+ /* The OS_TYPE bit in this register changes the reported CPUID! */
+ env->cp15.c0_cpuid = (value & (1 << 5)) ?
+ ARM_CPUID_TI915T : ARM_CPUID_TI925T;
+}
+
+static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ env->cp15.c15_threadid = value & 0xffff;
+}
+
+static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /* Wait-for-interrupt (deprecated) */
+ cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
+}
+
+static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+ /*
+ * On OMAP there are registers indicating the max/min index of dcache lines
+ * containing a dirty line; cache flush operations have to reset these.
+ */
+ env->cp15.c15_i_max = 0x000;
+ env->cp15.c15_i_min = 0xff0;
+}
+
+static const ARMCPRegInfo omap_cp_reginfo[] = {
+ { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
+ .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
+ .resetvalue = 0, },
+ { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW, .type = ARM_CP_NOP },
+ { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW,
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
+ .writefn = omap_ticonfig_write },
+ { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW,
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
+ { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW, .resetvalue = 0xff0,
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
+ { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
+ .access = PL1_RW,
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
+ .writefn = omap_threadid_write },
+ { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
+ .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
+ .type = ARM_CP_NO_RAW,
+ .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
+ /*
+ * TODO: Peripheral port remap register:
+ * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
+ * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
+ * when MMU is off.
+ */
+ { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
+ .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
+ .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
+ .writefn = omap_cachemaint_write },
+ { .name = "C9", .cp = 15, .crn = 9,
+ .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
+ .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
+};
+
+void define_omap_cp_regs(ARMCPU *cpu)
+{
+ define_arm_cp_regs(cpu, omap_cp_reginfo);
+}
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 7389f2988c..3ac88078aa 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -2900,83 +2900,6 @@ static const ARMCPRegInfo ttbcr2_reginfo = {
},
};
-static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- env->cp15.c15_ticonfig = value & 0xe7;
- /* The OS_TYPE bit in this register changes the reported CPUID! */
- env->cp15.c0_cpuid = (value & (1 << 5)) ?
- ARM_CPUID_TI915T : ARM_CPUID_TI925T;
-}
-
-static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- env->cp15.c15_threadid = value & 0xffff;
-}
-
-static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
-#ifdef CONFIG_USER_ONLY
- g_assert_not_reached();
-#else
- /* Wait-for-interrupt (deprecated) */
- cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
-#endif
-}
-
-static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
-{
- /*
- * On OMAP there are registers indicating the max/min index of dcache lines
- * containing a dirty line; cache flush operations have to reset these.
- */
- env->cp15.c15_i_max = 0x000;
- env->cp15.c15_i_min = 0xff0;
-}
-
-static const ARMCPRegInfo omap_cp_reginfo[] = {
- { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
- .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
- .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
- .resetvalue = 0, },
- { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .type = ARM_CP_NOP },
- { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
- .writefn = omap_ticonfig_write },
- { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
- { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW, .resetvalue = 0xff0,
- .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
- { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
- .access = PL1_RW,
- .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
- .writefn = omap_threadid_write },
- { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
- .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
- .type = ARM_CP_NO_RAW,
- .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
- /*
- * TODO: Peripheral port remap register:
- * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
- * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
- * when MMU is off.
- */
- { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
- .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
- .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
- .writefn = omap_cachemaint_write },
- { .name = "C9", .cp = 15, .crn = 9,
- .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
- .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
-};
-
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
/*
* RAZ/WI the whole crn=15 space, when we don't have a more specific
@@ -7043,7 +6966,7 @@ void register_cp_regs_for_features(ARMCPU *cpu)
define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);
}
if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
- define_arm_cp_regs(cpu, omap_cp_reginfo);
+ define_omap_cp_regs(cpu);
}
if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
define_arm_cp_regs(cpu, strongarm_cp_reginfo);
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 8ec2750847..73fcb84a84 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -1796,6 +1796,8 @@ void define_at_insn_regs(ARMCPU *cpu);
void define_pm_cpregs(ARMCPU *cpu);
/* Add the cpreg definitions for GCS cpregs */
void define_gcs_cpregs(ARMCPU *cpu);
+/* Add the cpreg definitions for OMAP CP15 regs */
+void define_omap_cp_regs(ARMCPU *cpu);
/* Effective value of MDCR_EL2 */
static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
diff --git a/target/arm/meson.build b/target/arm/meson.build
index 6e0e504a40..192ac7c31e 100644
--- a/target/arm/meson.build
+++ b/target/arm/meson.build
@@ -33,6 +33,7 @@ arm_user_ss.add(files(
'helper.c',
'vfp_fpscr.c',
'el2-stubs.c',
+ 'cpregs-omap-stub.c',
))
arm_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
if_true: files('common-semi-target.c'))
@@ -48,6 +49,7 @@ arm_common_system_ss.add(files(
'arm-powerctl.c',
'cortex-regs.c',
'cpregs-gcs.c',
+ 'cpregs-omap.c',
'cpregs-pmu.c',
'cpu-irq.c',
'debug_helper.c',
--
2.53.0
Hi Alessandro,
On 3/4/26 15:14, Alessandro Ratti wrote:
> The OMAP CP15 registers are only relevant to system-mode emulation
> of OMAP SoCs. Move them out of the monolithic helper.c into a
> dedicated file, following the pattern of cpregs-pmu.c and
> cpregs-gcs.c. This reduces the size of helper.c and compiles
> the OMAP-specific code out of CONFIG_USER_ONLY builds.
>
> Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Alessandro Ratti <alessandro@0x65c.net>
> ---
> target/arm/cpregs-omap-stub.c | 10 ++++
> target/arm/cpregs-omap.c | 88 +++++++++++++++++++++++++++++++++++
> target/arm/helper.c | 79 +------------------------------
> target/arm/internals.h | 2 +
> target/arm/meson.build | 2 +
> 5 files changed, 103 insertions(+), 78 deletions(-)
> create mode 100644 target/arm/cpregs-omap-stub.c
> create mode 100644 target/arm/cpregs-omap.c
>
> diff --git a/target/arm/cpregs-omap-stub.c b/target/arm/cpregs-omap-stub.c
> new file mode 100644
> index 0000000000..e0fe32632e
> --- /dev/null
> +++ b/target/arm/cpregs-omap-stub.c
> @@ -0,0 +1,10 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
Instead:
#include "target/arm/cpu-qom.h"
> +#include "internals.h"
> +
> +void define_omap_cp_regs(ARMCPU *cpu)
> +{
> + g_assert_not_reached();
> +}
> diff --git a/target/arm/cpregs-omap.c b/target/arm/cpregs-omap.c
> new file mode 100644
> index 0000000000..5fa6b70150
> --- /dev/null
> +++ b/target/arm/cpregs-omap.c
> @@ -0,0 +1,88 @@
> +/*
> + * QEMU ARM OMAP CP15 register definitions
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "cpu.h"
Please use full target path:
#include "target/arm/cpu.h"
...
> +#include "cpregs.h"
> +#include "internals.h"
With the requested changes:
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
© 2016 - 2026 Red Hat, Inc.