]>
Commit | Line | Data |
---|---|---|
9e5e54d1 | 1 | /* |
0829d24e | 2 | * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200 |
9e5e54d1 PM |
3 | * |
4 | * Copyright (c) 2018 Linaro Limited | |
5 | * Written by Peter Maydell | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 or | |
9 | * (at your option) any later version. | |
10 | */ | |
11 | ||
93dbd103 PM |
12 | /* |
13 | * This is a model of the Arm "Subsystems for Embedded" family of | |
14 | * hardware, which include the IoT Kit and the SSE-050, SSE-100 and | |
0829d24e PM |
15 | * SSE-200. Currently we model: |
16 | * - the Arm IoT Kit which is documented in | |
50b52b18 | 17 | * https://developer.arm.com/documentation/ecm0601256/latest |
0829d24e | 18 | * - the SSE-200 which is documented in |
50b52b18 | 19 | * https://developer.arm.com/documentation/101104/latest/ |
0829d24e PM |
20 | * |
21 | * The IoTKit contains: | |
9e5e54d1 PM |
22 | * a Cortex-M33 |
23 | * the IDAU | |
24 | * some timers and watchdogs | |
25 | * two peripheral protection controllers | |
26 | * a memory protection controller | |
27 | * a security controller | |
28 | * a bus fabric which arranges that some parts of the address | |
29 | * space are secure and non-secure aliases of each other | |
0829d24e PM |
30 | * The SSE-200 additionally contains: |
31 | * a second Cortex-M33 | |
32 | * two Message Handling Units (MHUs) | |
33 | * an optional CryptoCell (which we do not model) | |
34 | * more SRAM banks with associated MPCs | |
35 | * multiple Power Policy Units (PPUs) | |
36 | * a control interface for an icache for each CPU | |
37 | * per-CPU identity and control register blocks | |
9e5e54d1 PM |
38 | * |
39 | * QEMU interface: | |
8fd34dc0 PM |
40 | * + Clock input "MAINCLK": clock for CPUs and most peripherals |
41 | * + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals | |
9e5e54d1 PM |
42 | * + QOM property "memory" is a MemoryRegion containing the devices provided |
43 | * by the board model. | |
91c1e9fc PM |
44 | * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts. |
45 | * (In hardware, the SSE-200 permits the number of expansion interrupts | |
46 | * for the two CPUs to be configured separately, but we restrict it to | |
47 | * being the same for both, to avoid having to have separate Property | |
48 | * lists for different variants. This restriction can be relaxed later | |
49 | * if necessary.) | |
74ecf767 PM |
50 | * + QOM property "SRAM_ADDR_WIDTH" sets the number of bits used for the |
51 | * address of each SRAM bank (and thus the total amount of internal SRAM) | |
32187419 PM |
52 | * + QOM property "init-svtor" sets the initial value of the CPU SVTOR register |
53 | * (where it expects to load the PC and SP from the vector table on reset) | |
a90a862b PM |
54 | * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which |
55 | * set whether the CPUs have the FPU and DSP features present. The default | |
56 | * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an | |
57 | * SSE-200 both are present; CPU0 in an SSE-200 has neither. | |
58 | * Since the IoTKit has only one CPU, it does not have the CPU1_* properties. | |
e73b8bb8 PM |
59 | * + QOM properties "CPU0_MPU_NS", "CPU0_MPU_S", "CPU1_MPU_NS" and "CPU1_MPU_S" |
60 | * which set the number of MPU regions on the CPUs. If there is only one | |
61 | * CPU the CPU1 properties are not present. | |
91c1e9fc PM |
62 | * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0, |
63 | * which are wired to its NVIC lines 32 .. n+32 | |
64 | * + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for | |
65 | * CPU 1, which are wired to its NVIC lines 32 .. n+32 | |
132b475a PM |
66 | * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows |
67 | * bus master devices in the board model to make transactions into | |
68 | * all the devices and memory areas in the IoTKit | |
9e5e54d1 PM |
69 | * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit |
70 | * might provide: | |
71 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] | |
72 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15] | |
73 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable | |
74 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear | |
75 | * + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status | |
76 | * Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit | |
77 | * might provide: | |
78 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15] | |
79 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15] | |
80 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable | |
81 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear | |
82 | * + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status | |
bb75e16d PM |
83 | * Controlling each of the 16 expansion MPCs which a system using the IoTKit |
84 | * might provide: | |
85 | * + named GPIO inputs mpcexp_status[0..15] | |
132b475a PM |
86 | * Controlling each of the 16 expansion MSCs which a system using the IoTKit |
87 | * might provide: | |
88 | * + named GPIO inputs mscexp_status[0..15] | |
89 | * + named GPIO outputs mscexp_clear[0..15] | |
90 | * + named GPIO outputs mscexp_ns[0..15] | |
9e5e54d1 PM |
91 | */ |
92 | ||
6eee5d24 PM |
93 | #ifndef ARMSSE_H |
94 | #define ARMSSE_H | |
9e5e54d1 PM |
95 | |
96 | #include "hw/sysbus.h" | |
97 | #include "hw/arm/armv7m.h" | |
98 | #include "hw/misc/iotkit-secctl.h" | |
99 | #include "hw/misc/tz-ppc.h" | |
af60b291 | 100 | #include "hw/misc/tz-mpc.h" |
9e5e54d1 | 101 | #include "hw/timer/cmsdk-apb-timer.h" |
017d069d | 102 | #include "hw/timer/cmsdk-apb-dualtimer.h" |
9febd175 | 103 | #include "hw/timer/sse-counter.h" |
f11de231 | 104 | #include "hw/timer/sse-timer.h" |
d61e4e1f | 105 | #include "hw/watchdog/cmsdk-apb-watchdog.h" |
06e65af3 PM |
106 | #include "hw/misc/iotkit-sysctl.h" |
107 | #include "hw/misc/iotkit-sysinfo.h" | |
ade67dcd | 108 | #include "hw/misc/armsse-cpuid.h" |
68d6b36f | 109 | #include "hw/misc/armsse-mhu.h" |
4668b441 | 110 | #include "hw/misc/armsse-cpu-pwrctrl.h" |
f8574705 | 111 | #include "hw/misc/unimp.h" |
9e5e54d1 | 112 | #include "hw/or-irq.h" |
8fd34dc0 | 113 | #include "hw/clock.h" |
9e5e54d1 | 114 | #include "hw/core/split-irq.h" |
7cd3a2e0 | 115 | #include "hw/cpu/cluster.h" |
db1015e9 | 116 | #include "qom/object.h" |
9e5e54d1 | 117 | |
8055340f | 118 | #define TYPE_ARM_SSE "arm-sse" |
c821774a | 119 | OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass, |
30b5707c | 120 | ARM_SSE) |
93dbd103 PM |
121 | |
122 | /* | |
4c3690b5 PM |
123 | * These type names are for specific IoTKit subsystems; other than |
124 | * instantiating them, code using these devices should always handle | |
125 | * them via the ARMSSE base class, so they have no IOTKIT() etc macros. | |
93dbd103 | 126 | */ |
4c3690b5 | 127 | #define TYPE_IOTKIT "iotkit" |
0829d24e | 128 | #define TYPE_SSE200 "sse-200" |
8901bb41 | 129 | #define TYPE_SSE300 "sse-300" |
9e5e54d1 PM |
130 | |
131 | /* We have an IRQ splitter and an OR gate input for each external PPC | |
132 | * and the 2 internal PPCs | |
133 | */ | |
91eb4f64 | 134 | #define NUM_INTERNAL_PPCS 2 |
9e5e54d1 | 135 | #define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC) |
91eb4f64 | 136 | #define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS) |
9e5e54d1 | 137 | |
f0cab7fe PM |
138 | #define MAX_SRAM_BANKS 4 |
139 | #if MAX_SRAM_BANKS > IOTS_NUM_MPC | |
140 | #error Too many SRAM banks | |
141 | #endif | |
142 | ||
91c1e9fc PM |
143 | #define SSE_MAX_CPUS 2 |
144 | ||
6fe8acb4 | 145 | #define NUM_PPUS 8 |
e0b00f1b | 146 | |
33788738 PM |
147 | /* Number of CPU IRQs used by the SSE itself */ |
148 | #define NUM_SSE_IRQS 32 | |
149 | ||
db1015e9 | 150 | struct ARMSSE { |
9e5e54d1 PM |
151 | /*< private >*/ |
152 | SysBusDevice parent_obj; | |
153 | ||
154 | /*< public >*/ | |
91c1e9fc | 155 | ARMv7MState armv7m[SSE_MAX_CPUS]; |
7cd3a2e0 | 156 | CPUClusterState cluster[SSE_MAX_CPUS]; |
9e5e54d1 | 157 | IoTKitSecCtl secctl; |
91eb4f64 | 158 | TZPPC apb_ppc[NUM_INTERNAL_PPCS]; |
f0cab7fe | 159 | TZMPC mpc[IOTS_NUM_MPC]; |
99865afc | 160 | CMSDKAPBTimer timer[3]; |
e844f0c5 | 161 | OrIRQState ppc_irq_orgate; |
9e5e54d1 PM |
162 | SplitIRQ sec_resp_splitter; |
163 | SplitIRQ ppc_irq_splitter[NUM_PPCS]; | |
bb75e16d | 164 | SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; |
e844f0c5 PMD |
165 | OrIRQState mpc_irq_orgate; |
166 | OrIRQState nmi_orgate; | |
9e5e54d1 | 167 | |
33788738 | 168 | SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS]; |
91c1e9fc | 169 | |
017d069d | 170 | CMSDKAPBDualTimer dualtimer; |
9e5e54d1 | 171 | |
1292b932 | 172 | CMSDKAPBWatchdog cmsdk_watchdog[3]; |
d61e4e1f | 173 | |
9febd175 | 174 | SSECounter sse_counter; |
f11de231 | 175 | SSETimer sse_timer[4]; |
9febd175 | 176 | |
06e65af3 PM |
177 | IoTKitSysCtl sysctl; |
178 | IoTKitSysCtl sysinfo; | |
179 | ||
68d6b36f | 180 | ARMSSEMHU mhu[2]; |
a459e849 | 181 | UnimplementedDeviceState unimp[NUM_PPUS]; |
2357bca5 | 182 | UnimplementedDeviceState cachectrl[SSE_MAX_CPUS]; |
c1f57257 | 183 | UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS]; |
f8574705 | 184 | |
ade67dcd PM |
185 | ARMSSECPUID cpuid[SSE_MAX_CPUS]; |
186 | ||
4668b441 PM |
187 | ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS]; |
188 | ||
d847ca51 PM |
189 | /* |
190 | * 'container' holds all devices seen by all CPUs. | |
191 | * 'cpu_container[i]' is the view that CPU i has: this has the | |
192 | * per-CPU devices of that CPU, plus as the background 'container' | |
193 | * (or an alias of it, since we can only use it directly once). | |
194 | * container_alias[i] is the alias of 'container' used by CPU i+1; | |
195 | * CPU 0 can use 'container' directly. | |
196 | */ | |
9e5e54d1 | 197 | MemoryRegion container; |
d847ca51 PM |
198 | MemoryRegion container_alias[SSE_MAX_CPUS - 1]; |
199 | MemoryRegion cpu_container[SSE_MAX_CPUS]; | |
9e5e54d1 PM |
200 | MemoryRegion alias1; |
201 | MemoryRegion alias2; | |
3733f803 | 202 | MemoryRegion alias3[SSE_MAX_CPUS]; |
f0cab7fe | 203 | MemoryRegion sram[MAX_SRAM_BANKS]; |
cbb56388 PM |
204 | MemoryRegion itcm; |
205 | MemoryRegion dtcm; | |
9e5e54d1 | 206 | |
91c1e9fc | 207 | qemu_irq *exp_irqs[SSE_MAX_CPUS]; |
9e5e54d1 PM |
208 | qemu_irq ppc0_irq; |
209 | qemu_irq ppc1_irq; | |
210 | qemu_irq sec_resp_cfg; | |
211 | qemu_irq sec_resp_cfg_in; | |
212 | qemu_irq nsc_cfg_in; | |
213 | ||
214 | qemu_irq irq_status_in[NUM_EXTERNAL_PPCS]; | |
bb75e16d | 215 | qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC]; |
9e5e54d1 PM |
216 | |
217 | uint32_t nsccfg; | |
218 | ||
8fd34dc0 PM |
219 | Clock *mainclk; |
220 | Clock *s32kclk; | |
221 | ||
9e5e54d1 PM |
222 | /* Properties */ |
223 | MemoryRegion *board_memory; | |
224 | uint32_t exp_numirq; | |
4b635cf7 | 225 | uint32_t sram_addr_width; |
32187419 | 226 | uint32_t init_svtor; |
e73b8bb8 PM |
227 | uint32_t cpu_mpu_ns[SSE_MAX_CPUS]; |
228 | uint32_t cpu_mpu_s[SSE_MAX_CPUS]; | |
a90a862b PM |
229 | bool cpu_fpu[SSE_MAX_CPUS]; |
230 | bool cpu_dsp[SSE_MAX_CPUS]; | |
db1015e9 | 231 | }; |
9e5e54d1 | 232 | |
4c3690b5 PM |
233 | typedef struct ARMSSEInfo ARMSSEInfo; |
234 | ||
db1015e9 | 235 | struct ARMSSEClass { |
512c65e6 | 236 | SysBusDeviceClass parent_class; |
4c3690b5 | 237 | const ARMSSEInfo *info; |
db1015e9 | 238 | }; |
4c3690b5 | 239 | |
4c3690b5 | 240 | |
9e5e54d1 | 241 | #endif |