@samitouri / QOSamiQemu / commits / 9672cd7770

target/arm: Move OMAP CP15 register definitions to 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> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Alessandro Ratti <alessandro@0x65c.net> Message-id: 20260405180826.729652-1-alessandro@0x65c.net Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

Alessandro Ratti committed Apr 23, 2026 at 10:24 UTC 9672cd7770176297817ef753001ed27c07500253
5 files changed +103 -78
target/arm/cpregs-omap-stub.c new
+10
@@ -0,0 +1,10 @@
1 +/* SPDX-License-Identifier: GPL-2.0-or-later */
2 +
3 +#include "qemu/osdep.h"
4 +#include "target/arm/cpu-qom.h"
5 +#include "internals.h"
6 +
7 +void define_omap_cp_regs(ARMCPU *cpu)
8 +{
9 + g_assert_not_reached();
10 +}
target/arm/cpregs-omap.c new
+88
@@ -0,0 +1,88 @@
1 +/*
2 + * QEMU ARM OMAP CP15 register definitions
3 + *
4 + * SPDX-License-Identifier: GPL-2.0-or-later
5 + */
6 +
7 +#include "qemu/osdep.h"
8 +#include "target/arm/cpu.h"
9 +#include "target/arm/cpregs.h"
10 +#include "target/arm/internals.h"
11 +
12 +static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
13 + uint64_t value)
14 +{
15 + env->cp15.c15_ticonfig = value & 0xe7;
16 + /* The OS_TYPE bit in this register changes the reported CPUID! */
17 + env->cp15.c0_cpuid = (value & (1 << 5)) ?
18 + ARM_CPUID_TI915T : ARM_CPUID_TI925T;
19 +}
20 +
21 +static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
22 + uint64_t value)
23 +{
24 + env->cp15.c15_threadid = value & 0xffff;
25 +}
26 +
27 +static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
28 + uint64_t value)
29 +{
30 + /* Wait-for-interrupt (deprecated) */
31 + cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
32 +}
33 +
34 +static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
35 + uint64_t value)
36 +{
37 + /*
38 + * On OMAP there are registers indicating the max/min index of dcache lines
39 + * containing a dirty line; cache flush operations have to reset these.
40 + */
41 + env->cp15.c15_i_max = 0x000;
42 + env->cp15.c15_i_min = 0xff0;
43 +}
44 +
45 +static const ARMCPRegInfo omap_cp_reginfo[] = {
46 + { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
47 + .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
48 + .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
49 + .resetvalue = 0, },
50 + { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
51 + .access = PL1_RW, .type = ARM_CP_NOP },
52 + { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
53 + .access = PL1_RW,
54 + .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
55 + .writefn = omap_ticonfig_write },
56 + { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
57 + .access = PL1_RW,
58 + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
59 + { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
60 + .access = PL1_RW, .resetvalue = 0xff0,
61 + .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
62 + { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
63 + .access = PL1_RW,
64 + .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
65 + .writefn = omap_threadid_write },
66 + { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
67 + .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
68 + .type = ARM_CP_NO_RAW,
69 + .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
70 + /*
71 + * TODO: Peripheral port remap register:
72 + * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
73 + * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
74 + * when MMU is off.
75 + */
76 + { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
77 + .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
78 + .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
79 + .writefn = omap_cachemaint_write },
80 + { .name = "C9", .cp = 15, .crn = 9,
81 + .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
82 + .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
83 +};
84 +
85 +void define_omap_cp_regs(ARMCPU *cpu)
86 +{
87 + define_arm_cp_regs(cpu, omap_cp_reginfo);
88 +}
target/arm/helper.c
+1 -78
@@ -2900,83 +2900,6 @@ static const ARMCPRegInfo ttbcr2_reginfo = {
2900 },
2901 };
2902
2903 -static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri,
2904 - uint64_t value)
2905 -{
2906 - env->cp15.c15_ticonfig = value & 0xe7;
2907 - /* The OS_TYPE bit in this register changes the reported CPUID! */
2908 - env->cp15.c0_cpuid = (value & (1 << 5)) ?
2909 - ARM_CPUID_TI915T : ARM_CPUID_TI925T;
2910 -}
2911 -
2912 -static void omap_threadid_write(CPUARMState *env, const ARMCPRegInfo *ri,
2913 - uint64_t value)
2914 -{
2915 - env->cp15.c15_threadid = value & 0xffff;
2916 -}
2917 -
2918 -static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
2919 - uint64_t value)
2920 -{
2921 -#ifdef CONFIG_USER_ONLY
2922 - g_assert_not_reached();
2923 -#else
2924 - /* Wait-for-interrupt (deprecated) */
2925 - cpu_interrupt(env_cpu(env), CPU_INTERRUPT_HALT);
2926 -#endif
2927 -}
2928 -
2929 -static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
2930 - uint64_t value)
2931 -{
2932 - /*
2933 - * On OMAP there are registers indicating the max/min index of dcache lines
2934 - * containing a dirty line; cache flush operations have to reset these.
2935 - */
2936 - env->cp15.c15_i_max = 0x000;
2937 - env->cp15.c15_i_min = 0xff0;
2938 -}
2939 -
2940 -static const ARMCPRegInfo omap_cp_reginfo[] = {
2941 - { .name = "DFSR", .cp = 15, .crn = 5, .crm = CP_ANY,
2942 - .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW, .type = ARM_CP_OVERRIDE,
2943 - .fieldoffset = offsetoflow32(CPUARMState, cp15.esr_el[1]),
2944 - .resetvalue = 0, },
2945 - { .name = "", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
2946 - .access = PL1_RW, .type = ARM_CP_NOP },
2947 - { .name = "TICONFIG", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
2948 - .access = PL1_RW,
2949 - .fieldoffset = offsetof(CPUARMState, cp15.c15_ticonfig), .resetvalue = 0,
2950 - .writefn = omap_ticonfig_write },
2951 - { .name = "IMAX", .cp = 15, .crn = 15, .crm = 2, .opc1 = 0, .opc2 = 0,
2952 - .access = PL1_RW,
2953 - .fieldoffset = offsetof(CPUARMState, cp15.c15_i_max), .resetvalue = 0, },
2954 - { .name = "IMIN", .cp = 15, .crn = 15, .crm = 3, .opc1 = 0, .opc2 = 0,
2955 - .access = PL1_RW, .resetvalue = 0xff0,
2956 - .fieldoffset = offsetof(CPUARMState, cp15.c15_i_min) },
2957 - { .name = "THREADID", .cp = 15, .crn = 15, .crm = 4, .opc1 = 0, .opc2 = 0,
2958 - .access = PL1_RW,
2959 - .fieldoffset = offsetof(CPUARMState, cp15.c15_threadid), .resetvalue = 0,
2960 - .writefn = omap_threadid_write },
2961 - { .name = "TI925T_STATUS", .cp = 15, .crn = 15,
2962 - .crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
2963 - .type = ARM_CP_NO_RAW,
2964 - .readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
2965 - /*
2966 - * TODO: Peripheral port remap register:
2967 - * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
2968 - * base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
2969 - * when MMU is off.
2970 - */
2971 - { .name = "OMAP_CACHEMAINT", .cp = 15, .crn = 7, .crm = CP_ANY,
2972 - .opc1 = 0, .opc2 = CP_ANY, .access = PL1_W,
2973 - .type = ARM_CP_OVERRIDE | ARM_CP_NO_RAW,
2974 - .writefn = omap_cachemaint_write },
2975 - { .name = "C9", .cp = 15, .crn = 9,
2976 - .crm = CP_ANY, .opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_RW,
2977 - .type = ARM_CP_CONST | ARM_CP_OVERRIDE, .resetvalue = 0 },
2978 -};
2979 -
2903 static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
2904 /*
2905 * 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)
6966 define_arm_cp_regs(cpu, cache_block_ops_cp_reginfo);
6967 }
6968 if (arm_feature(env, ARM_FEATURE_OMAPCP)) {
7046 - define_arm_cp_regs(cpu, omap_cp_reginfo);
6969 + define_omap_cp_regs(cpu);
6970 }
6971 if (arm_feature(env, ARM_FEATURE_STRONGARM)) {
6972 define_arm_cp_regs(cpu, strongarm_cp_reginfo);
target/arm/internals.h
+2
@@ -1799,6 +1799,8 @@ void define_at_insn_regs(ARMCPU *cpu);
1799 void define_pm_cpregs(ARMCPU *cpu);
1800 /* Add the cpreg definitions for GCS cpregs */
1801 void define_gcs_cpregs(ARMCPU *cpu);
1802 +/* Add the cpreg definitions for OMAP CP15 regs */
1803 +void define_omap_cp_regs(ARMCPU *cpu);
1804
1805 /* Effective value of MDCR_EL2 */
1806 static inline uint64_t arm_mdcr_el2_eff(CPUARMState *env)
target/arm/meson.build
+2
@@ -33,6 +33,7 @@ arm_user_ss.add(files(
33 'helper.c',
34 'vfp_fpscr.c',
35 'el2-stubs.c',
36 + 'cpregs-omap-stub.c',
37 ))
38 arm_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING',
39 if_true: files('common-semi-target.c'))
@@ -48,6 +49,7 @@ arm_common_system_ss.add(files(
49 'arm-powerctl.c',
50 'cortex-regs.c',
51 'cpregs-gcs.c',
52 + 'cpregs-omap.c',
53 'cpregs-pmu.c',
54 'cpu-irq.c',
55 'debug_helper.c',