summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPeter Maydell2019-02-01 17:39:17 +0100
committerPeter Maydell2019-02-01 17:39:17 +0100
commite83d74286cad2b9b967e1ba0ce5c8d16cba9679f (patch)
treebd57034a1550568ec8f9d6aa4457fd38531e9c17 /include
parentMerge remote-tracking branch 'remotes/kraxel/tags/ui-20190201-pull-request' i... (diff)
parenttests/microbit-test: Add tests for nRF51 NVMC (diff)
downloadqemu-e83d74286cad2b9b967e1ba0ce5c8d16cba9679f.tar.gz
qemu-e83d74286cad2b9b967e1ba0ce5c8d16cba9679f.tar.xz
qemu-e83d74286cad2b9b967e1ba0ce5c8d16cba9679f.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190201' into staging
target-arm queue: * New machine mps2-an521 -- this is a model of the AN521 FPGA image for the MPS2 devboard * Fix various places where we failed to UNDEF invalid A64 instructions * Don't UNDEF a valid FCMLA on 32-bit inputs * Fix some bugs in the newly-added PAuth implementation * microbit: Implement NVMC non-volatile memory controller # gpg: Signature made Fri 01 Feb 2019 16:06:03 GMT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20190201: (47 commits) tests/microbit-test: Add tests for nRF51 NVMC arm: Instantiate NRF51 special NVM's and NVMC hw/nvram/nrf51_nvm: Add nRF51 non-volatile memories target/arm: fix decoding of B{,L}RA{A,B} target/arm: fix AArch64 virtual address space size linux-user: Initialize aarch64 pac keys aarch64-linux-user: Enable HWCAP bits for PAuth aarch64-linux-user: Update HWCAP bits from linux 5.0-rc1 target/arm: Always enable pac keys for user-only arm: Clarify the logic of set_pc() target/arm: Enable API, APK bits in SCR, HCR target/arm: Add a timer to predict PMU counter overflow target/arm: Send interrupts on PMU counter overflow target/arm/translate-a64: Fix mishandling of size in FCMLA decode target/arm/translate-a64: Fix FCMLA decoding error exec.c: Don't reallocate IOMMUNotifiers that are in use target/arm/translate-a64: Don't underdecode SDOT and UDOT target/arm/translate-a64: Don't underdecode FP insns target/arm/translate-a64: Don't underdecode add/sub extended register target/arm/translate-a64: Don't underdecode SIMD ld/st single ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include')
-rw-r--r--include/hw/arm/armsse.h (renamed from include/hw/arm/iotkit.h)113
-rw-r--r--include/hw/arm/armv7m.h1
-rw-r--r--include/hw/arm/nrf51_soc.h2
-rw-r--r--include/hw/misc/armsse-cpuid.h41
-rw-r--r--include/hw/misc/iotkit-secctl.h6
-rw-r--r--include/hw/misc/iotkit-sysinfo.h6
-rw-r--r--include/hw/nvram/nrf51_nvm.h64
-rw-r--r--include/qom/cpu.h16
8 files changed, 229 insertions, 20 deletions
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/armsse.h
index 3a8ee63908..f800bafb14 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/armsse.h
@@ -1,5 +1,5 @@
/*
- * ARM IoT Kit
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
*
* Copyright (c) 2018 Linaro Limited
* Written by Peter Maydell
@@ -9,9 +9,16 @@
* (at your option) any later version.
*/
-/* This is a model of the Arm IoT Kit which is documented in
+/*
+ * 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
+ * SSE-200. Currently we model:
+ * - the Arm IoT Kit which is documented in
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
- * It contains:
+ * - the SSE-200 which is documented in
+ * 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
+ *
+ * The IoTKit contains:
* a Cortex-M33
* the IDAU
* some timers and watchdogs
@@ -20,14 +27,29 @@
* a security controller
* a bus fabric which arranges that some parts of the address
* space are secure and non-secure aliases of each other
+ * 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
*
* QEMU interface:
* + QOM property "memory" is a MemoryRegion containing the devices provided
* by the board model.
* + QOM property "MAINCLK" is the frequency of the main system clock
- * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts
- * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which
- * are wired to the NVIC lines 32 .. n+32
+ * + 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.)
+ * + 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
* + 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
@@ -55,8 +77,8 @@
* + named GPIO outputs mscexp_ns[0..15]
*/
-#ifndef IOTKIT_H
-#define IOTKIT_H
+#ifndef ARMSSE_H
+#define ARMSSE_H
#include "hw/sysbus.h"
#include "hw/arm/armv7m.h"
@@ -68,11 +90,22 @@
#include "hw/watchdog/cmsdk-apb-watchdog.h"
#include "hw/misc/iotkit-sysctl.h"
#include "hw/misc/iotkit-sysinfo.h"
+#include "hw/misc/armsse-cpuid.h"
+#include "hw/misc/unimp.h"
#include "hw/or-irq.h"
#include "hw/core/split-irq.h"
+#include "hw/cpu/cluster.h"
+#define TYPE_ARMSSE "arm-sse"
+#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
+
+/*
+ * 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.
+ */
#define TYPE_IOTKIT "iotkit"
-#define IOTKIT(obj) OBJECT_CHECK(IoTKit, (obj), TYPE_IOTKIT)
+#define TYPE_SSE200 "sse-200"
/* We have an IRQ splitter and an OR gate input for each external PPC
* and the 2 internal PPCs
@@ -80,16 +113,34 @@
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
-typedef struct IoTKit {
+#define MAX_SRAM_BANKS 4
+#if MAX_SRAM_BANKS > IOTS_NUM_MPC
+#error Too many SRAM banks
+#endif
+
+#define SSE_MAX_CPUS 2
+
+/* These define what each PPU in the ppu[] index is for */
+#define CPU0CORE_PPU 0
+#define CPU1CORE_PPU 1
+#define DBG_PPU 2
+#define RAM0_PPU 3
+#define RAM1_PPU 4
+#define RAM2_PPU 5
+#define RAM3_PPU 6
+#define NUM_PPUS 7
+
+typedef struct ARMSSE {
/*< private >*/
SysBusDevice parent_obj;
/*< public >*/
- ARMv7MState armv7m;
+ ARMv7MState armv7m[SSE_MAX_CPUS];
+ CPUClusterState cluster[SSE_MAX_CPUS];
IoTKitSecCtl secctl;
TZPPC apb_ppc0;
TZPPC apb_ppc1;
- TZMPC mpc;
+ TZMPC mpc[IOTS_NUM_MPC];
CMSDKAPBTIMER timer0;
CMSDKAPBTIMER timer1;
CMSDKAPBTIMER s32ktimer;
@@ -100,6 +151,8 @@ typedef struct IoTKit {
qemu_or_irq mpc_irq_orgate;
qemu_or_irq nmi_orgate;
+ SplitIRQ cpu_irq_splitter[32];
+
CMSDKAPBDualTimer dualtimer;
CMSDKAPBWatchdog s32kwatchdog;
@@ -109,13 +162,30 @@ typedef struct IoTKit {
IoTKitSysCtl sysctl;
IoTKitSysCtl sysinfo;
+ UnimplementedDeviceState mhu[2];
+ UnimplementedDeviceState ppu[NUM_PPUS];
+ UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
+ UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
+
+ ARMSSECPUID cpuid[SSE_MAX_CPUS];
+
+ /*
+ * '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.
+ */
MemoryRegion container;
+ MemoryRegion container_alias[SSE_MAX_CPUS - 1];
+ MemoryRegion cpu_container[SSE_MAX_CPUS];
MemoryRegion alias1;
MemoryRegion alias2;
MemoryRegion alias3;
- MemoryRegion sram0;
+ MemoryRegion sram[MAX_SRAM_BANKS];
- qemu_irq *exp_irqs;
+ qemu_irq *exp_irqs[SSE_MAX_CPUS];
qemu_irq ppc0_irq;
qemu_irq ppc1_irq;
qemu_irq sec_resp_cfg;
@@ -131,6 +201,19 @@ typedef struct IoTKit {
MemoryRegion *board_memory;
uint32_t exp_numirq;
uint32_t mainclk_frq;
-} IoTKit;
+ uint32_t sram_addr_width;
+} ARMSSE;
+
+typedef struct ARMSSEInfo ARMSSEInfo;
+
+typedef struct ARMSSEClass {
+ DeviceClass parent_class;
+ const ARMSSEInfo *info;
+} ARMSSEClass;
+
+#define ARMSSE_CLASS(klass) \
+ OBJECT_CLASS_CHECK(ARMSSEClass, (klass), TYPE_ARMSSE)
+#define ARMSSE_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(ARMSSEClass, (obj), TYPE_ARMSSE)
#endif
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
index 2ba24953b6..e96a98f809 100644
--- a/include/hw/arm/armv7m.h
+++ b/include/hw/arm/armv7m.h
@@ -65,6 +65,7 @@ typedef struct ARMv7MState {
Object *idau;
uint32_t init_svtor;
bool enable_bitband;
+ bool start_powered_off;
} ARMv7MState;
#endif
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
index fbdefc07e4..fd7fcc71a5 100644
--- a/include/hw/arm/nrf51_soc.h
+++ b/include/hw/arm/nrf51_soc.h
@@ -15,6 +15,7 @@
#include "hw/char/nrf51_uart.h"
#include "hw/misc/nrf51_rng.h"
#include "hw/gpio/nrf51_gpio.h"
+#include "hw/nvram/nrf51_nvm.h"
#include "hw/timer/nrf51_timer.h"
#define TYPE_NRF51_SOC "nrf51-soc"
@@ -32,6 +33,7 @@ typedef struct NRF51State {
NRF51UARTState uart;
NRF51RNGState rng;
+ NRF51NVMState nvm;
NRF51GPIOState gpio;
NRF51TimerState timer[NRF51_NUM_TIMERS];
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
new file mode 100644
index 0000000000..0ef33fcaba
--- /dev/null
+++ b/include/hw/misc/armsse-cpuid.h
@@ -0,0 +1,41 @@
+/*
+ * ARM SSE-200 CPU_IDENTITY register block
+ *
+ * Copyright (c) 2019 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.
+ */
+
+/*
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
+ * Arm SSE-200 and documented in
+ * 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
+ *
+ * QEMU interface:
+ * + QOM property "CPUID": the value to use for the CPUID register
+ * + sysbus MMIO region 0: the system information register bank
+ */
+
+#ifndef HW_MISC_ARMSSE_CPUID_H
+#define HW_MISC_ARMSSE_CPUID_H
+
+#include "hw/sysbus.h"
+
+#define TYPE_ARMSSE_CPUID "armsse-cpuid"
+#define ARMSSE_CPUID(obj) OBJECT_CHECK(ARMSSECPUID, (obj), TYPE_ARMSSE_CPUID)
+
+typedef struct ARMSSECPUID {
+ /*< private >*/
+ SysBusDevice parent_obj;
+
+ /*< public >*/
+ MemoryRegion iomem;
+
+ /* Properties */
+ uint32_t cpuid;
+} ARMSSECPUID;
+
+#endif
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
index 1a193b306f..bcb0437be5 100644
--- a/include/hw/misc/iotkit-secctl.h
+++ b/include/hw/misc/iotkit-secctl.h
@@ -40,8 +40,8 @@
* + 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
- * Controlling the MPC in the IoTKit:
- * + named GPIO input mpc_status
+ * Controlling the (up to) 4 MPCs in the IoTKit/SSE:
+ * + named GPIO inputs mpc_status[0..3]
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
* might provide:
* + named GPIO inputs mpcexp_status[0..15]
@@ -67,7 +67,7 @@
#define IOTS_NUM_APB_EXP_PPC 4
#define IOTS_NUM_AHB_EXP_PPC 4
#define IOTS_NUM_EXP_MPC 16
-#define IOTS_NUM_MPC 1
+#define IOTS_NUM_MPC 4
#define IOTS_NUM_EXP_MSC 16
typedef struct IoTKitSecCtl IoTKitSecCtl;
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
index 7b2e1a5e48..d84eb203b9 100644
--- a/include/hw/misc/iotkit-sysinfo.h
+++ b/include/hw/misc/iotkit-sysinfo.h
@@ -14,6 +14,8 @@
* Arm IoTKit and documented in
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
* QEMU interface:
+ * + QOM property "SYS_VERSION": value to use for SYS_VERSION register
+ * + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
* + sysbus MMIO region 0: the system information register bank
*/
@@ -32,6 +34,10 @@ typedef struct IoTKitSysInfo {
/*< public >*/
MemoryRegion iomem;
+
+ /* Properties */
+ uint32_t sys_version;
+ uint32_t sys_config;
} IoTKitSysInfo;
#endif
diff --git a/include/hw/nvram/nrf51_nvm.h b/include/hw/nvram/nrf51_nvm.h
new file mode 100644
index 0000000000..3792e4a9fe
--- /dev/null
+++ b/include/hw/nvram/nrf51_nvm.h
@@ -0,0 +1,64 @@
+/*
+ * Nordic Semiconductor nRF51 non-volatile memory
+ *
+ * It provides an interface to erase regions in flash memory.
+ * Furthermore it provides the user and factory information registers.
+ *
+ * QEMU interface:
+ * + sysbus MMIO regions 0: NVMC peripheral registers
+ * + sysbus MMIO regions 1: FICR peripheral registers
+ * + sysbus MMIO regions 2: UICR peripheral registers
+ * + flash-size property: flash size in bytes.
+ *
+ * Accuracy of the peripheral model:
+ * + Code regions (MPU configuration) are disregarded.
+ *
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
+ *
+ * This code is licensed under the GPL version 2 or later. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#ifndef NRF51_NVM_H
+#define NRF51_NVM_H
+
+#include "hw/sysbus.h"
+#define TYPE_NRF51_NVM "nrf51_soc.nvm"
+#define NRF51_NVM(obj) OBJECT_CHECK(NRF51NVMState, (obj), TYPE_NRF51_NVM)
+
+#define NRF51_UICR_FIXTURE_SIZE 64
+
+#define NRF51_NVMC_SIZE 0x1000
+
+#define NRF51_NVMC_READY 0x400
+#define NRF51_NVMC_READY_READY 0x01
+#define NRF51_NVMC_CONFIG 0x504
+#define NRF51_NVMC_CONFIG_MASK 0x03
+#define NRF51_NVMC_CONFIG_WEN 0x01
+#define NRF51_NVMC_CONFIG_EEN 0x02
+#define NRF51_NVMC_ERASEPCR1 0x508
+#define NRF51_NVMC_ERASEPCR0 0x510
+#define NRF51_NVMC_ERASEALL 0x50C
+#define NRF51_NVMC_ERASEUICR 0x514
+#define NRF51_NVMC_ERASE 0x01
+
+#define NRF51_UICR_SIZE 0x100
+
+typedef struct NRF51NVMState {
+ SysBusDevice parent_obj;
+
+ MemoryRegion mmio;
+ MemoryRegion ficr;
+ MemoryRegion uicr;
+ MemoryRegion flash;
+
+ uint32_t uicr_content[NRF51_UICR_FIXTURE_SIZE];
+ uint32_t flash_size;
+ uint8_t *storage;
+
+ uint32_t config;
+
+} NRF51NVMState;
+
+
+#endif
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 4c2feb9c17..1d6099e5d4 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -103,9 +103,21 @@ struct TranslationBlock;
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
* @get_memory_mapping: Callback for obtaining the memory mappings.
- * @set_pc: Callback for setting the Program Counter register.
+ * @set_pc: Callback for setting the Program Counter register. This
+ * should have the semantics used by the target architecture when
+ * setting the PC from a source such as an ELF file entry point;
+ * for example on Arm it will also set the Thumb mode bit based
+ * on the least significant bit of the new PC value.
+ * If the target behaviour here is anything other than "set
+ * the PC register to the value passed in" then the target must
+ * also implement the synchronize_from_tb hook.
* @synchronize_from_tb: Callback for synchronizing state from a TCG
- * #TranslationBlock.
+ * #TranslationBlock. This is called when we abandon execution
+ * of a TB before starting it, and must set all parts of the CPU
+ * state which the previous TB in the chain may not have updated.
+ * This always includes at least the program counter; some targets
+ * will need to do more. If this hook is not implemented then the
+ * default is to call @set_pc(tb->pc).
* @handle_mmu_fault: Callback for handling an MMU fault.
* @get_phys_page_debug: Callback for obtaining a physical address.
* @get_phys_page_attrs_debug: Callback for obtaining a physical address and the