2018-03-02 11:45:40 +01:00
|
|
|
/*
|
2019-02-01 15:55:43 +01:00
|
|
|
* ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
|
2018-03-02 11:45:40 +01:00
|
|
|
*
|
|
|
|
* Copyright (c) 2018 Linaro Limited
|
|
|
|
* Written by Peter Maydell
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License version 2 or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*/
|
|
|
|
|
2019-02-01 15:55:41 +01:00
|
|
|
/*
|
|
|
|
* This is a model of the Arm "Subsystems for Embedded" family of
|
|
|
|
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
|
2019-02-01 15:55:43 +01:00
|
|
|
* SSE-200. Currently we model:
|
|
|
|
* - the Arm IoT Kit which is documented in
|
2021-02-15 12:51:38 +01:00
|
|
|
* https://developer.arm.com/documentation/ecm0601256/latest
|
2019-02-01 15:55:43 +01:00
|
|
|
* - the SSE-200 which is documented in
|
2021-02-15 12:51:38 +01:00
|
|
|
* https://developer.arm.com/documentation/101104/latest/
|
2019-02-01 15:55:43 +01:00
|
|
|
*
|
|
|
|
* The IoTKit contains:
|
2018-03-02 11:45:40 +01:00
|
|
|
* a Cortex-M33
|
|
|
|
* the IDAU
|
|
|
|
* some timers and watchdogs
|
|
|
|
* two peripheral protection controllers
|
|
|
|
* a memory protection controller
|
|
|
|
* a security controller
|
|
|
|
* a bus fabric which arranges that some parts of the address
|
|
|
|
* space are secure and non-secure aliases of each other
|
2019-02-01 15:55:43 +01:00
|
|
|
* The SSE-200 additionally contains:
|
|
|
|
* a second Cortex-M33
|
|
|
|
* two Message Handling Units (MHUs)
|
|
|
|
* an optional CryptoCell (which we do not model)
|
|
|
|
* more SRAM banks with associated MPCs
|
|
|
|
* multiple Power Policy Units (PPUs)
|
|
|
|
* a control interface for an icache for each CPU
|
|
|
|
* per-CPU identity and control register blocks
|
2018-03-02 11:45:40 +01:00
|
|
|
*
|
|
|
|
* QEMU interface:
|
2021-01-28 12:41:31 +01:00
|
|
|
* + Clock input "MAINCLK": clock for CPUs and most peripherals
|
|
|
|
* + Clock input "S32KCLK": slow 32KHz clock used for a few peripherals
|
2018-03-02 11:45:40 +01:00
|
|
|
* + QOM property "memory" is a MemoryRegion containing the devices provided
|
|
|
|
* by the board model.
|
2019-02-01 15:55:42 +01:00
|
|
|
* + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
|
|
|
|
* (In hardware, the SSE-200 permits the number of expansion interrupts
|
|
|
|
* for the two CPUs to be configured separately, but we restrict it to
|
|
|
|
* being the same for both, to avoid having to have separate Property
|
|
|
|
* lists for different variants. This restriction can be relaxed later
|
|
|
|
* if necessary.)
|
2019-02-21 19:17:47 +01:00
|
|
|
* + QOM property "SRAM_ADDR_WIDTH" sets the number of bits used for the
|
|
|
|
* address of each SRAM bank (and thus the total amount of internal SRAM)
|
2019-02-21 19:17:47 +01:00
|
|
|
* + QOM property "init-svtor" sets the initial value of the CPU SVTOR register
|
|
|
|
* (where it expects to load the PC and SP from the vector table on reset)
|
2019-05-17 19:40:46 +02:00
|
|
|
* + QOM properties "CPU0_FPU", "CPU0_DSP", "CPU1_FPU" and "CPU1_DSP" which
|
|
|
|
* set whether the CPUs have the FPU and DSP features present. The default
|
|
|
|
* (matching the hardware) is that for CPU0 in an IoTKit and CPU1 in an
|
|
|
|
* SSE-200 both are present; CPU0 in an SSE-200 has neither.
|
|
|
|
* Since the IoTKit has only one CPU, it does not have the CPU1_* properties.
|
2019-02-01 15:55:42 +01:00
|
|
|
* + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
|
|
|
|
* which are wired to its NVIC lines 32 .. n+32
|
|
|
|
* + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
|
|
|
|
* CPU 1, which are wired to its NVIC lines 32 .. n+32
|
2018-08-24 14:17:44 +02:00
|
|
|
* + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows
|
|
|
|
* bus master devices in the board model to make transactions into
|
|
|
|
* all the devices and memory areas in the IoTKit
|
2018-03-02 11:45:40 +01:00
|
|
|
* Controlling up to 4 AHB expansion PPBs which a system using the IoTKit
|
|
|
|
* might provide:
|
|
|
|
* + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15]
|
|
|
|
* + named GPIO outputs apb_ppcexp{0,1,2,3}_ap[0..15]
|
|
|
|
* + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_enable
|
|
|
|
* + named GPIO outputs apb_ppcexp{0,1,2,3}_irq_clear
|
|
|
|
* + named GPIO inputs apb_ppcexp{0,1,2,3}_irq_status
|
|
|
|
* Controlling each of the 4 expansion AHB PPCs which a system using the IoTKit
|
|
|
|
* might provide:
|
|
|
|
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_nonsec[0..15]
|
|
|
|
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_ap[0..15]
|
|
|
|
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
|
|
|
|
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
|
|
|
|
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
|
2018-06-22 14:28:40 +02:00
|
|
|
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
|
|
|
|
* might provide:
|
|
|
|
* + named GPIO inputs mpcexp_status[0..15]
|
2018-08-24 14:17:44 +02:00
|
|
|
* Controlling each of the 16 expansion MSCs which a system using the IoTKit
|
|
|
|
* might provide:
|
|
|
|
* + named GPIO inputs mscexp_status[0..15]
|
|
|
|
* + named GPIO outputs mscexp_clear[0..15]
|
|
|
|
* + named GPIO outputs mscexp_ns[0..15]
|
2018-03-02 11:45:40 +01:00
|
|
|
*/
|
|
|
|
|
2019-02-01 15:55:42 +01:00
|
|
|
#ifndef ARMSSE_H
|
|
|
|
#define ARMSSE_H
|
2018-03-02 11:45:40 +01:00
|
|
|
|
|
|
|
#include "hw/sysbus.h"
|
|
|
|
#include "hw/arm/armv7m.h"
|
|
|
|
#include "hw/misc/iotkit-secctl.h"
|
|
|
|
#include "hw/misc/tz-ppc.h"
|
2018-06-22 14:28:40 +02:00
|
|
|
#include "hw/misc/tz-mpc.h"
|
2018-03-02 11:45:40 +01:00
|
|
|
#include "hw/timer/cmsdk-apb-timer.h"
|
2018-08-24 14:17:41 +02:00
|
|
|
#include "hw/timer/cmsdk-apb-dualtimer.h"
|
2021-02-19 15:46:05 +01:00
|
|
|
#include "hw/timer/sse-counter.h"
|
2021-02-19 15:46:06 +01:00
|
|
|
#include "hw/timer/sse-timer.h"
|
2018-08-24 14:17:42 +02:00
|
|
|
#include "hw/watchdog/cmsdk-apb-watchdog.h"
|
2018-08-24 14:17:43 +02:00
|
|
|
#include "hw/misc/iotkit-sysctl.h"
|
|
|
|
#include "hw/misc/iotkit-sysinfo.h"
|
2019-02-01 15:55:43 +01:00
|
|
|
#include "hw/misc/armsse-cpuid.h"
|
2019-02-28 11:55:15 +01:00
|
|
|
#include "hw/misc/armsse-mhu.h"
|
2021-02-19 15:46:07 +01:00
|
|
|
#include "hw/misc/armsse-cpu-pwrctrl.h"
|
2019-02-01 15:55:43 +01:00
|
|
|
#include "hw/misc/unimp.h"
|
2018-03-02 11:45:40 +01:00
|
|
|
#include "hw/or-irq.h"
|
2021-01-28 12:41:31 +01:00
|
|
|
#include "hw/clock.h"
|
2018-03-02 11:45:40 +01:00
|
|
|
#include "hw/core/split-irq.h"
|
2019-02-01 15:55:42 +01:00
|
|
|
#include "hw/cpu/cluster.h"
|
2020-09-03 22:43:22 +02:00
|
|
|
#include "qom/object.h"
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2020-08-25 21:20:21 +02:00
|
|
|
#define TYPE_ARM_SSE "arm-sse"
|
2020-08-31 23:07:37 +02:00
|
|
|
OBJECT_DECLARE_TYPE(ARMSSE, ARMSSEClass,
|
qom: Remove module_obj_name parameter from OBJECT_DECLARE* macros
One of the goals of having less boilerplate on QOM declarations
is to avoid human error. Requiring an extra argument that is
never used is an opportunity for mistakes.
Remove the unused argument from OBJECT_DECLARE_TYPE and
OBJECT_DECLARE_SIMPLE_TYPE.
Coccinelle patch used to convert all users of the macros:
@@
declarer name OBJECT_DECLARE_TYPE;
identifier InstanceType, ClassType, lowercase, UPPERCASE;
@@
OBJECT_DECLARE_TYPE(InstanceType, ClassType,
- lowercase,
UPPERCASE);
@@
declarer name OBJECT_DECLARE_SIMPLE_TYPE;
identifier InstanceType, lowercase, UPPERCASE;
@@
OBJECT_DECLARE_SIMPLE_TYPE(InstanceType,
- lowercase,
UPPERCASE);
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Acked-by: Cornelia Huck <cohuck@redhat.com>
Acked-by: Igor Mammedov <imammedo@redhat.com>
Acked-by: Paul Durrant <paul@xen.org>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20200916182519.415636-4-ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
2020-09-16 20:25:17 +02:00
|
|
|
ARM_SSE)
|
2019-02-01 15:55:41 +01:00
|
|
|
|
|
|
|
/*
|
2019-02-01 15:55:41 +01:00
|
|
|
* These type names are for specific IoTKit subsystems; other than
|
|
|
|
* instantiating them, code using these devices should always handle
|
|
|
|
* them via the ARMSSE base class, so they have no IOTKIT() etc macros.
|
2019-02-01 15:55:41 +01:00
|
|
|
*/
|
2019-02-01 15:55:41 +01:00
|
|
|
#define TYPE_IOTKIT "iotkit"
|
2019-02-01 15:55:43 +01:00
|
|
|
#define TYPE_SSE200 "sse-200"
|
2021-02-19 15:46:08 +01:00
|
|
|
#define TYPE_SSE300 "sse-300"
|
2018-03-02 11:45:40 +01:00
|
|
|
|
|
|
|
/* We have an IRQ splitter and an OR gate input for each external PPC
|
|
|
|
* and the 2 internal PPCs
|
|
|
|
*/
|
2021-02-19 15:45:54 +01:00
|
|
|
#define NUM_INTERNAL_PPCS 2
|
2018-03-02 11:45:40 +01:00
|
|
|
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
|
2021-02-19 15:45:54 +01:00
|
|
|
#define NUM_PPCS (NUM_EXTERNAL_PPCS + NUM_INTERNAL_PPCS)
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2019-02-01 15:55:42 +01:00
|
|
|
#define MAX_SRAM_BANKS 4
|
|
|
|
#if MAX_SRAM_BANKS > IOTS_NUM_MPC
|
|
|
|
#error Too many SRAM banks
|
|
|
|
#endif
|
|
|
|
|
2019-02-01 15:55:42 +01:00
|
|
|
#define SSE_MAX_CPUS 2
|
|
|
|
|
2021-02-19 15:46:03 +01:00
|
|
|
#define NUM_PPUS 8
|
2019-02-01 15:55:43 +01:00
|
|
|
|
2021-02-19 15:45:55 +01:00
|
|
|
/* Number of CPU IRQs used by the SSE itself */
|
|
|
|
#define NUM_SSE_IRQS 32
|
|
|
|
|
2020-09-03 22:43:22 +02:00
|
|
|
struct ARMSSE {
|
2018-03-02 11:45:40 +01:00
|
|
|
/*< private >*/
|
|
|
|
SysBusDevice parent_obj;
|
|
|
|
|
|
|
|
/*< public >*/
|
2019-02-01 15:55:42 +01:00
|
|
|
ARMv7MState armv7m[SSE_MAX_CPUS];
|
2019-02-01 15:55:42 +01:00
|
|
|
CPUClusterState cluster[SSE_MAX_CPUS];
|
2018-03-02 11:45:40 +01:00
|
|
|
IoTKitSecCtl secctl;
|
2021-02-19 15:45:54 +01:00
|
|
|
TZPPC apb_ppc[NUM_INTERNAL_PPCS];
|
2019-02-01 15:55:42 +01:00
|
|
|
TZMPC mpc[IOTS_NUM_MPC];
|
2021-02-19 15:45:59 +01:00
|
|
|
CMSDKAPBTimer timer[3];
|
2023-01-13 21:01:38 +01:00
|
|
|
OrIRQState ppc_irq_orgate;
|
2018-03-02 11:45:40 +01:00
|
|
|
SplitIRQ sec_resp_splitter;
|
|
|
|
SplitIRQ ppc_irq_splitter[NUM_PPCS];
|
2018-06-22 14:28:40 +02:00
|
|
|
SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
|
2023-01-13 21:01:38 +01:00
|
|
|
OrIRQState mpc_irq_orgate;
|
|
|
|
OrIRQState nmi_orgate;
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2021-02-19 15:45:55 +01:00
|
|
|
SplitIRQ cpu_irq_splitter[NUM_SSE_IRQS];
|
2019-02-01 15:55:42 +01:00
|
|
|
|
2018-08-24 14:17:41 +02:00
|
|
|
CMSDKAPBDualTimer dualtimer;
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2021-02-19 15:45:58 +01:00
|
|
|
CMSDKAPBWatchdog cmsdk_watchdog[3];
|
2018-08-24 14:17:42 +02:00
|
|
|
|
2021-02-19 15:46:05 +01:00
|
|
|
SSECounter sse_counter;
|
2021-02-19 15:46:06 +01:00
|
|
|
SSETimer sse_timer[4];
|
2021-02-19 15:46:05 +01:00
|
|
|
|
2018-08-24 14:17:43 +02:00
|
|
|
IoTKitSysCtl sysctl;
|
|
|
|
IoTKitSysCtl sysinfo;
|
|
|
|
|
2019-02-28 11:55:15 +01:00
|
|
|
ARMSSEMHU mhu[2];
|
2021-02-19 15:46:02 +01:00
|
|
|
UnimplementedDeviceState unimp[NUM_PPUS];
|
2019-02-01 15:55:43 +01:00
|
|
|
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
|
2019-02-01 15:55:43 +01:00
|
|
|
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
|
2019-02-01 15:55:43 +01:00
|
|
|
|
2019-02-01 15:55:43 +01:00
|
|
|
ARMSSECPUID cpuid[SSE_MAX_CPUS];
|
|
|
|
|
2021-02-19 15:46:07 +01:00
|
|
|
ARMSSECPUPwrCtrl cpu_pwrctrl[SSE_MAX_CPUS];
|
|
|
|
|
2019-02-01 15:55:42 +01:00
|
|
|
/*
|
|
|
|
* 'container' holds all devices seen by all CPUs.
|
|
|
|
* 'cpu_container[i]' is the view that CPU i has: this has the
|
|
|
|
* per-CPU devices of that CPU, plus as the background 'container'
|
|
|
|
* (or an alias of it, since we can only use it directly once).
|
|
|
|
* container_alias[i] is the alias of 'container' used by CPU i+1;
|
|
|
|
* CPU 0 can use 'container' directly.
|
|
|
|
*/
|
2018-03-02 11:45:40 +01:00
|
|
|
MemoryRegion container;
|
2019-02-01 15:55:42 +01:00
|
|
|
MemoryRegion container_alias[SSE_MAX_CPUS - 1];
|
|
|
|
MemoryRegion cpu_container[SSE_MAX_CPUS];
|
2018-03-02 11:45:40 +01:00
|
|
|
MemoryRegion alias1;
|
|
|
|
MemoryRegion alias2;
|
2019-02-21 19:17:48 +01:00
|
|
|
MemoryRegion alias3[SSE_MAX_CPUS];
|
2019-02-01 15:55:42 +01:00
|
|
|
MemoryRegion sram[MAX_SRAM_BANKS];
|
2021-05-10 21:08:44 +02:00
|
|
|
MemoryRegion itcm;
|
|
|
|
MemoryRegion dtcm;
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2019-02-01 15:55:42 +01:00
|
|
|
qemu_irq *exp_irqs[SSE_MAX_CPUS];
|
2018-03-02 11:45:40 +01:00
|
|
|
qemu_irq ppc0_irq;
|
|
|
|
qemu_irq ppc1_irq;
|
|
|
|
qemu_irq sec_resp_cfg;
|
|
|
|
qemu_irq sec_resp_cfg_in;
|
|
|
|
qemu_irq nsc_cfg_in;
|
|
|
|
|
|
|
|
qemu_irq irq_status_in[NUM_EXTERNAL_PPCS];
|
2018-06-22 14:28:40 +02:00
|
|
|
qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC];
|
2018-03-02 11:45:40 +01:00
|
|
|
|
|
|
|
uint32_t nsccfg;
|
|
|
|
|
2021-01-28 12:41:31 +01:00
|
|
|
Clock *mainclk;
|
|
|
|
Clock *s32kclk;
|
|
|
|
|
2018-03-02 11:45:40 +01:00
|
|
|
/* Properties */
|
|
|
|
MemoryRegion *board_memory;
|
|
|
|
uint32_t exp_numirq;
|
2019-02-01 15:55:42 +01:00
|
|
|
uint32_t sram_addr_width;
|
2019-02-21 19:17:47 +01:00
|
|
|
uint32_t init_svtor;
|
2019-05-17 19:40:46 +02:00
|
|
|
bool cpu_fpu[SSE_MAX_CPUS];
|
|
|
|
bool cpu_dsp[SSE_MAX_CPUS];
|
2020-09-03 22:43:22 +02:00
|
|
|
};
|
2018-03-02 11:45:40 +01:00
|
|
|
|
2019-02-01 15:55:41 +01:00
|
|
|
typedef struct ARMSSEInfo ARMSSEInfo;
|
|
|
|
|
2020-09-03 22:43:22 +02:00
|
|
|
struct ARMSSEClass {
|
2020-08-28 11:02:47 +02:00
|
|
|
SysBusDeviceClass parent_class;
|
2019-02-01 15:55:41 +01:00
|
|
|
const ARMSSEInfo *info;
|
2020-09-03 22:43:22 +02:00
|
|
|
};
|
2019-02-01 15:55:41 +01:00
|
|
|
|
|
|
|
|
2018-03-02 11:45:40 +01:00
|
|
|
#endif
|