]>
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 | |
9e5e54d1 | 17 | * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html |
0829d24e PM |
18 | * - the SSE-200 which is documented in |
19 | * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf | |
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: | |
40 | * + QOM property "memory" is a MemoryRegion containing the devices provided | |
41 | * by the board model. | |
42 | * + QOM property "MAINCLK" is the frequency of the main system clock | |
91c1e9fc PM |
43 | * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts. |
44 | * (In hardware, the SSE-200 permits the number of expansion interrupts | |
45 | * for the two CPUs to be configured separately, but we restrict it to | |
46 | * being the same for both, to avoid having to have separate Property | |
47 | * lists for different variants. This restriction can be relaxed later | |
48 | * if necessary.) | |
74ecf767 PM |
49 | * + QOM property "SRAM_ADDR_WIDTH" sets the number of bits used for the |
50 | * address of each SRAM bank (and thus the total amount of internal SRAM) | |
32187419 PM |
51 | * + QOM property "init-svtor" sets the initial value of the CPU SVTOR register |
52 | * (where it expects to load the PC and SP from the vector table on reset) | |
a90a862b PM |
53 | * + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which |
54 | * set whether the CPUs have the FPU and DSP features present. The default | |
55 | * (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an | |
56 | * SSE-200 both are present; CPU0 in an SSE-200 has neither. | |
57 | * Since the IoTKit has only one CPU, it does not have the CPU1_* properties. | |
91c1e9fc PM |
58 | * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0, |
59 | * which are wired to its NVIC lines 32 .. n+32 | |
60 | * + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for | |
61 | * CPU 1, which are wired to its NVIC lines 32 .. n+32 | |
132b475a PM |
62 | * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows |
63 | * bus master devices in the board model to make transactions into | |
64 | * all the devices and memory areas in the IoTKit | |
9e5e54d1 PM |
65 | * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit |
66 | * might provide: | |
67 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] | |
68 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15] | |
69 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable | |
70 | * + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear | |
71 | * + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status | |
72 | * Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit | |
73 | * might provide: | |
74 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15] | |
75 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15] | |
76 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable | |
77 | * + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear | |
78 | * + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status | |
bb75e16d PM |
79 | * Controlling each of the 16 expansion MPCs which a system using the IoTKit |
80 | * might provide: | |
81 | * + named GPIO inputs mpcexp_status[0..15] | |
132b475a PM |
82 | * Controlling each of the 16 expansion MSCs which a system using the IoTKit |
83 | * might provide: | |
84 | * + named GPIO inputs mscexp_status[0..15] | |
85 | * + named GPIO outputs mscexp_clear[0..15] | |
86 | * + named GPIO outputs mscexp_ns[0..15] | |
9e5e54d1 PM |
87 | */ |
88 | ||
6eee5d24 PM |
89 | #ifndef ARMSSE_H |
90 | #define ARMSSE_H | |
9e5e54d1 PM |
91 | |
92 | #include "hw/sysbus.h" | |
93 | #include "hw/arm/armv7m.h" | |
94 | #include "hw/misc/iotkit-secctl.h" | |
95 | #include "hw/misc/tz-ppc.h" | |
af60b291 | 96 | #include "hw/misc/tz-mpc.h" |
9e5e54d1 | 97 | #include "hw/timer/cmsdk-apb-timer.h" |
017d069d | 98 | #include "hw/timer/cmsdk-apb-dualtimer.h" |
d61e4e1f | 99 | #include "hw/watchdog/cmsdk-apb-watchdog.h" |
06e65af3 PM |
100 | #include "hw/misc/iotkit-sysctl.h" |
101 | #include "hw/misc/iotkit-sysinfo.h" | |
ade67dcd | 102 | #include "hw/misc/armsse-cpuid.h" |
68d6b36f | 103 | #include "hw/misc/armsse-mhu.h" |
f8574705 | 104 | #include "hw/misc/unimp.h" |
9e5e54d1 PM |
105 | #include "hw/or-irq.h" |
106 | #include "hw/core/split-irq.h" | |
7cd3a2e0 | 107 | #include "hw/cpu/cluster.h" |
db1015e9 | 108 | #include "qom/object.h" |
9e5e54d1 | 109 | |
8055340f | 110 | #define TYPE_ARM_SSE "arm-sse" |
db1015e9 EH |
111 | typedef struct ARMSSE ARMSSE; |
112 | typedef struct ARMSSEClass ARMSSEClass; | |
8110fa1d EH |
113 | DECLARE_OBJ_CHECKERS(ARMSSE, ARMSSEClass, |
114 | ARM_SSE, TYPE_ARM_SSE) | |
93dbd103 PM |
115 | |
116 | /* | |
4c3690b5 PM |
117 | * These type names are for specific IoTKit subsystems; other than |
118 | * instantiating them, code using these devices should always handle | |
119 | * them via the ARMSSE base class, so they have no IOTKIT() etc macros. | |
93dbd103 | 120 | */ |
4c3690b5 | 121 | #define TYPE_IOTKIT "iotkit" |
0829d24e | 122 | #define TYPE_SSE200 "sse-200" |
9e5e54d1 PM |
123 | |
124 | /* We have an IRQ splitter and an OR gate input for each external PPC | |
125 | * and the 2 internal PPCs | |
126 | */ | |
127 | #define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC) | |
128 | #define NUM_PPCS (NUM_EXTERNAL_PPCS + 2) | |
129 | ||
f0cab7fe PM |
130 | #define MAX_SRAM_BANKS 4 |
131 | #if MAX_SRAM_BANKS > IOTS_NUM_MPC | |
132 | #error Too many SRAM banks | |
133 | #endif | |
134 | ||
91c1e9fc PM |
135 | #define SSE_MAX_CPUS 2 |
136 | ||
e0b00f1b PM |
137 | /* These define what each PPU in the ppu[] index is for */ |
138 | #define CPU0CORE_PPU 0 | |
139 | #define CPU1CORE_PPU 1 | |
140 | #define DBG_PPU 2 | |
141 | #define RAM0_PPU 3 | |
142 | #define RAM1_PPU 4 | |
143 | #define RAM2_PPU 5 | |
144 | #define RAM3_PPU 6 | |
145 | #define NUM_PPUS 7 | |
146 | ||
db1015e9 | 147 | struct ARMSSE { |
9e5e54d1 PM |
148 | /*< private >*/ |
149 | SysBusDevice parent_obj; | |
150 | ||
151 | /*< public >*/ | |
91c1e9fc | 152 | ARMv7MState armv7m[SSE_MAX_CPUS]; |
7cd3a2e0 | 153 | CPUClusterState cluster[SSE_MAX_CPUS]; |
9e5e54d1 PM |
154 | IoTKitSecCtl secctl; |
155 | TZPPC apb_ppc0; | |
156 | TZPPC apb_ppc1; | |
f0cab7fe | 157 | TZMPC mpc[IOTS_NUM_MPC]; |
9e5e54d1 PM |
158 | CMSDKAPBTIMER timer0; |
159 | CMSDKAPBTIMER timer1; | |
e2d203ba | 160 | CMSDKAPBTIMER s32ktimer; |
9e5e54d1 PM |
161 | qemu_or_irq ppc_irq_orgate; |
162 | SplitIRQ sec_resp_splitter; | |
163 | SplitIRQ ppc_irq_splitter[NUM_PPCS]; | |
bb75e16d PM |
164 | SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; |
165 | qemu_or_irq mpc_irq_orgate; | |
d61e4e1f | 166 | qemu_or_irq nmi_orgate; |
9e5e54d1 | 167 | |
91c1e9fc PM |
168 | SplitIRQ cpu_irq_splitter[32]; |
169 | ||
017d069d | 170 | CMSDKAPBDualTimer dualtimer; |
9e5e54d1 | 171 | |
d61e4e1f PM |
172 | CMSDKAPBWatchdog s32kwatchdog; |
173 | CMSDKAPBWatchdog nswatchdog; | |
174 | CMSDKAPBWatchdog swatchdog; | |
175 | ||
06e65af3 PM |
176 | IoTKitSysCtl sysctl; |
177 | IoTKitSysCtl sysinfo; | |
178 | ||
68d6b36f | 179 | ARMSSEMHU mhu[2]; |
e0b00f1b | 180 | UnimplementedDeviceState ppu[NUM_PPUS]; |
2357bca5 | 181 | UnimplementedDeviceState cachectrl[SSE_MAX_CPUS]; |
c1f57257 | 182 | UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS]; |
f8574705 | 183 | |
ade67dcd PM |
184 | ARMSSECPUID cpuid[SSE_MAX_CPUS]; |
185 | ||
d847ca51 PM |
186 | /* |
187 | * 'container' holds all devices seen by all CPUs. | |
188 | * 'cpu_container[i]' is the view that CPU i has: this has the | |
189 | * per-CPU devices of that CPU, plus as the background 'container' | |
190 | * (or an alias of it, since we can only use it directly once). | |
191 | * container_alias[i] is the alias of 'container' used by CPU i+1; | |
192 | * CPU 0 can use 'container' directly. | |
193 | */ | |
9e5e54d1 | 194 | MemoryRegion container; |
d847ca51 PM |
195 | MemoryRegion container_alias[SSE_MAX_CPUS - 1]; |
196 | MemoryRegion cpu_container[SSE_MAX_CPUS]; | |
9e5e54d1 PM |
197 | MemoryRegion alias1; |
198 | MemoryRegion alias2; | |
3733f803 | 199 | MemoryRegion alias3[SSE_MAX_CPUS]; |
f0cab7fe | 200 | MemoryRegion sram[MAX_SRAM_BANKS]; |
9e5e54d1 | 201 | |
91c1e9fc | 202 | qemu_irq *exp_irqs[SSE_MAX_CPUS]; |
9e5e54d1 PM |
203 | qemu_irq ppc0_irq; |
204 | qemu_irq ppc1_irq; | |
205 | qemu_irq sec_resp_cfg; | |
206 | qemu_irq sec_resp_cfg_in; | |
207 | qemu_irq nsc_cfg_in; | |
208 | ||
209 | qemu_irq irq_status_in[NUM_EXTERNAL_PPCS]; | |
bb75e16d | 210 | qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC]; |
9e5e54d1 PM |
211 | |
212 | uint32_t nsccfg; | |
213 | ||
214 | /* Properties */ | |
215 | MemoryRegion *board_memory; | |
216 | uint32_t exp_numirq; | |
217 | uint32_t mainclk_frq; | |
4b635cf7 | 218 | uint32_t sram_addr_width; |
32187419 | 219 | uint32_t init_svtor; |
a90a862b PM |
220 | bool cpu_fpu[SSE_MAX_CPUS]; |
221 | bool cpu_dsp[SSE_MAX_CPUS]; | |
db1015e9 | 222 | }; |
9e5e54d1 | 223 | |
4c3690b5 PM |
224 | typedef struct ARMSSEInfo ARMSSEInfo; |
225 | ||
db1015e9 | 226 | struct ARMSSEClass { |
512c65e6 | 227 | SysBusDeviceClass parent_class; |
4c3690b5 | 228 | const ARMSSEInfo *info; |
db1015e9 | 229 | }; |
4c3690b5 | 230 | |
4c3690b5 | 231 | |
9e5e54d1 | 232 | #endif |