1
As promised, more Arm patches. The big thing in here is the
1
v1->v2 changes: dropped the last 6 patches from rth as there's
2
MPS2-AN521 board model.
2
a problem with one of them that's too complicated to try to
3
fix up.
3
4
4
thanks
5
thanks
5
-- PMM
6
-- PMM
6
7
7
The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:
8
The following changes since commit a8c6af67e1e8d460e2c6e87070807e0a02c0fec2:
8
9
9
Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)
10
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-5.0-20200221' into staging (2020-02-21 14:20:42 +0000)
10
11
11
are available in the Git repository at:
12
are available in the Git repository at:
12
13
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190201
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200221-1
14
15
15
for you to fetch changes up to 7743b70ffe7a8ce168adce2cf50ad156b1fefb8c:
16
for you to fetch changes up to 9eb4f58918a851fb46895fd9b7ce579afeac9d02:
16
17
17
tests/microbit-test: Add tests for nRF51 NVMC (2019-02-01 15:32:17 +0000)
18
target/arm: Set MVFR0.FPSP for ARMv5 cpus (2020-02-21 16:07:03 +0000)
18
19
19
----------------------------------------------------------------
20
----------------------------------------------------------------
20
target-arm queue:
21
target-arm queue:
21
* New machine mps2-an521 -- this is a model of the AN521 FPGA image for the MPS2 devboard
22
* aspeed/scu: Implement chip ID register
22
* Fix various places where we failed to UNDEF invalid A64 instructions
23
* hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
23
* Don't UNDEF a valid FCMLA on 32-bit inputs
24
* mainstone: Make providing flash images non-mandatory
24
* Fix some bugs in the newly-added PAuth implementation
25
* z2: Make providing flash images non-mandatory
25
* microbit: Implement NVMC non-volatile memory controller
26
* Fix failures to flush SVE high bits after AdvSIMD INS/ZIP/UZP/TRN/TBL/TBX/EXT
27
* Minor performance improvement: spend less time recalculating hflags values
28
* Code cleanup to isar_feature function tests
29
* Implement ARMv8.1-PMU and ARMv8.4-PMU extensions
30
* Bugfix: correct handling of PMCR_EL0.LC bit
31
* Bugfix: correct definition of PMCRDP
32
* Correctly implement ACTLR2, HACTLR2
33
* allwinner: Wire up USB ports
34
* Vectorize emulation of USHL, SSHL, PMUL*
35
* xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
36
* sh4: Fix PCI ISA IO memory subregion
26
37
27
----------------------------------------------------------------
38
----------------------------------------------------------------
28
Aaron Lindsay OS (2):
39
Francisco Iglesias (1):
29
target/arm: Send interrupts on PMU counter overflow
40
xilinx_spips: Correct the number of dummy cycles for the FAST_READ_4 cmd
30
target/arm: Add a timer to predict PMU counter overflow
31
41
32
Julia Suvorova (1):
42
Guenter Roeck (6):
33
arm: Clarify the logic of set_pc()
43
mainstone: Make providing flash images non-mandatory
44
z2: Make providing flash images non-mandatory
45
hw: usb: hcd-ohci: Move OHCISysBusState and TYPE_SYSBUS_OHCI to include file
46
hcd-ehci: Introduce "companion-enable" sysbus property
47
arm: allwinner: Wire up USB ports
48
sh4: Fix PCI ISA IO memory subregion
34
49
35
Peter Maydell (33):
50
Joel Stanley (2):
36
armv7m: Don't assume the NVIC's CPU is CPU 0
51
aspeed/scu: Create separate write callbacks
37
armv7m: Make cpu object a child of the armv7m container
52
aspeed/scu: Implement chip ID register
38
armv7m: Pass through start-powered-off CPU property
39
hw/arm/iotkit: Rename IoTKit to ARMSSE
40
hw/arm/iotkit: Refactor into abstract base class and subclass
41
hw/arm/iotkit: Rename 'iotkit' local variables and functions
42
hw/arm/iotkit: Rename files to hw/arm/armsse.[ch]
43
hw/misc/iotkit-secctl: Support 4 internal MPCs
44
hw/arm/armsse: Make number of SRAM banks parameterised
45
hw/arm/armsse: Make SRAM bank size configurable
46
hw/arm/armsse: Support dual-CPU configuration
47
hw/arm/armsse: Give each CPU its own view of memory
48
hw/arm/armsse: Put each CPU in its own cluster object
49
iotkit-sysinfo: Make SYS_VERSION and SYS_CONFIG configurable
50
hw/arm/armsse: Add unimplemented-device stubs for MHUs
51
hw/arm/armsse: Add unimplemented-device stubs for PPUs
52
hw/arm/armsse: Add unimplemented-device stub for cache control registers
53
hw/arm/armsse: Add unimplemented-device stub for CPU local control registers
54
hw/misc/armsse-cpuid: Implement SSE-200 CPU_IDENTITY register block
55
hw/arm/armsse: Add CPU_IDENTITY block to SSE-200
56
hw/arm/armsse: Add SSE-200 model
57
hw/arm/mps2-tz: Add IRQ infrastructure to support SSE-200
58
hw/arm/mps2-tz: Add mps2-an521 model
59
target/arm/translate-a64: Don't underdecode system instructions
60
target/arm/translate-a64: Don't underdecode PRFM
61
target/arm/translate-a64: Don't underdecode SIMD ld/st multiple
62
target/arm/translate-a64: Don't underdecode SIMD ld/st single
63
target/arm/translate-a64: Don't underdecode add/sub extended register
64
target/arm/translate-a64: Don't underdecode FP insns
65
target/arm/translate-a64: Don't underdecode SDOT and UDOT
66
exec.c: Don't reallocate IOMMUNotifiers that are in use
67
target/arm/translate-a64: Fix FCMLA decoding error
68
target/arm/translate-a64: Fix mishandling of size in FCMLA decode
69
53
70
Remi Denis-Courmont (2):
54
Peter Maydell (21):
71
target/arm: fix AArch64 virtual address space size
55
target/arm: Add _aa32_ to isar_feature functions testing 32-bit ID registers
72
target/arm: fix decoding of B{,L}RA{A,B}
56
target/arm: Check aa32_pan in take_aarch32_exception(), not aa64_pan
57
target/arm: Add isar_feature_any_fp16 and document naming/usage conventions
58
target/arm: Define and use any_predinv isar_feature test
59
target/arm: Factor out PMU register definitions
60
target/arm: Add and use FIELD definitions for ID_AA64DFR0_EL1
61
target/arm: Use FIELD macros for clearing ID_DFR0 PERFMON field
62
target/arm: Define an aa32_pmu_8_1 isar feature test function
63
target/arm: Add _aa64_ and _any_ versions of pmu_8_1 isar checks
64
target/arm: Stop assuming DBGDIDR always exists
65
target/arm: Move DBGDIDR into ARMISARegisters
66
target/arm: Read debug-related ID registers from KVM
67
target/arm: Implement ARMv8.1-PMU extension
68
target/arm: Implement ARMv8.4-PMU extension
69
target/arm: Provide ARMv8.4-PMU in '-cpu max'
70
target/arm: Correct definition of PMCRDP
71
target/arm: Correct handling of PMCR_EL0.LC bit
72
target/arm: Test correct register in aa32_pan and aa32_ats1e1 checks
73
target/arm: Use isar_feature function for testing AA32HPD feature
74
target/arm: Use FIELD_EX32 for testing 32-bit fields
75
target/arm: Correctly implement ACTLR2, HACTLR2
73
76
74
Richard Henderson (5):
77
Philippe Mathieu-Daudé (1):
75
target/arm: Enable API, APK bits in SCR, HCR
78
hw/misc/iotkit-secctl: Fix writing to 'PPC Interrupt Clear' register
76
target/arm: Always enable pac keys for user-only
77
aarch64-linux-user: Update HWCAP bits from linux 5.0-rc1
78
aarch64-linux-user: Enable HWCAP bits for PAuth
79
linux-user: Initialize aarch64 pac keys
80
79
81
Steffen Görtz (3):
80
Richard Henderson (15):
82
hw/nvram/nrf51_nvm: Add nRF51 non-volatile memories
81
target/arm: Flush high bits of sve register after AdvSIMD EXT
83
arm: Instantiate NRF51 special NVM's and NVMC
82
target/arm: Flush high bits of sve register after AdvSIMD TBL/TBX
84
tests/microbit-test: Add tests for nRF51 NVMC
83
target/arm: Flush high bits of sve register after AdvSIMD ZIP/UZP/TRN
84
target/arm: Flush high bits of sve register after AdvSIMD INS
85
target/arm: Use bit 55 explicitly for pauth
86
target/arm: Fix select for aa64_va_parameters_both
87
target/arm: Remove ttbr1_valid check from get_phys_addr_lpae
88
target/arm: Split out aa64_va_parameter_tbi, aa64_va_parameter_tbid
89
target/arm: Vectorize USHL and SSHL
90
target/arm: Convert PMUL.8 to gvec
91
target/arm: Convert PMULL.64 to gvec
92
target/arm: Convert PMULL.8 to gvec
93
target/arm: Rename isar_feature_aa32_simd_r32
94
target/arm: Use isar_feature_aa32_simd_r32 more places
95
target/arm: Set MVFR0.FPSP for ARMv5 cpus
85
96
86
kumar sourav (1):
97
hw/usb/hcd-ohci.h | 16 ++
87
hw/arm/nrf51_soc: set object owner in memory_region_init_ram
98
include/hw/arm/allwinner-a10.h | 6 +
99
target/arm/cpu.h | 145 ++++++++++---
100
target/arm/helper-sve.h | 2 +
101
target/arm/helper.h | 21 +-
102
target/arm/internals.h | 47 ++++-
103
target/arm/translate.h | 6 +
104
hw/arm/allwinner-a10.c | 43 ++++
105
hw/arm/mainstone.c | 11 +-
106
hw/arm/z2.c | 6 -
107
hw/intc/armv7m_nvic.c | 10 +-
108
hw/misc/aspeed_scu.c | 93 ++++++--
109
hw/misc/iotkit-secctl.c | 2 +-
110
hw/sh4/sh_pci.c | 11 +-
111
hw/ssi/xilinx_spips.c | 2 +-
112
hw/usb/hcd-ehci-sysbus.c | 2 +
113
hw/usb/hcd-ohci.c | 15 --
114
linux-user/elfload.c | 4 +-
115
target/arm/cpu.c | 169 +++++++--------
116
target/arm/cpu64.c | 58 +++--
117
target/arm/debug_helper.c | 6 +-
118
target/arm/helper.c | 468 +++++++++++++++++++++++------------------
119
target/arm/kvm32.c | 25 +++
120
target/arm/kvm64.c | 46 ++++
121
target/arm/neon_helper.c | 117 -----------
122
target/arm/pauth_helper.c | 3 +-
123
target/arm/translate-a64.c | 92 ++++----
124
target/arm/translate-vfp.inc.c | 53 ++---
125
target/arm/translate.c | 356 ++++++++++++++++++++++++++-----
126
target/arm/vec_helper.c | 211 +++++++++++++++++++
127
target/arm/vfp_helper.c | 2 +-
128
31 files changed, 1377 insertions(+), 671 deletions(-)
88
129
89
hw/arm/Makefile.objs | 2 +-
90
hw/misc/Makefile.objs | 1 +
91
hw/nvram/Makefile.objs | 1 +
92
include/hw/arm/{iotkit.h => armsse.h} | 113 ++-
93
include/hw/arm/armv7m.h | 1 +
94
include/hw/arm/nrf51_soc.h | 2 +
95
include/hw/misc/armsse-cpuid.h | 41 ++
96
include/hw/misc/iotkit-secctl.h | 6 +-
97
include/hw/misc/iotkit-sysinfo.h | 6 +
98
include/hw/nvram/nrf51_nvm.h | 64 ++
99
include/qom/cpu.h | 16 +-
100
linux-user/aarch64/target_syscall.h | 2 +
101
target/arm/cpu.h | 12 +-
102
exec.c | 10 +-
103
hw/arm/armsse.c | 1241 +++++++++++++++++++++++++++++++++
104
hw/arm/armv7m.c | 23 +-
105
hw/arm/boot.c | 4 -
106
hw/arm/iotkit.c | 759 --------------------
107
hw/arm/mps2-tz.c | 121 +++-
108
hw/arm/nrf51_soc.c | 44 +-
109
hw/intc/armv7m_nvic.c | 3 +-
110
hw/misc/armsse-cpuid.c | 134 ++++
111
hw/misc/iotkit-secctl.c | 5 +-
112
hw/misc/iotkit-sysinfo.c | 15 +-
113
hw/nvram/nrf51_nvm.c | 388 +++++++++++
114
linux-user/aarch64/cpu_loop.c | 31 +-
115
linux-user/elfload.c | 10 +
116
target/arm/arm-powerctl.c | 3 -
117
target/arm/cpu.c | 41 +-
118
target/arm/cpu64.c | 75 --
119
target/arm/helper.c | 139 +++-
120
target/arm/translate-a64.c | 59 +-
121
tests/microbit-test.c | 108 +++
122
MAINTAINERS | 6 +-
123
default-configs/arm-softmmu.mak | 3 +-
124
hw/misc/trace-events | 4 +
125
36 files changed, 2552 insertions(+), 941 deletions(-)
126
rename include/hw/arm/{iotkit.h => armsse.h} (53%)
127
create mode 100644 include/hw/misc/armsse-cpuid.h
128
create mode 100644 include/hw/nvram/nrf51_nvm.h
129
create mode 100644 hw/arm/armsse.c
130
delete mode 100644 hw/arm/iotkit.c
131
create mode 100644 hw/misc/armsse-cpuid.c
132
create mode 100644 hw/nvram/nrf51_nvm.c
133
diff view generated by jsdifflib
Deleted patch
1
From: kumar sourav <sourav.jb1988@gmail.com>
2
1
3
set object owner in memory_region_init_ram() instead
4
of NULL.
5
6
Signed-off-by: kumar sourav <sourav.jb1988@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190125155630.17430-1-sourav.jb1988@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/nrf51_soc.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/nrf51_soc.c
18
+++ b/hw/arm/nrf51_soc.c
19
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
20
}
21
memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
22
23
- memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
24
+ memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
25
+ &err);
26
if (err) {
27
error_propagate(errp, err);
28
return;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
Currently the ARMv7M NVIC object's realize method assumes that the
2
CPU the NVIC is attached to is CPU 0, because it thinks there can
3
only ever be one CPU in the system. To allow a dual-Cortex-M33
4
setup we need to remove this assumption; instead the armv7m
5
wrapper object tells the NVIC its CPU, in the same way that it
6
already tells the CPU what the NVIC is.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190121185118.18550-2-peter.maydell@linaro.org
12
---
13
hw/arm/armv7m.c | 6 ++++--
14
hw/intc/armv7m_nvic.c | 3 +--
15
2 files changed, 5 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/armv7m.c
20
+++ b/hw/arm/armv7m.c
21
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
22
}
23
}
24
25
- /* Tell the CPU where the NVIC is; it will fail realize if it doesn't
26
- * have one.
27
+ /*
28
+ * Tell the CPU where the NVIC is; it will fail realize if it doesn't
29
+ * have one. Similarly, tell the NVIC where its CPU is.
30
*/
31
s->cpu->env.nvic = &s->nvic;
32
+ s->nvic.cpu = s->cpu;
33
34
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
35
if (err != NULL) {
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/armv7m_nvic.c
39
+++ b/hw/intc/armv7m_nvic.c
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
41
Error *err = NULL;
42
int regionlen;
43
44
- s->cpu = ARM_CPU(qemu_get_cpu(0));
45
-
46
+ /* The armv7m container object will have set our CPU pointer */
47
if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
48
error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
49
return;
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
Rather than just creating the CPUs with object_new, make them child
2
objects of the armv7m container. This will allow the cluster code to
3
find the CPUs if an armv7m object is made a child of a cluster object.
4
object_new_with_props() will do the parenting for us.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190121185118.18550-3-peter.maydell@linaro.org
10
---
11
hw/arm/armv7m.c | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/armv7m.c
17
+++ b/hw/arm/armv7m.c
18
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
19
20
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
21
22
- s->cpu = ARM_CPU(object_new(s->cpu_type));
23
+ s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
24
+ &err, NULL));
25
+ if (err != NULL) {
26
+ error_propagate(errp, err);
27
+ return;
28
+ }
29
30
object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
31
&error_abort);
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
Expose "start-powered-off" as a property of the ARMv7M container,
2
which we just pass through to the CPU object in the same way that we
3
do for "init-svtor" and "idau". (We want this for the SSE-200, which
4
powers up only the first CPU at reset and leaves the second powered
5
down.)
6
1
7
As with the other CPU properties here, we can't just use alias
8
properties, because the CPU QOM object is not created until armv7m
9
realize time.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-4-peter.maydell@linaro.org
14
---
15
include/hw/arm/armv7m.h | 1 +
16
hw/arm/armv7m.c | 10 ++++++++++
17
2 files changed, 11 insertions(+)
18
19
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/armv7m.h
22
+++ b/include/hw/arm/armv7m.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
24
Object *idau;
25
uint32_t init_svtor;
26
bool enable_bitband;
27
+ bool start_powered_off;
28
} ARMv7MState;
29
30
#endif
31
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/armv7m.c
34
+++ b/hw/arm/armv7m.c
35
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
36
return;
37
}
38
}
39
+ if (object_property_find(OBJECT(s->cpu), "start-powered-off", NULL)) {
40
+ object_property_set_bool(OBJECT(s->cpu), s->start_powered_off,
41
+ "start-powered-off", &err);
42
+ if (err != NULL) {
43
+ error_propagate(errp, err);
44
+ return;
45
+ }
46
+ }
47
48
/*
49
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
50
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
51
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
52
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
53
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
54
+ DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
55
+ false),
56
DEFINE_PROP_END_OF_LIST(),
57
};
58
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
Deleted patch
1
The Arm IoTKit was effectively the forerunner of a series of
2
subsystems for embedded SoCs, named the SSE-050, SSE-100 and SSE-200:
3
https://developer.arm.com/products/system-design/subsystems
4
These are generally quite similar, though later iterations have
5
extra devices that earlier ones do not.
6
1
7
We want to add a model of the SSE-200, which means refactoring the
8
IoTKit code into an abstract base class and subclasses (using the
9
same design that the bcm283x SoC and Aspeed SoC family
10
implementations do). As a first step, rename the IoTKit struct and
11
QOM macros to ARMSSE, which is what we're going to name the base
12
class. We temporarily retain TYPE_IOTKIT to avoid changing the
13
code that instantiates a TYPE_IOTKIT device here and then changing
14
it back again when it is re-introduced as a subclass.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190121185118.18550-5-peter.maydell@linaro.org
20
---
21
include/hw/arm/iotkit.h | 22 ++++++++++-----
22
hw/arm/iotkit.c | 59 +++++++++++++++++++++--------------------
23
hw/arm/mps2-tz.c | 2 +-
24
3 files changed, 47 insertions(+), 36 deletions(-)
25
26
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/iotkit.h
29
+++ b/include/hw/arm/iotkit.h
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM IoT Kit
33
+ * ARM SSE (Subsystems for Embedded): IoTKit
34
*
35
* Copyright (c) 2018 Linaro Limited
36
* Written by Peter Maydell
37
@@ -XXX,XX +XXX,XX @@
38
* (at your option) any later version.
39
*/
40
41
-/* This is a model of the Arm IoT Kit which is documented in
42
+/*
43
+ * This is a model of the Arm "Subsystems for Embedded" family of
44
+ * hardware, which include the IoT Kit and the SSE-050, SSE-100 and
45
+ * SSE-200. Currently we model only the Arm IoT Kit which is documented in
46
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
47
* It contains:
48
* a Cortex-M33
49
@@ -XXX,XX +XXX,XX @@
50
#include "hw/or-irq.h"
51
#include "hw/core/split-irq.h"
52
53
-#define TYPE_IOTKIT "iotkit"
54
-#define IOTKIT(obj) OBJECT_CHECK(IoTKit, (obj), TYPE_IOTKIT)
55
+#define TYPE_ARMSSE "iotkit"
56
+#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
57
+
58
+/*
59
+ * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
60
+ * latter's underlying name is left as "iotkit"); in a later
61
+ * commit it will become a subclass of TYPE_ARMSSE.
62
+ */
63
+#define TYPE_IOTKIT TYPE_ARMSSE
64
65
/* We have an IRQ splitter and an OR gate input for each external PPC
66
* and the 2 internal PPCs
67
@@ -XXX,XX +XXX,XX @@
68
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
69
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
70
71
-typedef struct IoTKit {
72
+typedef struct ARMSSE {
73
/*< private >*/
74
SysBusDevice parent_obj;
75
76
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
77
MemoryRegion *board_memory;
78
uint32_t exp_numirq;
79
uint32_t mainclk_frq;
80
-} IoTKit;
81
+} ARMSSE;
82
83
#endif
84
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/iotkit.c
87
+++ b/hw/arm/iotkit.c
88
@@ -XXX,XX +XXX,XX @@
89
/*
90
- * Arm IoT Kit
91
+ * Arm SSE (Subsystems for Embedded): IoTKit
92
*
93
* Copyright (c) 2018 Linaro Limited
94
* Written by Peter Maydell
95
@@ -XXX,XX +XXX,XX @@
96
/* Create an alias region of @size bytes starting at @base
97
* which mirrors the memory starting at @orig.
98
*/
99
-static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name,
100
+static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
101
hwaddr base, hwaddr size, hwaddr orig)
102
{
103
memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
104
@@ -XXX,XX +XXX,XX @@ static void irq_status_forwarder(void *opaque, int n, int level)
105
106
static void nsccfg_handler(void *opaque, int n, int level)
107
{
108
- IoTKit *s = IOTKIT(opaque);
109
+ ARMSSE *s = ARMSSE(opaque);
110
111
s->nsccfg = level;
112
}
113
114
-static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
115
+static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
116
{
117
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
118
- * system using the IoTKit has a collection of control lines which
119
+ * system using the ARMSSE has a collection of control lines which
120
* are provided by the security controller and which we want to
121
- * expose as control lines on the IoTKit device itself, so the
122
- * code using the IoTKit can wire them up to the PPCs.
123
+ * expose as control lines on the ARMSSE device itself, so the
124
+ * code using the ARMSSE can wire them up to the PPCs.
125
*/
126
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
127
DeviceState *iotkitdev = DEVICE(s);
128
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
129
g_free(name);
130
}
131
132
-static void iotkit_forward_sec_resp_cfg(IoTKit *s)
133
+static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
134
{
135
/* Forward the 3rd output from the splitter device as a
136
* named GPIO output of the iotkit object.
137
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_sec_resp_cfg(IoTKit *s)
138
139
static void iotkit_init(Object *obj)
140
{
141
- IoTKit *s = IOTKIT(obj);
142
+ ARMSSE *s = ARMSSE(obj);
143
int i;
144
145
memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
146
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
147
148
static void iotkit_exp_irq(void *opaque, int n, int level)
149
{
150
- IoTKit *s = IOTKIT(opaque);
151
+ ARMSSE *s = ARMSSE(opaque);
152
153
qemu_set_irq(s->exp_irqs[n], level);
154
}
155
156
static void iotkit_mpcexp_status(void *opaque, int n, int level)
157
{
158
- IoTKit *s = IOTKIT(opaque);
159
+ ARMSSE *s = ARMSSE(opaque);
160
qemu_set_irq(s->mpcexp_status_in[n], level);
161
}
162
163
static void iotkit_realize(DeviceState *dev, Error **errp)
164
{
165
- IoTKit *s = IOTKIT(dev);
166
+ ARMSSE *s = ARMSSE(dev);
167
int i;
168
MemoryRegion *mr;
169
Error *err = NULL;
170
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
171
* devices exist in both address spaces but with hard-wired security
172
* permissions that will cause the CPU to fault for non-secure accesses.
173
*
174
- * The IoTKit has an IDAU (Implementation Defined Access Unit),
175
+ * The ARMSSE has an IDAU (Implementation Defined Access Unit),
176
* which specifies hard-wired security permissions for different
177
- * areas of the physical address space. For the IoTKit IDAU, the
178
+ * areas of the physical address space. For the ARMSSE IDAU, the
179
* top 4 bits of the physical address are the IDAU region ID, and
180
* if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
181
* region, otherwise it is an S region.
182
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
183
* 0x20000000..0x2007ffff 32KB FPGA block RAM
184
* 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
185
* 0x40000000..0x4000ffff base peripheral region 1
186
- * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit)
187
+ * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
188
* 0x40020000..0x4002ffff system control element peripherals
189
* 0x40080000..0x400fffff base peripheral region 2
190
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
191
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
192
qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
193
194
/* The sec_resp_cfg output from the security controller must be split into
195
- * multiple lines, one for each of the PPCs within the IoTKit and one
196
- * that will be an output from the IoTKit to the system.
197
+ * multiple lines, one for each of the PPCs within the ARMSSE and one
198
+ * that will be an output from the ARMSSE to the system.
199
*/
200
object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
201
"num-lines", &err);
202
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
203
204
/* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
205
206
- /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */
207
+ /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
208
/* Devices behind APB PPC1:
209
* 0x4002f000: S32K timer
210
*/
211
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
212
qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
213
sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
214
215
- /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
216
+ /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
217
218
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
219
object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
220
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
221
* Expose our container region to the board model; this corresponds
222
* to the AHB Slave Expansion ports which allow bus master devices
223
* (eg DMA controllers) in the board model to make transactions into
224
- * devices in the IoTKit.
225
+ * devices in the ARMSSE.
226
*/
227
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
228
229
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
230
static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
231
int *iregion, bool *exempt, bool *ns, bool *nsc)
232
{
233
- /* For IoTKit systems the IDAU responses are simple logical functions
234
+ /*
235
+ * For ARMSSE systems the IDAU responses are simple logical functions
236
* of the address bits. The NSC attribute is guest-adjustable via the
237
* NSCCFG register in the security controller.
238
*/
239
- IoTKit *s = IOTKIT(ii);
240
+ ARMSSE *s = ARMSSE(ii);
241
int region = extract32(address, 28, 4);
242
243
*ns = !(region & 1);
244
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_vmstate = {
245
.version_id = 1,
246
.minimum_version_id = 1,
247
.fields = (VMStateField[]) {
248
- VMSTATE_UINT32(nsccfg, IoTKit),
249
+ VMSTATE_UINT32(nsccfg, ARMSSE),
250
VMSTATE_END_OF_LIST()
251
}
252
};
253
254
static Property iotkit_properties[] = {
255
- DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION,
256
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
257
MemoryRegion *),
258
- DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64),
259
- DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0),
260
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
261
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
262
DEFINE_PROP_END_OF_LIST()
263
};
264
265
static void iotkit_reset(DeviceState *dev)
266
{
267
- IoTKit *s = IOTKIT(dev);
268
+ ARMSSE *s = ARMSSE(dev);
269
270
s->nsccfg = 0;
271
}
272
@@ -XXX,XX +XXX,XX @@ static void iotkit_class_init(ObjectClass *klass, void *data)
273
}
274
275
static const TypeInfo iotkit_info = {
276
- .name = TYPE_IOTKIT,
277
+ .name = TYPE_ARMSSE,
278
.parent = TYPE_SYS_BUS_DEVICE,
279
- .instance_size = sizeof(IoTKit),
280
+ .instance_size = sizeof(ARMSSE),
281
.instance_init = iotkit_init,
282
.class_init = iotkit_class_init,
283
.interfaces = (InterfaceInfo[]) {
284
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/arm/mps2-tz.c
287
+++ b/hw/arm/mps2-tz.c
288
@@ -XXX,XX +XXX,XX @@ typedef struct {
289
typedef struct {
290
MachineState parent;
291
292
- IoTKit iotkit;
293
+ ARMSSE iotkit;
294
MemoryRegion psram;
295
MemoryRegion ssram[3];
296
MemoryRegion ssram1_m;
297
--
298
2.20.1
299
300
diff view generated by jsdifflib
Deleted patch
1
The Arm SSE-200 Subsystem for Embedded is a revised and
2
extended version of the older IoTKit SoC. Prepare for
3
adding a model of it by refactoring the IoTKit code into
4
an abstract base class which contains the functionality,
5
driven by a class data block specific to each subclass.
6
(This is the same approach used by the existing bcm283x
7
SoC family implementation.)
8
1
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190121185118.18550-6-peter.maydell@linaro.org
13
---
14
include/hw/arm/iotkit.h | 22 +++++++++++++++++-----
15
hw/arm/iotkit.c | 34 +++++++++++++++++++++++++++++-----
16
2 files changed, 46 insertions(+), 10 deletions(-)
17
18
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/iotkit.h
21
+++ b/include/hw/arm/iotkit.h
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/or-irq.h"
24
#include "hw/core/split-irq.h"
25
26
-#define TYPE_ARMSSE "iotkit"
27
+#define TYPE_ARMSSE "arm-sse"
28
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
29
30
/*
31
- * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
32
- * latter's underlying name is left as "iotkit"); in a later
33
- * commit it will become a subclass of TYPE_ARMSSE.
34
+ * These type names are for specific IoTKit subsystems; other than
35
+ * instantiating them, code using these devices should always handle
36
+ * them via the ARMSSE base class, so they have no IOTKIT() etc macros.
37
*/
38
-#define TYPE_IOTKIT TYPE_ARMSSE
39
+#define TYPE_IOTKIT "iotkit"
40
41
/* We have an IRQ splitter and an OR gate input for each external PPC
42
* and the 2 internal PPCs
43
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
44
uint32_t mainclk_frq;
45
} ARMSSE;
46
47
+typedef struct ARMSSEInfo ARMSSEInfo;
48
+
49
+typedef struct ARMSSEClass {
50
+ DeviceClass parent_class;
51
+ const ARMSSEInfo *info;
52
+} ARMSSEClass;
53
+
54
+#define ARMSSE_CLASS(klass) \
55
+ OBJECT_CLASS_CHECK(ARMSSEClass, (klass), TYPE_ARMSSE)
56
+#define ARMSSE_GET_CLASS(obj) \
57
+ OBJECT_GET_CLASS(ARMSSEClass, (obj), TYPE_ARMSSE)
58
+
59
#endif
60
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/iotkit.c
63
+++ b/hw/arm/iotkit.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "hw/arm/iotkit.h"
66
#include "hw/arm/arm.h"
67
68
+struct ARMSSEInfo {
69
+ const char *name;
70
+};
71
+
72
+static const ARMSSEInfo armsse_variants[] = {
73
+ {
74
+ .name = TYPE_IOTKIT,
75
+ },
76
+};
77
+
78
/* Clock frequency in HZ of the 32KHz "slow clock" */
79
#define S32KCLK (32 * 1000)
80
81
@@ -XXX,XX +XXX,XX @@ static void iotkit_class_init(ObjectClass *klass, void *data)
82
{
83
DeviceClass *dc = DEVICE_CLASS(klass);
84
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
85
+ ARMSSEClass *asc = ARMSSE_CLASS(klass);
86
87
dc->realize = iotkit_realize;
88
dc->vmsd = &iotkit_vmstate;
89
dc->props = iotkit_properties;
90
dc->reset = iotkit_reset;
91
iic->check = iotkit_idau_check;
92
+ asc->info = data;
93
}
94
95
-static const TypeInfo iotkit_info = {
96
+static const TypeInfo armsse_info = {
97
.name = TYPE_ARMSSE,
98
.parent = TYPE_SYS_BUS_DEVICE,
99
.instance_size = sizeof(ARMSSE),
100
.instance_init = iotkit_init,
101
- .class_init = iotkit_class_init,
102
+ .abstract = true,
103
.interfaces = (InterfaceInfo[]) {
104
{ TYPE_IDAU_INTERFACE },
105
{ }
106
}
107
};
108
109
-static void iotkit_register_types(void)
110
+static void armsse_register_types(void)
111
{
112
- type_register_static(&iotkit_info);
113
+ int i;
114
+
115
+ type_register_static(&armsse_info);
116
+
117
+ for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
118
+ TypeInfo ti = {
119
+ .name = armsse_variants[i].name,
120
+ .parent = TYPE_ARMSSE,
121
+ .class_init = iotkit_class_init,
122
+ .class_data = (void *)&armsse_variants[i],
123
+ };
124
+ type_register(&ti);
125
+ }
126
}
127
128
-type_init(iotkit_register_types);
129
+type_init(armsse_register_types);
130
--
131
2.20.1
132
133
diff view generated by jsdifflib
Deleted patch
1
Rename various internal uses of 'iotkit' in hw/arm/iotkit.c to
2
'armsse', for consistency. The remaining occurences are:
3
* related to the devices TYPE_IOTKIT_SYSCTL, TYPE_IOTKIT_SYSINFO,
4
etc, which this refactor is not touching
5
* references that apply specifically to the IoTKit (like
6
the lack of a private CPU region)
7
* the vmstate, which keeps its old "iotkit" name for
8
migration compatibility reasons
9
1
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-7-peter.maydell@linaro.org
14
---
15
hw/arm/iotkit.c | 68 ++++++++++++++++++++++++-------------------------
16
1 file changed, 34 insertions(+), 34 deletions(-)
17
18
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/iotkit.c
21
+++ b/hw/arm/iotkit.c
22
@@ -XXX,XX +XXX,XX @@ static void nsccfg_handler(void *opaque, int n, int level)
23
s->nsccfg = level;
24
}
25
26
-static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
27
+static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
28
{
29
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
30
* system using the ARMSSE has a collection of control lines which
31
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
32
* code using the ARMSSE can wire them up to the PPCs.
33
*/
34
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
35
- DeviceState *iotkitdev = DEVICE(s);
36
+ DeviceState *armssedev = DEVICE(s);
37
DeviceState *dev_secctl = DEVICE(&s->secctl);
38
DeviceState *dev_splitter = DEVICE(splitter);
39
char *name;
40
41
name = g_strdup_printf("%s_nonsec", ppcname);
42
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
43
+ qdev_pass_gpios(dev_secctl, armssedev, name);
44
g_free(name);
45
name = g_strdup_printf("%s_ap", ppcname);
46
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
47
+ qdev_pass_gpios(dev_secctl, armssedev, name);
48
g_free(name);
49
name = g_strdup_printf("%s_irq_enable", ppcname);
50
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
51
+ qdev_pass_gpios(dev_secctl, armssedev, name);
52
g_free(name);
53
name = g_strdup_printf("%s_irq_clear", ppcname);
54
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
55
+ qdev_pass_gpios(dev_secctl, armssedev, name);
56
g_free(name);
57
58
/* irq_status is a little more tricky, because we need to
59
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
60
qdev_connect_gpio_out(dev_splitter, 1,
61
qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
62
s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
63
- qdev_init_gpio_in_named_with_opaque(iotkitdev, irq_status_forwarder,
64
+ qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
65
s->irq_status_in[ppcnum], name, 1);
66
g_free(name);
67
}
68
69
-static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
70
+static void armsse_forward_sec_resp_cfg(ARMSSE *s)
71
{
72
/* Forward the 3rd output from the splitter device as a
73
- * named GPIO output of the iotkit object.
74
+ * named GPIO output of the armsse object.
75
*/
76
DeviceState *dev = DEVICE(s);
77
DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
78
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
79
qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
80
}
81
82
-static void iotkit_init(Object *obj)
83
+static void armsse_init(Object *obj)
84
{
85
ARMSSE *s = ARMSSE(obj);
86
int i;
87
88
- memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
89
+ memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
90
91
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
92
TYPE_ARMV7M);
93
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
94
sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG);
95
sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog,
96
sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG);
97
- sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl,
98
+ sysbus_init_child_obj(obj, "armsse-sysctl", &s->sysctl,
99
sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
100
- sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo,
101
+ sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
102
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
103
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
104
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
105
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
106
}
107
}
108
109
-static void iotkit_exp_irq(void *opaque, int n, int level)
110
+static void armsse_exp_irq(void *opaque, int n, int level)
111
{
112
ARMSSE *s = ARMSSE(opaque);
113
114
qemu_set_irq(s->exp_irqs[n], level);
115
}
116
117
-static void iotkit_mpcexp_status(void *opaque, int n, int level)
118
+static void armsse_mpcexp_status(void *opaque, int n, int level)
119
{
120
ARMSSE *s = ARMSSE(opaque);
121
qemu_set_irq(s->mpcexp_status_in[n], level);
122
}
123
124
-static void iotkit_realize(DeviceState *dev, Error **errp)
125
+static void armsse_realize(DeviceState *dev, Error **errp)
126
{
127
ARMSSE *s = ARMSSE(dev);
128
int i;
129
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
130
for (i = 0; i < s->exp_numirq; i++) {
131
s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
132
}
133
- qdev_init_gpio_in_named(dev, iotkit_exp_irq, "EXP_IRQ", s->exp_numirq);
134
+ qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
135
136
/* Set up the big aliases first */
137
make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
138
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
139
qdev_get_gpio_in(dev_splitter, 0));
140
141
/* This RAM lives behind the Memory Protection Controller */
142
- memory_region_init_ram(&s->sram0, NULL, "iotkit.sram0", 0x00008000, &err);
143
+ memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
144
if (err) {
145
error_propagate(errp, err);
146
return;
147
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
148
for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
149
char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
150
151
- iotkit_forward_ppc(s, ppcname, i);
152
+ armsse_forward_ppc(s, ppcname, i);
153
g_free(ppcname);
154
}
155
156
for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
157
char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
158
159
- iotkit_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
160
+ armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
161
g_free(ppcname);
162
}
163
164
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
165
/* Create GPIO inputs which will pass the line state for our
166
* mpcexp_irq inputs to the correct splitter devices.
167
*/
168
- qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
169
+ qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
170
IOTS_NUM_EXP_MPC);
171
172
- iotkit_forward_sec_resp_cfg(s);
173
+ armsse_forward_sec_resp_cfg(s);
174
175
/* Forward the MSC related signals */
176
qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
177
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
178
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
179
}
180
181
-static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
182
+static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
183
int *iregion, bool *exempt, bool *ns, bool *nsc)
184
{
185
/*
186
@@ -XXX,XX +XXX,XX @@ static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
187
*iregion = region;
188
}
189
190
-static const VMStateDescription iotkit_vmstate = {
191
+static const VMStateDescription armsse_vmstate = {
192
.name = "iotkit",
193
.version_id = 1,
194
.minimum_version_id = 1,
195
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_vmstate = {
196
}
197
};
198
199
-static Property iotkit_properties[] = {
200
+static Property armsse_properties[] = {
201
DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
202
MemoryRegion *),
203
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
204
@@ -XXX,XX +XXX,XX @@ static Property iotkit_properties[] = {
205
DEFINE_PROP_END_OF_LIST()
206
};
207
208
-static void iotkit_reset(DeviceState *dev)
209
+static void armsse_reset(DeviceState *dev)
210
{
211
ARMSSE *s = ARMSSE(dev);
212
213
s->nsccfg = 0;
214
}
215
216
-static void iotkit_class_init(ObjectClass *klass, void *data)
217
+static void armsse_class_init(ObjectClass *klass, void *data)
218
{
219
DeviceClass *dc = DEVICE_CLASS(klass);
220
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
221
ARMSSEClass *asc = ARMSSE_CLASS(klass);
222
223
- dc->realize = iotkit_realize;
224
- dc->vmsd = &iotkit_vmstate;
225
- dc->props = iotkit_properties;
226
- dc->reset = iotkit_reset;
227
- iic->check = iotkit_idau_check;
228
+ dc->realize = armsse_realize;
229
+ dc->vmsd = &armsse_vmstate;
230
+ dc->props = armsse_properties;
231
+ dc->reset = armsse_reset;
232
+ iic->check = armsse_idau_check;
233
asc->info = data;
234
}
235
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo armsse_info = {
237
.name = TYPE_ARMSSE,
238
.parent = TYPE_SYS_BUS_DEVICE,
239
.instance_size = sizeof(ARMSSE),
240
- .instance_init = iotkit_init,
241
+ .instance_init = armsse_init,
242
.abstract = true,
243
.interfaces = (InterfaceInfo[]) {
244
{ TYPE_IDAU_INTERFACE },
245
@@ -XXX,XX +XXX,XX @@ static void armsse_register_types(void)
246
TypeInfo ti = {
247
.name = armsse_variants[i].name,
248
.parent = TYPE_ARMSSE,
249
- .class_init = iotkit_class_init,
250
+ .class_init = armsse_class_init,
251
.class_data = (void *)&armsse_variants[i],
252
};
253
type_register(&ti);
254
--
255
2.20.1
256
257
diff view generated by jsdifflib
Deleted patch
1
Rename the files that used to be iotkit.[ch] to
2
armsse.[ch] to reflect the fact they new cover
3
multiple Arm subsystems for embedded.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-8-peter.maydell@linaro.org
9
---
10
hw/arm/Makefile.objs | 2 +-
11
include/hw/arm/{iotkit.h => armsse.h} | 4 ++--
12
hw/arm/{iotkit.c => armsse.c} | 2 +-
13
hw/arm/mps2-tz.c | 2 +-
14
MAINTAINERS | 4 ++--
15
default-configs/arm-softmmu.mak | 2 +-
16
6 files changed, 8 insertions(+), 8 deletions(-)
17
rename include/hw/arm/{iotkit.h => armsse.h} (99%)
18
rename hw/arm/{iotkit.c => armsse.c} (99%)
19
20
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/Makefile.objs
23
+++ b/hw/arm/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
25
obj-$(CONFIG_MPS2) += mps2.o
26
obj-$(CONFIG_MPS2) += mps2-tz.o
27
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
28
-obj-$(CONFIG_IOTKIT) += iotkit.o
29
+obj-$(CONFIG_ARMSSE) += armsse.o
30
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
31
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
32
obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
33
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/armsse.h
34
similarity index 99%
35
rename from include/hw/arm/iotkit.h
36
rename to include/hw/arm/armsse.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/include/hw/arm/iotkit.h
39
+++ b/include/hw/arm/armsse.h
40
@@ -XXX,XX +XXX,XX @@
41
* + named GPIO outputs mscexp_ns[0..15]
42
*/
43
44
-#ifndef IOTKIT_H
45
-#define IOTKIT_H
46
+#ifndef ARMSSE_H
47
+#define ARMSSE_H
48
49
#include "hw/sysbus.h"
50
#include "hw/arm/armv7m.h"
51
diff --git a/hw/arm/iotkit.c b/hw/arm/armsse.c
52
similarity index 99%
53
rename from hw/arm/iotkit.c
54
rename to hw/arm/armsse.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/iotkit.c
57
+++ b/hw/arm/armsse.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "trace.h"
60
#include "hw/sysbus.h"
61
#include "hw/registerfields.h"
62
-#include "hw/arm/iotkit.h"
63
+#include "hw/arm/armsse.h"
64
#include "hw/arm/arm.h"
65
66
struct ARMSSEInfo {
67
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/mps2-tz.c
70
+++ b/hw/arm/mps2-tz.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "hw/misc/mps2-fpgaio.h"
73
#include "hw/misc/tz-mpc.h"
74
#include "hw/misc/tz-msc.h"
75
-#include "hw/arm/iotkit.h"
76
+#include "hw/arm/armsse.h"
77
#include "hw/dma/pl080.h"
78
#include "hw/ssi/pl022.h"
79
#include "hw/devices.h"
80
diff --git a/MAINTAINERS b/MAINTAINERS
81
index XXXXXXX..XXXXXXX 100644
82
--- a/MAINTAINERS
83
+++ b/MAINTAINERS
84
@@ -XXX,XX +XXX,XX @@ F: hw/arm/mps2.c
85
F: hw/arm/mps2-tz.c
86
F: hw/misc/mps2-*.c
87
F: include/hw/misc/mps2-*.h
88
-F: hw/arm/iotkit.c
89
-F: include/hw/arm/iotkit.h
90
+F: hw/arm/armsse.c
91
+F: include/hw/arm/armsse.h
92
F: hw/misc/iotkit-secctl.c
93
F: include/hw/misc/iotkit-secctl.h
94
F: hw/misc/iotkit-sysctl.c
95
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
96
index XXXXXXX..XXXXXXX 100644
97
--- a/default-configs/arm-softmmu.mak
98
+++ b/default-configs/arm-softmmu.mak
99
@@ -XXX,XX +XXX,XX @@ CONFIG_MPS2_SCC=y
100
CONFIG_TZ_MPC=y
101
CONFIG_TZ_MSC=y
102
CONFIG_TZ_PPC=y
103
-CONFIG_IOTKIT=y
104
+CONFIG_ARMSSE=y
105
CONFIG_IOTKIT_SECCTL=y
106
CONFIG_IOTKIT_SYSCTL=y
107
CONFIG_IOTKIT_SYSINFO=y
108
--
109
2.20.1
110
111
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has 4 banks of SRAM, each with its own internal
2
Memory Protection Controller. The interrupt status for these
3
extra MPCs appears in the same security controller SECMPCINTSTATUS
4
register as the MPC for the IoTKit's single SRAM bank. Enhance the
5
iotkit-secctl device to allow 4 MPCs. (If the particular IoTKit/SSE
6
variant in use does not have all 4 MPCs then the unused inputs will
7
simply result in the SECMPCINTSTATUS bits being zero as required.)
8
1
9
The hardcoded constant "1"s in armsse.c indicate the actual number
10
of SRAM MPCs the IoTKit has, and will be replaced in the following
11
commit.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190121185118.18550-9-peter.maydell@linaro.org
16
---
17
include/hw/misc/iotkit-secctl.h | 6 +++---
18
hw/arm/armsse.c | 6 +++---
19
hw/misc/iotkit-secctl.c | 5 +++--
20
3 files changed, 9 insertions(+), 8 deletions(-)
21
22
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/misc/iotkit-secctl.h
25
+++ b/include/hw/misc/iotkit-secctl.h
26
@@ -XXX,XX +XXX,XX @@
27
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
28
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
29
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
30
- * Controlling the MPC in the IoTKit:
31
- * + named GPIO input mpc_status
32
+ * Controlling the (up to) 4 MPCs in the IoTKit/SSE:
33
+ * + named GPIO inputs mpc_status[0..3]
34
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
35
* might provide:
36
* + named GPIO inputs mpcexp_status[0..15]
37
@@ -XXX,XX +XXX,XX @@
38
#define IOTS_NUM_APB_EXP_PPC 4
39
#define IOTS_NUM_AHB_EXP_PPC 4
40
#define IOTS_NUM_EXP_MPC 16
41
-#define IOTS_NUM_MPC 1
42
+#define IOTS_NUM_MPC 4
43
#define IOTS_NUM_EXP_MSC 16
44
45
typedef struct IoTKitSecCtl IoTKitSecCtl;
46
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/armsse.c
49
+++ b/hw/arm/armsse.c
50
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
51
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
52
&error_abort, NULL);
53
54
- for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
55
+ for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
56
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
57
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
58
59
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
60
61
/* We must OR together lines from the MPC splitters to go to the NVIC */
62
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
63
- IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
64
+ IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
65
if (err) {
66
error_propagate(errp, err);
67
return;
68
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
69
}
70
71
/* Wire up the splitters for the MPC IRQs */
72
- for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
73
+ for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
74
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
75
DeviceState *dev_splitter = DEVICE(splitter);
76
77
diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/misc/iotkit-secctl.c
80
+++ b/hw/misc/iotkit-secctl.c
81
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_mpc_status(void *opaque, int n, int level)
82
{
83
IoTKitSecCtl *s = IOTKIT_SECCTL(opaque);
84
85
- s->mpcintstatus = deposit32(s->mpcintstatus, 0, 1, !!level);
86
+ s->mpcintstatus = deposit32(s->mpcintstatus, n, 1, !!level);
87
}
88
89
static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
90
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
91
qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
92
qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
93
94
- qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1);
95
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
96
+ IOTS_NUM_MPC);
97
qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
98
"mpcexp_status", IOTS_NUM_EXP_MPC);
99
100
--
101
2.20.1
102
103
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has four banks of SRAM, each with its own
2
Memory Protection Controller, where the IoTKit has only one.
3
Make the number of SRAM banks a field in ARMSSEInfo.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-10-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 9 +++--
10
hw/arm/armsse.c | 78 ++++++++++++++++++++++++++---------------
11
2 files changed, 56 insertions(+), 31 deletions(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
19
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
20
21
+#define MAX_SRAM_BANKS 4
22
+#if MAX_SRAM_BANKS > IOTS_NUM_MPC
23
+#error Too many SRAM banks
24
+#endif
25
+
26
typedef struct ARMSSE {
27
/*< private >*/
28
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
30
IoTKitSecCtl secctl;
31
TZPPC apb_ppc0;
32
TZPPC apb_ppc1;
33
- TZMPC mpc;
34
+ TZMPC mpc[IOTS_NUM_MPC];
35
CMSDKAPBTIMER timer0;
36
CMSDKAPBTIMER timer1;
37
CMSDKAPBTIMER s32ktimer;
38
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
39
MemoryRegion alias1;
40
MemoryRegion alias2;
41
MemoryRegion alias3;
42
- MemoryRegion sram0;
43
+ MemoryRegion sram[MAX_SRAM_BANKS];
44
45
qemu_irq *exp_irqs;
46
qemu_irq ppc0_irq;
47
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/armsse.c
50
+++ b/hw/arm/armsse.c
51
@@ -XXX,XX +XXX,XX @@
52
53
struct ARMSSEInfo {
54
const char *name;
55
+ int sram_banks;
56
};
57
58
static const ARMSSEInfo armsse_variants[] = {
59
{
60
.name = TYPE_IOTKIT,
61
+ .sram_banks = 1,
62
},
63
};
64
65
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
66
static void armsse_init(Object *obj)
67
{
68
ARMSSE *s = ARMSSE(obj);
69
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
70
+ const ARMSSEInfo *info = asc->info;
71
int i;
72
73
+ assert(info->sram_banks <= MAX_SRAM_BANKS);
74
+
75
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
76
77
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
78
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
79
TYPE_TZ_PPC);
80
sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
81
TYPE_TZ_PPC);
82
- sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
83
+ for (i = 0; i < info->sram_banks; i++) {
84
+ char *name = g_strdup_printf("mpc%d", i);
85
+ sysbus_init_child_obj(obj, name, &s->mpc[i],
86
+ sizeof(s->mpc[i]), TYPE_TZ_MPC);
87
+ g_free(name);
88
+ }
89
object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
90
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
91
&error_abort, NULL);
92
93
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
94
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
95
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
96
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
97
98
@@ -XXX,XX +XXX,XX @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
99
static void armsse_realize(DeviceState *dev, Error **errp)
100
{
101
ARMSSE *s = ARMSSE(dev);
102
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
103
+ const ARMSSEInfo *info = asc->info;
104
int i;
105
MemoryRegion *mr;
106
Error *err = NULL;
107
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
108
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
109
qdev_get_gpio_in(dev_splitter, 0));
110
111
- /* This RAM lives behind the Memory Protection Controller */
112
- memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
113
- if (err) {
114
- error_propagate(errp, err);
115
- return;
116
+ /* Each SRAM bank lives behind its own Memory Protection Controller */
117
+ for (i = 0; i < info->sram_banks; i++) {
118
+ char *ramname = g_strdup_printf("armsse.sram%d", i);
119
+ SysBusDevice *sbd_mpc;
120
+
121
+ memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
122
+ g_free(ramname);
123
+ if (err) {
124
+ error_propagate(errp, err);
125
+ return;
126
+ }
127
+ object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
128
+ "downstream", &err);
129
+ if (err) {
130
+ error_propagate(errp, err);
131
+ return;
132
+ }
133
+ object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
134
+ if (err) {
135
+ error_propagate(errp, err);
136
+ return;
137
+ }
138
+ /* Map the upstream end of the MPC into the right place... */
139
+ sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
140
+ memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
141
+ sysbus_mmio_get_region(sbd_mpc, 1));
142
+ /* ...and its register interface */
143
+ memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
144
+ sysbus_mmio_get_region(sbd_mpc, 0));
145
}
146
- object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
147
- "downstream", &err);
148
- if (err) {
149
- error_propagate(errp, err);
150
- return;
151
- }
152
- object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
153
- if (err) {
154
- error_propagate(errp, err);
155
- return;
156
- }
157
- /* Map the upstream end of the MPC into the right place... */
158
- memory_region_add_subregion(&s->container, 0x20000000,
159
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
160
- 1));
161
- /* ...and its register interface */
162
- memory_region_add_subregion(&s->container, 0x50083000,
163
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
164
- 0));
165
166
/* We must OR together lines from the MPC splitters to go to the NVIC */
167
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
168
- IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
169
+ IOTS_NUM_EXP_MPC + info->sram_banks,
170
+ "num-lines", &err);
171
if (err) {
172
error_propagate(errp, err);
173
return;
174
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
175
}
176
177
/* Wire up the splitters for the MPC IRQs */
178
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
179
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
180
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
181
DeviceState *dev_splitter = DEVICE(splitter);
182
183
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
184
"mpcexp_status", i));
185
} else {
186
/* Splitter input is from our own MPC */
187
- qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
188
+ qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
189
+ "irq", 0,
190
qdev_get_gpio_in(dev_splitter, 0));
191
qdev_connect_gpio_out(dev_splitter, 0,
192
qdev_get_gpio_in_named(dev_secctl,
193
--
194
2.20.1
195
196
diff view generated by jsdifflib
Deleted patch
1
For the IoTKit the SRAM bank size is always 32K (15 bits); for the
2
SSE-200 this is a configurable parameter, which defaults to 32K but
3
can be changed when it is built into a particular SoC. For instance
4
the Musca-B1 board sets it to 128K (17 bits).
5
1
6
Make the bank size a QOM property. We follow the SSE-200 hardware in
7
naming the parameter SRAM_ADDR_WIDTH, which specifies the number of
8
address bits of a single SRAM bank.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190121185118.18550-11-peter.maydell@linaro.org
13
---
14
include/hw/arm/armsse.h | 1 +
15
hw/arm/armsse.c | 18 ++++++++++++++++--
16
2 files changed, 17 insertions(+), 2 deletions(-)
17
18
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/armsse.h
21
+++ b/include/hw/arm/armsse.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
23
MemoryRegion *board_memory;
24
uint32_t exp_numirq;
25
uint32_t mainclk_frq;
26
+ uint32_t sram_addr_width;
27
} ARMSSE;
28
29
typedef struct ARMSSEInfo ARMSSEInfo;
30
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/armsse.c
33
+++ b/hw/arm/armsse.c
34
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
35
DeviceState *dev_apb_ppc1;
36
DeviceState *dev_secctl;
37
DeviceState *dev_splitter;
38
+ uint32_t addr_width_max;
39
40
if (!s->board_memory) {
41
error_setg(errp, "memory property was not set");
42
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
43
return;
44
}
45
46
+ /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
47
+ assert(is_power_of_2(info->sram_banks));
48
+ addr_width_max = 24 - ctz32(info->sram_banks);
49
+ if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
50
+ error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
51
+ addr_width_max);
52
+ return;
53
+ }
54
+
55
/* Handling of which devices should be available only to secure
56
* code is usually done differently for M profile than for A profile.
57
* Instead of putting some devices only into the secure address space,
58
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
59
for (i = 0; i < info->sram_banks; i++) {
60
char *ramname = g_strdup_printf("armsse.sram%d", i);
61
SysBusDevice *sbd_mpc;
62
+ uint32_t sram_bank_size = 1 << s->sram_addr_width;
63
64
- memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
65
+ memory_region_init_ram(&s->sram[i], NULL, ramname,
66
+ sram_bank_size, &err);
67
g_free(ramname);
68
if (err) {
69
error_propagate(errp, err);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
}
72
/* Map the upstream end of the MPC into the right place... */
73
sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
74
- memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
75
+ memory_region_add_subregion(&s->container,
76
+ 0x20000000 + i * sram_bank_size,
77
sysbus_mmio_get_region(sbd_mpc, 1));
78
/* ...and its register interface */
79
memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
80
@@ -XXX,XX +XXX,XX @@ static Property armsse_properties[] = {
81
MemoryRegion *),
82
DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
83
DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
84
+ DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
85
DEFINE_PROP_END_OF_LIST()
86
};
87
88
--
89
2.20.1
90
91
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has two Cortex-M33 CPUs. These see the same view
2
of memory, with the exception of the "private CPU region" which
3
has per-CPU devices. Internal device interrupts for SSE-200
4
devices are mostly wired up to both CPUs, with the exception of
5
a few per-CPU devices. External GPIO inputs on the SSE-200
6
device are provided for the second CPU's interrupts above 32,
7
as is already the case for the first CPU.
8
1
9
Refactor the code to support creation of multiple CPUs.
10
For the moment we leave all CPUs with the same view of
11
memory: this will not work in the multiple-CPU case, but
12
we will fix this in the following commit.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20190121185118.18550-12-peter.maydell@linaro.org
17
---
18
include/hw/arm/armsse.h | 21 +++-
19
hw/arm/armsse.c | 206 ++++++++++++++++++++++++++++++++--------
20
2 files changed, 180 insertions(+), 47 deletions(-)
21
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/armsse.h
25
+++ b/include/hw/arm/armsse.h
26
@@ -XXX,XX +XXX,XX @@
27
* + QOM property "memory" is a MemoryRegion containing the devices provided
28
* by the board model.
29
* + QOM property "MAINCLK" is the frequency of the main system clock
30
- * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts
31
- * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which
32
- * are wired to the NVIC lines 32 .. n+32
33
+ * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts.
34
+ * (In hardware, the SSE-200 permits the number of expansion interrupts
35
+ * for the two CPUs to be configured separately, but we restrict it to
36
+ * being the same for both, to avoid having to have separate Property
37
+ * lists for different variants. This restriction can be relaxed later
38
+ * if necessary.)
39
+ * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts for CPU 0,
40
+ * which are wired to its NVIC lines 32 .. n+32
41
+ * + Named GPIO inputs "EXP_CPU1_IRQ" 0..n are the expansion interrupts for
42
+ * CPU 1, which are wired to its NVIC lines 32 .. n+32
43
* + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows
44
* bus master devices in the board model to make transactions into
45
* all the devices and memory areas in the IoTKit
46
@@ -XXX,XX +XXX,XX @@
47
#error Too many SRAM banks
48
#endif
49
50
+#define SSE_MAX_CPUS 2
51
+
52
typedef struct ARMSSE {
53
/*< private >*/
54
SysBusDevice parent_obj;
55
56
/*< public >*/
57
- ARMv7MState armv7m;
58
+ ARMv7MState armv7m[SSE_MAX_CPUS];
59
IoTKitSecCtl secctl;
60
TZPPC apb_ppc0;
61
TZPPC apb_ppc1;
62
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
63
qemu_or_irq mpc_irq_orgate;
64
qemu_or_irq nmi_orgate;
65
66
+ SplitIRQ cpu_irq_splitter[32];
67
+
68
CMSDKAPBDualTimer dualtimer;
69
70
CMSDKAPBWatchdog s32kwatchdog;
71
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
72
MemoryRegion alias3;
73
MemoryRegion sram[MAX_SRAM_BANKS];
74
75
- qemu_irq *exp_irqs;
76
+ qemu_irq *exp_irqs[SSE_MAX_CPUS];
77
qemu_irq ppc0_irq;
78
qemu_irq ppc1_irq;
79
qemu_irq sec_resp_cfg;
80
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/armsse.c
83
+++ b/hw/arm/armsse.c
84
@@ -XXX,XX +XXX,XX @@
85
struct ARMSSEInfo {
86
const char *name;
87
int sram_banks;
88
+ int num_cpus;
89
};
90
91
static const ARMSSEInfo armsse_variants[] = {
92
{
93
.name = TYPE_IOTKIT,
94
.sram_banks = 1,
95
+ .num_cpus = 1,
96
},
97
};
98
99
/* Clock frequency in HZ of the 32KHz "slow clock" */
100
#define S32KCLK (32 * 1000)
101
102
+/* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
103
+static bool irq_is_common[32] = {
104
+ [0 ... 5] = true,
105
+ /* 6, 7: per-CPU MHU interrupts */
106
+ [8 ... 12] = true,
107
+ /* 13: per-CPU icache interrupt */
108
+ /* 14: reserved */
109
+ [15 ... 20] = true,
110
+ /* 21: reserved */
111
+ [22 ... 26] = true,
112
+ /* 27: reserved */
113
+ /* 28, 29: per-CPU CTI interrupts */
114
+ /* 30, 31: reserved */
115
+};
116
+
117
/* Create an alias region of @size bytes starting at @base
118
* which mirrors the memory starting at @orig.
119
*/
120
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
121
int i;
122
123
assert(info->sram_banks <= MAX_SRAM_BANKS);
124
+ assert(info->num_cpus <= SSE_MAX_CPUS);
125
126
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
127
128
- sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
129
- TYPE_ARMV7M);
130
- qdev_prop_set_string(DEVICE(&s->armv7m), "cpu-type",
131
- ARM_CPU_TYPE_NAME("cortex-m33"));
132
+ for (i = 0; i < info->num_cpus; i++) {
133
+ char *name = g_strdup_printf("armv7m%d", i);
134
+ sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
135
+ TYPE_ARMV7M);
136
+ qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
137
+ ARM_CPU_TYPE_NAME("cortex-m33"));
138
+ g_free(name);
139
+ }
140
141
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
142
TYPE_IOTKIT_SECCTL);
143
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
144
TYPE_SPLIT_IRQ, &error_abort, NULL);
145
g_free(name);
146
}
147
+ if (info->num_cpus > 1) {
148
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
149
+ if (irq_is_common[i]) {
150
+ char *name = g_strdup_printf("cpu-irq-splitter%d", i);
151
+ SplitIRQ *splitter = &s->cpu_irq_splitter[i];
152
+
153
+ object_initialize_child(obj, name, splitter, sizeof(*splitter),
154
+ TYPE_SPLIT_IRQ, &error_abort, NULL);
155
+ g_free(name);
156
+ }
157
+ }
158
+ }
159
}
160
161
static void armsse_exp_irq(void *opaque, int n, int level)
162
{
163
- ARMSSE *s = ARMSSE(opaque);
164
+ qemu_irq *irqarray = opaque;
165
166
- qemu_set_irq(s->exp_irqs[n], level);
167
+ qemu_set_irq(irqarray[n], level);
168
}
169
170
static void armsse_mpcexp_status(void *opaque, int n, int level)
171
@@ -XXX,XX +XXX,XX @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
172
qemu_set_irq(s->mpcexp_status_in[n], level);
173
}
174
175
+static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
176
+{
177
+ /*
178
+ * Return a qemu_irq which can be used to signal IRQ n to
179
+ * all CPUs in the SSE.
180
+ */
181
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
182
+ const ARMSSEInfo *info = asc->info;
183
+
184
+ assert(irq_is_common[irqno]);
185
+
186
+ if (info->num_cpus == 1) {
187
+ /* Only one CPU -- just connect directly to it */
188
+ return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
189
+ } else {
190
+ /* Connect to the splitter which feeds all CPUs */
191
+ return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
192
+ }
193
+}
194
+
195
static void armsse_realize(DeviceState *dev, Error **errp)
196
{
197
ARMSSE *s = ARMSSE(dev);
198
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
199
200
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
201
202
- qdev_prop_set_uint32(DEVICE(&s->armv7m), "num-irq", s->exp_numirq + 32);
203
- /* In real hardware the initial Secure VTOR is set from the INITSVTOR0
204
- * register in the IoT Kit System Control Register block, and the
205
- * initial value of that is in turn specifiable by the FPGA that
206
- * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
207
- * and simply set the CPU's init-svtor to the IoT Kit default value.
208
- */
209
- qdev_prop_set_uint32(DEVICE(&s->armv7m), "init-svtor", 0x10000000);
210
- object_property_set_link(OBJECT(&s->armv7m), OBJECT(&s->container),
211
- "memory", &err);
212
- if (err) {
213
- error_propagate(errp, err);
214
- return;
215
- }
216
- object_property_set_link(OBJECT(&s->armv7m), OBJECT(s), "idau", &err);
217
- if (err) {
218
- error_propagate(errp, err);
219
- return;
220
- }
221
- object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
222
- if (err) {
223
- error_propagate(errp, err);
224
- return;
225
+ for (i = 0; i < info->num_cpus; i++) {
226
+ DeviceState *cpudev = DEVICE(&s->armv7m[i]);
227
+ Object *cpuobj = OBJECT(&s->armv7m[i]);
228
+ int j;
229
+ char *gpioname;
230
+
231
+ qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + 32);
232
+ /*
233
+ * In real hardware the initial Secure VTOR is set from the INITSVTOR0
234
+ * register in the IoT Kit System Control Register block, and the
235
+ * initial value of that is in turn specifiable by the FPGA that
236
+ * instantiates the IoT Kit. In QEMU we don't implement this wrinkle,
237
+ * and simply set the CPU's init-svtor to the IoT Kit default value.
238
+ * In SSE-200 the situation is similar, except that the default value
239
+ * is a reset-time signal input. Typically a board using the SSE-200
240
+ * will have a system control processor whose boot firmware initializes
241
+ * the INITSVTOR* registers before powering up the CPUs in any case,
242
+ * so the hardware's default value doesn't matter. QEMU doesn't emulate
243
+ * the control processor, so instead we behave in the way that the
244
+ * firmware does. All boards currently known about have firmware that
245
+ * sets the INITSVTOR0 and INITSVTOR1 registers to 0x10000000, like the
246
+ * IoTKit default. We can make this more configurable if necessary.
247
+ */
248
+ qdev_prop_set_uint32(cpudev, "init-svtor", 0x10000000);
249
+ /*
250
+ * Start all CPUs except CPU0 powered down. In real hardware it is
251
+ * a configurable property of the SSE-200 which CPUs start powered up
252
+ * (via the CPUWAIT0_RST and CPUWAIT1_RST parameters), but since all
253
+ * the boards we care about start CPU0 and leave CPU1 powered off,
254
+ * we hard-code that for now. We can add QOM properties for this
255
+ * later if necessary.
256
+ */
257
+ if (i > 0) {
258
+ object_property_set_bool(cpuobj, true, "start-powered-off", &err);
259
+ if (err) {
260
+ error_propagate(errp, err);
261
+ return;
262
+ }
263
+ }
264
+ object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
265
+ if (err) {
266
+ error_propagate(errp, err);
267
+ return;
268
+ }
269
+ object_property_set_link(cpuobj, OBJECT(s), "idau", &err);
270
+ if (err) {
271
+ error_propagate(errp, err);
272
+ return;
273
+ }
274
+ object_property_set_bool(cpuobj, true, "realized", &err);
275
+ if (err) {
276
+ error_propagate(errp, err);
277
+ return;
278
+ }
279
+
280
+ /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
281
+ s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
282
+ for (j = 0; j < s->exp_numirq; j++) {
283
+ s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, i + 32);
284
+ }
285
+ if (i == 0) {
286
+ gpioname = g_strdup("EXP_IRQ");
287
+ } else {
288
+ gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
289
+ }
290
+ qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
291
+ s->exp_irqs[i],
292
+ gpioname, s->exp_numirq);
293
+ g_free(gpioname);
294
}
295
296
- /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
297
- s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
298
- for (i = 0; i < s->exp_numirq; i++) {
299
- s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
300
+ /* Wire up the splitters that connect common IRQs to all CPUs */
301
+ if (info->num_cpus > 1) {
302
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
303
+ if (irq_is_common[i]) {
304
+ Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
305
+ DeviceState *devs = DEVICE(splitter);
306
+ int cpunum;
307
+
308
+ object_property_set_int(splitter, info->num_cpus,
309
+ "num-lines", &err);
310
+ if (err) {
311
+ error_propagate(errp, err);
312
+ return;
313
+ }
314
+ object_property_set_bool(splitter, true, "realized", &err);
315
+ if (err) {
316
+ error_propagate(errp, err);
317
+ return;
318
+ }
319
+ for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
320
+ DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
321
+
322
+ qdev_connect_gpio_out(devs, cpunum,
323
+ qdev_get_gpio_in(cpudev, i));
324
+ }
325
+ }
326
+ }
327
}
328
- qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
329
330
/* Set up the big aliases first */
331
make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
332
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
333
return;
334
}
335
qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
336
- qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
337
+ armsse_get_common_irq_in(s, 9));
338
339
/* Devices behind APB PPC0:
340
* 0x40000000: timer0
341
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
342
return;
343
}
344
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
345
- qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
346
+ armsse_get_common_irq_in(s, 3));
347
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
348
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
349
if (err) {
350
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
351
return;
352
}
353
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer1), 0,
354
- qdev_get_gpio_in(DEVICE(&s->armv7m), 4));
355
+ armsse_get_common_irq_in(s, 4));
356
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer1), 0);
357
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[1]", &err);
358
if (err) {
359
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
360
return;
361
}
362
sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0,
363
- qdev_get_gpio_in(DEVICE(&s->armv7m), 5));
364
+ armsse_get_common_irq_in(s, 5));
365
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0);
366
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err);
367
if (err) {
368
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
369
return;
370
}
371
qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
372
- qdev_get_gpio_in(DEVICE(&s->armv7m), 10));
373
+ armsse_get_common_irq_in(s, 10));
374
375
/* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
376
377
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
378
return;
379
}
380
sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0,
381
- qdev_get_gpio_in(DEVICE(&s->armv7m), 2));
382
+ armsse_get_common_irq_in(s, 2));
383
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0);
384
object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err);
385
if (err) {
386
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
387
return;
388
}
389
sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0,
390
- qdev_get_gpio_in(DEVICE(&s->armv7m), 1));
391
+ armsse_get_common_irq_in(s, 1));
392
sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000);
393
394
qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq);
395
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
396
qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
397
qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
398
qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
399
- qdev_get_gpio_in(DEVICE(&s->armv7m), 11));
400
+ armsse_get_common_irq_in(s, 11));
401
402
/*
403
* Expose our container region to the board model; this corresponds
404
--
405
2.20.1
406
407
diff view generated by jsdifflib
Deleted patch
1
Give each CPU its own container memory region. This is necessary
2
for two reasons:
3
* some devices are instantiated one per CPU and the CPU sees only
4
its own device
5
* since a memory region can only be put into one container, we must
6
give each armv7m object a different MemoryRegion as its 'memory'
7
property, or a dual-CPU configuration will assert on realize when
8
the second armv7m object tries to put the MR into a container when
9
it is already in the first armv7m object's container
10
1
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-13-peter.maydell@linaro.org
14
---
15
include/hw/arm/armsse.h | 10 ++++++++++
16
hw/arm/armsse.c | 22 ++++++++++++++++++++--
17
2 files changed, 30 insertions(+), 2 deletions(-)
18
19
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/armsse.h
22
+++ b/include/hw/arm/armsse.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
24
IoTKitSysCtl sysctl;
25
IoTKitSysCtl sysinfo;
26
27
+ /*
28
+ * 'container' holds all devices seen by all CPUs.
29
+ * 'cpu_container[i]' is the view that CPU i has: this has the
30
+ * per-CPU devices of that CPU, plus as the background 'container'
31
+ * (or an alias of it, since we can only use it directly once).
32
+ * container_alias[i] is the alias of 'container' used by CPU i+1;
33
+ * CPU 0 can use 'container' directly.
34
+ */
35
MemoryRegion container;
36
+ MemoryRegion container_alias[SSE_MAX_CPUS - 1];
37
+ MemoryRegion cpu_container[SSE_MAX_CPUS];
38
MemoryRegion alias1;
39
MemoryRegion alias2;
40
MemoryRegion alias3;
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/armsse.c
44
+++ b/hw/arm/armsse.c
45
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
46
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
47
ARM_CPU_TYPE_NAME("cortex-m33"));
48
g_free(name);
49
+ name = g_strdup_printf("arm-sse-cpu-container%d", i);
50
+ memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
51
+ g_free(name);
52
+ if (i > 0) {
53
+ name = g_strdup_printf("arm-sse-container-alias%d", i);
54
+ memory_region_init_alias(&s->container_alias[i - 1], obj,
55
+ name, &s->container, 0, UINT64_MAX);
56
+ g_free(name);
57
+ }
58
}
59
60
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
63
*/
64
65
- memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
66
+ memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
67
68
for (i = 0; i < info->num_cpus; i++) {
69
DeviceState *cpudev = DEVICE(&s->armv7m[i]);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
return;
72
}
73
}
74
- object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
75
+
76
+ if (i > 0) {
77
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
78
+ &s->container_alias[i - 1], -1);
79
+ } else {
80
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
81
+ &s->container, -1);
82
+ }
83
+ object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
84
+ "memory", &err);
85
if (err) {
86
error_propagate(errp, err);
87
return;
88
--
89
2.20.1
90
91
diff view generated by jsdifflib
Deleted patch
1
Create a cluster object to hold each CPU in the SSE. They are
2
logically distinct and may be configured differently (for instance
3
one may not have an FPU where the other does).
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-14-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 2 ++
10
hw/arm/armsse.c | 31 ++++++++++++++++++++++++++++---
11
2 files changed, 30 insertions(+), 3 deletions(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/misc/iotkit-sysinfo.h"
19
#include "hw/or-irq.h"
20
#include "hw/core/split-irq.h"
21
+#include "hw/cpu/cluster.h"
22
23
#define TYPE_ARMSSE "arm-sse"
24
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
27
/*< public >*/
28
ARMv7MState armv7m[SSE_MAX_CPUS];
29
+ CPUClusterState cluster[SSE_MAX_CPUS];
30
IoTKitSecCtl secctl;
31
TZPPC apb_ppc0;
32
TZPPC apb_ppc1;
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
38
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
39
40
for (i = 0; i < info->num_cpus; i++) {
41
- char *name = g_strdup_printf("armv7m%d", i);
42
- sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
43
- TYPE_ARMV7M);
44
+ /*
45
+ * We put each CPU in its own cluster as they are logically
46
+ * distinct and may be configured differently.
47
+ */
48
+ char *name;
49
+
50
+ name = g_strdup_printf("cluster%d", i);
51
+ object_initialize_child(obj, name, &s->cluster[i],
52
+ sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
53
+ &error_abort, NULL);
54
+ qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
55
+ g_free(name);
56
+
57
+ name = g_strdup_printf("armv7m%d", i);
58
+ sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
59
+ &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
60
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
61
ARM_CPU_TYPE_NAME("cortex-m33"));
62
g_free(name);
63
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
64
error_propagate(errp, err);
65
return;
66
}
67
+ /*
68
+ * The cluster must be realized after the armv7m container, as
69
+ * the container's CPU object is only created on realize, and the
70
+ * CPU must exist and have been parented into the cluster before
71
+ * the cluster is realized.
72
+ */
73
+ object_property_set_bool(OBJECT(&s->cluster[i]),
74
+ true, "realized", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
80
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
81
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
Deleted patch
1
The SYS_VERSION and SYS_CONFIG register values differ between the
2
IoTKit and SSE-200. Make them configurable via QOM properties rather
3
than hard-coded, and set them appropriately in the ARMSSE code that
4
instantiates the IOTKIT_SYSINFO device.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-15-peter.maydell@linaro.org
9
---
10
include/hw/misc/iotkit-sysinfo.h | 6 ++++
11
hw/arm/armsse.c | 51 ++++++++++++++++++++++++++++++++
12
hw/misc/iotkit-sysinfo.c | 15 ++++++++--
13
3 files changed, 70 insertions(+), 2 deletions(-)
14
15
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/iotkit-sysinfo.h
18
+++ b/include/hw/misc/iotkit-sysinfo.h
19
@@ -XXX,XX +XXX,XX @@
20
* Arm IoTKit and documented in
21
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
22
* QEMU interface:
23
+ * + QOM property "SYS_VERSION": value to use for SYS_VERSION register
24
+ * + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
25
* + sysbus MMIO region 0: the system information register bank
26
*/
27
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysInfo {
29
30
/*< public >*/
31
MemoryRegion iomem;
32
+
33
+ /* Properties */
34
+ uint32_t sys_version;
35
+ uint32_t sys_config;
36
} IoTKitSysInfo;
37
38
#endif
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/armsse.c
42
+++ b/hw/arm/armsse.c
43
@@ -XXX,XX +XXX,XX @@
44
#include "hw/arm/armsse.h"
45
#include "hw/arm/arm.h"
46
47
+/* Format of the System Information block SYS_CONFIG register */
48
+typedef enum SysConfigFormat {
49
+ IoTKitFormat,
50
+ SSE200Format,
51
+} SysConfigFormat;
52
+
53
struct ARMSSEInfo {
54
const char *name;
55
int sram_banks;
56
int num_cpus;
57
+ uint32_t sys_version;
58
+ SysConfigFormat sys_config_format;
59
};
60
61
static const ARMSSEInfo armsse_variants[] = {
62
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
63
.name = TYPE_IOTKIT,
64
.sram_banks = 1,
65
.num_cpus = 1,
66
+ .sys_version = 0x41743,
67
+ .sys_config_format = IoTKitFormat,
68
},
69
};
70
71
+static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
72
+{
73
+ /* Return the SYS_CONFIG value for this SSE */
74
+ uint32_t sys_config;
75
+
76
+ switch (info->sys_config_format) {
77
+ case IoTKitFormat:
78
+ sys_config = 0;
79
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
80
+ sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
81
+ break;
82
+ case SSE200Format:
83
+ sys_config = 0;
84
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
85
+ sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
86
+ sys_config = deposit32(sys_config, 24, 4, 2);
87
+ if (info->num_cpus > 1) {
88
+ sys_config = deposit32(sys_config, 10, 1, 1);
89
+ sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
90
+ sys_config = deposit32(sys_config, 28, 4, 2);
91
+ }
92
+ break;
93
+ default:
94
+ g_assert_not_reached();
95
+ }
96
+ return sys_config;
97
+}
98
+
99
/* Clock frequency in HZ of the 32KHz "slow clock" */
100
#define S32KCLK (32 * 1000)
101
102
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
103
qdev_get_gpio_in_named(dev_apb_ppc1,
104
"cfg_sec_resp", 0));
105
106
+ object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
107
+ "SYS_VERSION", &err);
108
+ if (err) {
109
+ error_propagate(errp, err);
110
+ return;
111
+ }
112
+ object_property_set_int(OBJECT(&s->sysinfo),
113
+ armsse_sys_config_value(s, info),
114
+ "SYS_CONFIG", &err);
115
+ if (err) {
116
+ error_propagate(errp, err);
117
+ return;
118
+ }
119
object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
120
if (err) {
121
error_propagate(errp, err);
122
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/misc/iotkit-sysinfo.c
125
+++ b/hw/misc/iotkit-sysinfo.c
126
@@ -XXX,XX +XXX,XX @@ static const int sysinfo_id[] = {
127
static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
128
unsigned size)
129
{
130
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
131
uint64_t r;
132
133
switch (offset) {
134
case A_SYS_VERSION:
135
- r = 0x41743;
136
+ r = s->sys_version;
137
break;
138
139
case A_SYS_CONFIG:
140
- r = 0x31;
141
+ r = s->sys_config;
142
break;
143
case A_PID4 ... A_CID3:
144
r = sysinfo_id[(offset - A_PID4) / 4];
145
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
146
.valid.max_access_size = 4,
147
};
148
149
+static Property iotkit_sysinfo_props[] = {
150
+ DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
151
+ DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
152
+ DEFINE_PROP_END_OF_LIST()
153
+};
154
+
155
static void iotkit_sysinfo_init(Object *obj)
156
{
157
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
158
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_init(Object *obj)
159
160
static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
161
{
162
+ DeviceClass *dc = DEVICE_CLASS(klass);
163
+
164
/*
165
* This device has no guest-modifiable state and so it
166
* does not need a reset function or VMState.
167
*/
168
+
169
+ dc->props = iotkit_sysinfo_props;
170
}
171
172
static const TypeInfo iotkit_sysinfo_info = {
173
--
174
2.20.1
175
176
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has two Message Handling Units (MHUs), which sit behind
2
the APB PPC0. Wire up some unimplemented-device stubs for these,
3
since we don't yet implement a real model of this device.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-16-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 3 +++
10
hw/arm/armsse.c | 41 +++++++++++++++++++++++++++++++++++++++++
11
2 files changed, 44 insertions(+)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/watchdog/cmsdk-apb-watchdog.h"
19
#include "hw/misc/iotkit-sysctl.h"
20
#include "hw/misc/iotkit-sysinfo.h"
21
+#include "hw/misc/unimp.h"
22
#include "hw/or-irq.h"
23
#include "hw/core/split-irq.h"
24
#include "hw/cpu/cluster.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
IoTKitSysCtl sysctl;
27
IoTKitSysCtl sysinfo;
28
29
+ UnimplementedDeviceState mhu[2];
30
+
31
/*
32
* 'container' holds all devices seen by all CPUs.
33
* 'cpu_container[i]' is the view that CPU i has: this has the
34
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/armsse.c
37
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
39
int num_cpus;
40
uint32_t sys_version;
41
SysConfigFormat sys_config_format;
42
+ bool has_mhus;
43
};
44
45
static const ARMSSEInfo armsse_variants[] = {
46
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
47
.num_cpus = 1,
48
.sys_version = 0x41743,
49
.sys_config_format = IoTKitFormat,
50
+ .has_mhus = false,
51
},
52
};
53
54
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
55
sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
56
sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
57
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
58
+ if (info->has_mhus) {
59
+ sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
60
+ TYPE_UNIMPLEMENTED_DEVICE);
61
+ sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
62
+ TYPE_UNIMPLEMENTED_DEVICE);
63
+ }
64
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
65
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
66
&error_abort, NULL);
67
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
68
* 0x40000000: timer0
69
* 0x40001000: timer1
70
* 0x40002000: dual timer
71
+ * 0x40003000: MHU0 (SSE-200 only)
72
+ * 0x40004000: MHU1 (SSE-200 only)
73
* We must configure and realize each downstream device and connect
74
* it to the appropriate PPC port; then we can realize the PPC and
75
* map its upstream ends to the right place in the container.
76
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
77
return;
78
}
79
80
+ if (info->has_mhus) {
81
+ for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
82
+ char *name = g_strdup_printf("MHU%d", i);
83
+ char *port = g_strdup_printf("port[%d]", i + 3);
84
+
85
+ qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
86
+ qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
87
+ object_property_set_bool(OBJECT(&s->mhu[i]), true,
88
+ "realized", &err);
89
+ if (err) {
90
+ error_propagate(errp, err);
91
+ return;
92
+ }
93
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
94
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
95
+ port, &err);
96
+ if (err) {
97
+ error_propagate(errp, err);
98
+ return;
99
+ }
100
+ g_free(name);
101
+ g_free(port);
102
+ }
103
+ }
104
+
105
object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
106
if (err) {
107
error_propagate(errp, err);
108
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
109
memory_region_add_subregion(&s->container, 0x40001000, mr);
110
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
111
memory_region_add_subregion(&s->container, 0x40002000, mr);
112
+ if (info->has_mhus) {
113
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
114
+ memory_region_add_subregion(&s->container, 0x40003000, mr);
115
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
116
+ memory_region_add_subregion(&s->container, 0x40004000, mr);
117
+ }
118
for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
119
qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
120
qdev_get_gpio_in_named(dev_apb_ppc0,
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
Add unimplemented-device stubs for the various Power Policy Unit
2
devices that the SSE-200 has.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-17-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 11 ++++++++
9
hw/arm/armsse.c | 58 +++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 69 insertions(+)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
18
#define SSE_MAX_CPUS 2
19
20
+/* These define what each PPU in the ppu[] index is for */
21
+#define CPU0CORE_PPU 0
22
+#define CPU1CORE_PPU 1
23
+#define DBG_PPU 2
24
+#define RAM0_PPU 3
25
+#define RAM1_PPU 4
26
+#define RAM2_PPU 5
27
+#define RAM3_PPU 6
28
+#define NUM_PPUS 7
29
+
30
typedef struct ARMSSE {
31
/*< private >*/
32
SysBusDevice parent_obj;
33
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
34
IoTKitSysCtl sysinfo;
35
36
UnimplementedDeviceState mhu[2];
37
+ UnimplementedDeviceState ppu[NUM_PPUS];
38
39
/*
40
* 'container' holds all devices seen by all CPUs.
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/armsse.c
44
+++ b/hw/arm/armsse.c
45
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
46
uint32_t sys_version;
47
SysConfigFormat sys_config_format;
48
bool has_mhus;
49
+ bool has_ppus;
50
};
51
52
static const ARMSSEInfo armsse_variants[] = {
53
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
54
.sys_version = 0x41743,
55
.sys_config_format = IoTKitFormat,
56
.has_mhus = false,
57
+ .has_ppus = false,
58
},
59
};
60
61
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
62
sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
63
TYPE_UNIMPLEMENTED_DEVICE);
64
}
65
+ if (info->has_ppus) {
66
+ for (i = 0; i < info->num_cpus; i++) {
67
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
68
+ int ppuidx = CPU0CORE_PPU + i;
69
+
70
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
71
+ sizeof(s->ppu[ppuidx]),
72
+ TYPE_UNIMPLEMENTED_DEVICE);
73
+ g_free(name);
74
+ }
75
+ sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
76
+ sizeof(s->ppu[DBG_PPU]),
77
+ TYPE_UNIMPLEMENTED_DEVICE);
78
+ for (i = 0; i < info->sram_banks; i++) {
79
+ char *name = g_strdup_printf("RAM%d_PPU", i);
80
+ int ppuidx = RAM0_PPU + i;
81
+
82
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
83
+ sizeof(s->ppu[ppuidx]),
84
+ TYPE_UNIMPLEMENTED_DEVICE);
85
+ g_free(name);
86
+ }
87
+ }
88
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
89
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
90
&error_abort, NULL);
91
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
92
}
93
}
94
95
+static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
96
+{
97
+ /* Map a PPU unimplemented device stub */
98
+ DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
99
+
100
+ qdev_prop_set_string(dev, "name", name);
101
+ qdev_prop_set_uint64(dev, "size", 0x1000);
102
+ qdev_init_nofail(dev);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
104
+}
105
+
106
static void armsse_realize(DeviceState *dev, Error **errp)
107
{
108
ARMSSE *s = ARMSSE(dev);
109
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
110
}
111
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
112
113
+ if (info->has_ppus) {
114
+ /* CPUnCORE_PPU for each CPU */
115
+ for (i = 0; i < info->num_cpus; i++) {
116
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
117
+
118
+ map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
119
+ /*
120
+ * We don't support CPU debug so don't create the
121
+ * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
122
+ */
123
+ g_free(name);
124
+ }
125
+ map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
126
+
127
+ for (i = 0; i < info->sram_banks; i++) {
128
+ char *name = g_strdup_printf("RAM%d_PPU", i);
129
+
130
+ map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
131
+ g_free(name);
132
+ }
133
+ }
134
+
135
/* This OR gate wires together outputs from the secure watchdogs to NMI */
136
object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
137
if (err) {
138
--
139
2.20.1
140
141
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 gives each CPU a register bank to use to control its
2
L1 instruction cache. Put in an unimplemented-device stub for this.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-18-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 1 +
9
hw/arm/armsse.c | 39 ++++++++++++++++++++++++++++++++++++++-
10
2 files changed, 39 insertions(+), 1 deletion(-)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
17
18
UnimplementedDeviceState mhu[2];
19
UnimplementedDeviceState ppu[NUM_PPUS];
20
+ UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
21
22
/*
23
* 'container' holds all devices seen by all CPUs.
24
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/armsse.c
27
+++ b/hw/arm/armsse.c
28
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
29
SysConfigFormat sys_config_format;
30
bool has_mhus;
31
bool has_ppus;
32
+ bool has_cachectrl;
33
};
34
35
static const ARMSSEInfo armsse_variants[] = {
36
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
37
.sys_config_format = IoTKitFormat,
38
.has_mhus = false,
39
.has_ppus = false,
40
+ .has_cachectrl = false,
41
},
42
};
43
44
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
45
g_free(name);
46
}
47
}
48
+ if (info->has_cachectrl) {
49
+ for (i = 0; i < info->num_cpus; i++) {
50
+ char *name = g_strdup_printf("cachectrl%d", i);
51
+
52
+ sysbus_init_child_obj(obj, name, &s->cachectrl[i],
53
+ sizeof(s->cachectrl[i]),
54
+ TYPE_UNIMPLEMENTED_DEVICE);
55
+ g_free(name);
56
+ }
57
+ }
58
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
59
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
60
&error_abort, NULL);
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
63
armsse_get_common_irq_in(s, 10));
64
65
- /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
66
+ /*
67
+ * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
68
+ * private per-CPU region (all these devices are SSE-200 only):
69
+ * 0x50010000: L1 icache control registers
70
+ * 0x50011000: CPUSECCTRL (CPU local security control registers)
71
+ * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
72
+ */
73
+ if (info->has_cachectrl) {
74
+ for (i = 0; i < info->num_cpus; i++) {
75
+ char *name = g_strdup_printf("cachectrl%d", i);
76
+ MemoryRegion *mr;
77
+
78
+ qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
79
+ g_free(name);
80
+ qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
81
+ object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
82
+ "realized", &err);
83
+ if (err) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
89
+ memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
90
+ }
91
+ }
92
93
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
94
/* Devices behind APB PPC1:
95
--
96
2.20.1
97
98
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has a "CPU local security control" register bank; add an
2
unimplemented-device stub for it. (The register bank has only one
3
interesting register, which allows the guest to lock down changes
4
to various CPU registers so they cannot be modified further. We
5
don't support that in our Cortex-M33 model anyway.)
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190121185118.18550-19-peter.maydell@linaro.org
10
---
11
include/hw/arm/armsse.h | 1 +
12
hw/arm/armsse.c | 31 +++++++++++++++++++++++++++++++
13
2 files changed, 32 insertions(+)
14
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/armsse.h
18
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
20
UnimplementedDeviceState mhu[2];
21
UnimplementedDeviceState ppu[NUM_PPUS];
22
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
23
+ UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
24
25
/*
26
* 'container' holds all devices seen by all CPUs.
27
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/armsse.c
30
+++ b/hw/arm/armsse.c
31
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
32
bool has_mhus;
33
bool has_ppus;
34
bool has_cachectrl;
35
+ bool has_cpusecctrl;
36
};
37
38
static const ARMSSEInfo armsse_variants[] = {
39
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
40
.has_mhus = false,
41
.has_ppus = false,
42
.has_cachectrl = false,
43
+ .has_cpusecctrl = false,
44
},
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
48
g_free(name);
49
}
50
}
51
+ if (info->has_cpusecctrl) {
52
+ for (i = 0; i < info->num_cpus; i++) {
53
+ char *name = g_strdup_printf("cpusecctrl%d", i);
54
+
55
+ sysbus_init_child_obj(obj, name, &s->cpusecctrl[i],
56
+ sizeof(s->cpusecctrl[i]),
57
+ TYPE_UNIMPLEMENTED_DEVICE);
58
+ g_free(name);
59
+ }
60
+ }
61
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
62
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
63
&error_abort, NULL);
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
66
}
67
}
68
+ if (info->has_cpusecctrl) {
69
+ for (i = 0; i < info->num_cpus; i++) {
70
+ char *name = g_strdup_printf("CPUSECCTRL%d", i);
71
+ MemoryRegion *mr;
72
+
73
+ qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
74
+ g_free(name);
75
+ qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
76
+ object_property_set_bool(OBJECT(&s->cpusecctrl[i]), true,
77
+ "realized", &err);
78
+ if (err) {
79
+ error_propagate(errp, err);
80
+ return;
81
+ }
82
+
83
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
84
+ memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
85
+ }
86
+ }
87
88
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
89
/* Devices behind APB PPC1:
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has a CPU_IDENTITY register block, which is a set of
2
read-only registers. As well as the usual PID/CID registers, there
3
is a single CPUID register which indicates whether the CPU is CPU 0
4
or CPU 1. Implement a model of this register block.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-20-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/armsse-cpuid.h | 41 ++++++++++
12
hw/misc/armsse-cpuid.c | 134 ++++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
hw/misc/trace-events | 4 +
16
6 files changed, 183 insertions(+)
17
create mode 100644 include/hw/misc/armsse-cpuid.h
18
create mode 100644 hw/misc/armsse-cpuid.c
19
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/Makefile.objs
23
+++ b/hw/misc/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_TZ_PPC) += tz-ppc.o
25
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
26
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
27
obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
28
+obj-$(CONFIG_ARMSSE_CPUID) += armsse-cpuid.o
29
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
31
obj-$(CONFIG_AUX) += auxbus.o
32
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/armsse-cpuid.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * ARM SSE-200 CPU_IDENTITY register block
40
+ *
41
+ * Copyright (c) 2019 Linaro Limited
42
+ * Written by Peter Maydell
43
+ *
44
+ * This program is free software; you can redistribute it and/or modify
45
+ * it under the terms of the GNU General Public License version 2 or
46
+ * (at your option) any later version.
47
+ */
48
+
49
+/*
50
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
51
+ * Arm SSE-200 and documented in
52
+ * 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
53
+ *
54
+ * QEMU interface:
55
+ * + QOM property "CPUID": the value to use for the CPUID register
56
+ * + sysbus MMIO region 0: the system information register bank
57
+ */
58
+
59
+#ifndef HW_MISC_ARMSSE_CPUID_H
60
+#define HW_MISC_ARMSSE_CPUID_H
61
+
62
+#include "hw/sysbus.h"
63
+
64
+#define TYPE_ARMSSE_CPUID "armsse-cpuid"
65
+#define ARMSSE_CPUID(obj) OBJECT_CHECK(ARMSSECPUID, (obj), TYPE_ARMSSE_CPUID)
66
+
67
+typedef struct ARMSSECPUID {
68
+ /*< private >*/
69
+ SysBusDevice parent_obj;
70
+
71
+ /*< public >*/
72
+ MemoryRegion iomem;
73
+
74
+ /* Properties */
75
+ uint32_t cpuid;
76
+} ARMSSECPUID;
77
+
78
+#endif
79
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
80
new file mode 100644
81
index XXXXXXX..XXXXXXX
82
--- /dev/null
83
+++ b/hw/misc/armsse-cpuid.c
84
@@ -XXX,XX +XXX,XX @@
85
+/*
86
+ * ARM SSE-200 CPU_IDENTITY register block
87
+ *
88
+ * Copyright (c) 2019 Linaro Limited
89
+ * Written by Peter Maydell
90
+ *
91
+ * This program is free software; you can redistribute it and/or modify
92
+ * it under the terms of the GNU General Public License version 2 or
93
+ * (at your option) any later version.
94
+ */
95
+
96
+/*
97
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
98
+ * Arm SSE-200 and documented in
99
+ * 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
100
+ *
101
+ * It consists of one read-only CPUID register (set by QOM property), plus the
102
+ * usual ID registers.
103
+ */
104
+
105
+#include "qemu/osdep.h"
106
+#include "qemu/log.h"
107
+#include "trace.h"
108
+#include "qapi/error.h"
109
+#include "sysemu/sysemu.h"
110
+#include "hw/sysbus.h"
111
+#include "hw/registerfields.h"
112
+#include "hw/misc/armsse-cpuid.h"
113
+
114
+REG32(CPUID, 0x0)
115
+REG32(PID4, 0xfd0)
116
+REG32(PID5, 0xfd4)
117
+REG32(PID6, 0xfd8)
118
+REG32(PID7, 0xfdc)
119
+REG32(PID0, 0xfe0)
120
+REG32(PID1, 0xfe4)
121
+REG32(PID2, 0xfe8)
122
+REG32(PID3, 0xfec)
123
+REG32(CID0, 0xff0)
124
+REG32(CID1, 0xff4)
125
+REG32(CID2, 0xff8)
126
+REG32(CID3, 0xffc)
127
+
128
+/* PID/CID values */
129
+static const int sysinfo_id[] = {
130
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
131
+ 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
132
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
133
+};
134
+
135
+static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
136
+ unsigned size)
137
+{
138
+ ARMSSECPUID *s = ARMSSE_CPUID(opaque);
139
+ uint64_t r;
140
+
141
+ switch (offset) {
142
+ case A_CPUID:
143
+ r = s->cpuid;
144
+ break;
145
+ case A_PID4 ... A_CID3:
146
+ r = sysinfo_id[(offset - A_PID4) / 4];
147
+ break;
148
+ default:
149
+ qemu_log_mask(LOG_GUEST_ERROR,
150
+ "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
151
+ r = 0;
152
+ break;
153
+ }
154
+ trace_armsse_cpuid_read(offset, r, size);
155
+ return r;
156
+}
157
+
158
+static void armsse_cpuid_write(void *opaque, hwaddr offset,
159
+ uint64_t value, unsigned size)
160
+{
161
+ trace_armsse_cpuid_write(offset, value, size);
162
+
163
+ qemu_log_mask(LOG_GUEST_ERROR,
164
+ "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
165
+}
166
+
167
+static const MemoryRegionOps armsse_cpuid_ops = {
168
+ .read = armsse_cpuid_read,
169
+ .write = armsse_cpuid_write,
170
+ .endianness = DEVICE_LITTLE_ENDIAN,
171
+ /* byte/halfword accesses are just zero-padded on reads and writes */
172
+ .impl.min_access_size = 4,
173
+ .impl.max_access_size = 4,
174
+ .valid.min_access_size = 1,
175
+ .valid.max_access_size = 4,
176
+};
177
+
178
+static Property armsse_cpuid_props[] = {
179
+ DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
180
+ DEFINE_PROP_END_OF_LIST()
181
+};
182
+
183
+static void armsse_cpuid_init(Object *obj)
184
+{
185
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
186
+ ARMSSECPUID *s = ARMSSE_CPUID(obj);
187
+
188
+ memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
189
+ s, "armsse-cpuid", 0x1000);
190
+ sysbus_init_mmio(sbd, &s->iomem);
191
+}
192
+
193
+static void armsse_cpuid_class_init(ObjectClass *klass, void *data)
194
+{
195
+ DeviceClass *dc = DEVICE_CLASS(klass);
196
+
197
+ /*
198
+ * This device has no guest-modifiable state and so it
199
+ * does not need a reset function or VMState.
200
+ */
201
+
202
+ dc->props = armsse_cpuid_props;
203
+}
204
+
205
+static const TypeInfo armsse_cpuid_info = {
206
+ .name = TYPE_ARMSSE_CPUID,
207
+ .parent = TYPE_SYS_BUS_DEVICE,
208
+ .instance_size = sizeof(ARMSSECPUID),
209
+ .instance_init = armsse_cpuid_init,
210
+ .class_init = armsse_cpuid_class_init,
211
+};
212
+
213
+static void armsse_cpuid_register_types(void)
214
+{
215
+ type_register_static(&armsse_cpuid_info);
216
+}
217
+
218
+type_init(armsse_cpuid_register_types);
219
diff --git a/MAINTAINERS b/MAINTAINERS
220
index XXXXXXX..XXXXXXX 100644
221
--- a/MAINTAINERS
222
+++ b/MAINTAINERS
223
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysctl.c
224
F: include/hw/misc/iotkit-sysctl.h
225
F: hw/misc/iotkit-sysinfo.c
226
F: include/hw/misc/iotkit-sysinfo.h
227
+F: hw/misc/armsse-cpuid.c
228
+F: include/hw/misc/armsse-cpuid.h
229
230
Musicpal
231
M: Jan Kiszka <jan.kiszka@web.de>
232
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
233
index XXXXXXX..XXXXXXX 100644
234
--- a/default-configs/arm-softmmu.mak
235
+++ b/default-configs/arm-softmmu.mak
236
@@ -XXX,XX +XXX,XX @@ CONFIG_ARMSSE=y
237
CONFIG_IOTKIT_SECCTL=y
238
CONFIG_IOTKIT_SYSCTL=y
239
CONFIG_IOTKIT_SYSINFO=y
240
+CONFIG_ARMSSE_CPUID=y
241
242
CONFIG_VERSATILE=y
243
CONFIG_VERSATILE_PCI=y
244
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/misc/trace-events
247
+++ b/hw/misc/trace-events
248
@@ -XXX,XX +XXX,XX @@ iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysI
249
iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
250
iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
251
iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
252
+
253
+# hw/misc/armsse-cpuid.c
254
+armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
255
+armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
Deleted patch
1
Instantiate a copy of the CPU_IDENTITY register block for each CPU
2
in an SSE-200.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-21-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 3 +++
9
hw/arm/armsse.c | 28 ++++++++++++++++++++++++++++
10
2 files changed, 31 insertions(+)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/watchdog/cmsdk-apb-watchdog.h"
18
#include "hw/misc/iotkit-sysctl.h"
19
#include "hw/misc/iotkit-sysinfo.h"
20
+#include "hw/misc/armsse-cpuid.h"
21
#include "hw/misc/unimp.h"
22
#include "hw/or-irq.h"
23
#include "hw/core/split-irq.h"
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
25
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
26
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
27
28
+ ARMSSECPUID cpuid[SSE_MAX_CPUS];
29
+
30
/*
31
* 'container' holds all devices seen by all CPUs.
32
* 'cpu_container[i]' is the view that CPU i has: this has the
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
38
bool has_ppus;
39
bool has_cachectrl;
40
bool has_cpusecctrl;
41
+ bool has_cpuid;
42
};
43
44
static const ARMSSEInfo armsse_variants[] = {
45
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
46
.has_ppus = false,
47
.has_cachectrl = false,
48
.has_cpusecctrl = false,
49
+ .has_cpuid = false,
50
},
51
};
52
53
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
54
g_free(name);
55
}
56
}
57
+ if (info->has_cpuid) {
58
+ for (i = 0; i < info->num_cpus; i++) {
59
+ char *name = g_strdup_printf("cpuid%d", i);
60
+
61
+ sysbus_init_child_obj(obj, name, &s->cpuid[i],
62
+ sizeof(s->cpuid[i]),
63
+ TYPE_ARMSSE_CPUID);
64
+ g_free(name);
65
+ }
66
+ }
67
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
68
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
69
&error_abort, NULL);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
72
}
73
}
74
+ if (info->has_cpuid) {
75
+ for (i = 0; i < info->num_cpus; i++) {
76
+ MemoryRegion *mr;
77
+
78
+ qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
79
+ object_property_set_bool(OBJECT(&s->cpuid[i]), true,
80
+ "realized", &err);
81
+ if (err) {
82
+ error_propagate(errp, err);
83
+ return;
84
+ }
85
+
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
87
+ memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
88
+ }
89
+ }
90
91
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
92
/* Devices behind APB PPC1:
93
--
94
2.20.1
95
96
diff view generated by jsdifflib
Deleted patch
1
Add a model of the SSE-200, now we have put in all
2
the code that lets us make it different from the IoTKit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-22-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 19 ++++++++++++++++---
9
hw/arm/armsse.c | 12 ++++++++++++
10
2 files changed, 28 insertions(+), 3 deletions(-)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
/*
18
- * ARM SSE (Subsystems for Embedded): IoTKit
19
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
20
*
21
* Copyright (c) 2018 Linaro Limited
22
* Written by Peter Maydell
23
@@ -XXX,XX +XXX,XX @@
24
/*
25
* This is a model of the Arm "Subsystems for Embedded" family of
26
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
27
- * SSE-200. Currently we model only the Arm IoT Kit which is documented in
28
+ * SSE-200. Currently we model:
29
+ * - the Arm IoT Kit which is documented in
30
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
31
- * It contains:
32
+ * - the SSE-200 which is documented in
33
+ * 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
34
+ *
35
+ * The IoTKit contains:
36
* a Cortex-M33
37
* the IDAU
38
* some timers and watchdogs
39
@@ -XXX,XX +XXX,XX @@
40
* a security controller
41
* a bus fabric which arranges that some parts of the address
42
* space are secure and non-secure aliases of each other
43
+ * The SSE-200 additionally contains:
44
+ * a second Cortex-M33
45
+ * two Message Handling Units (MHUs)
46
+ * an optional CryptoCell (which we do not model)
47
+ * more SRAM banks with associated MPCs
48
+ * multiple Power Policy Units (PPUs)
49
+ * a control interface for an icache for each CPU
50
+ * per-CPU identity and control register blocks
51
*
52
* QEMU interface:
53
* + QOM property "memory" is a MemoryRegion containing the devices provided
54
@@ -XXX,XX +XXX,XX @@
55
* them via the ARMSSE base class, so they have no IOTKIT() etc macros.
56
*/
57
#define TYPE_IOTKIT "iotkit"
58
+#define TYPE_SSE200 "sse-200"
59
60
/* We have an IRQ splitter and an OR gate input for each external PPC
61
* and the 2 internal PPCs
62
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/armsse.c
65
+++ b/hw/arm/armsse.c
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
67
.has_cpusecctrl = false,
68
.has_cpuid = false,
69
},
70
+ {
71
+ .name = TYPE_SSE200,
72
+ .sram_banks = 4,
73
+ .num_cpus = 2,
74
+ .sys_version = 0x22041743,
75
+ .sys_config_format = SSE200Format,
76
+ .has_mhus = true,
77
+ .has_ppus = true,
78
+ .has_cachectrl = true,
79
+ .has_cpusecctrl = true,
80
+ .has_cpuid = true,
81
+ },
82
};
83
84
static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
Deleted patch
1
In preparation for adding support for the AN521 MPS2 image, we need
2
to handle wiring up the MPS2 device interrupt lines to both CPUs in
3
the SSE-200, rather than just the one that the IoTKit has.
4
1
5
Abstract out a "connect to the IoTKit interrupt line" function
6
and make it connect to a splitter which feeds both sets of inputs
7
for the SSE-200 case.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190121185118.18550-23-peter.maydell@linaro.org
12
---
13
hw/arm/mps2-tz.c | 79 ++++++++++++++++++++++++++++++++++++------------
14
1 file changed, 59 insertions(+), 20 deletions(-)
15
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
19
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "net/net.h"
22
#include "hw/core/split-irq.h"
23
24
+#define MPS2TZ_NUMIRQ 92
25
+
26
typedef enum MPS2TZFPGAType {
27
FPGA_AN505,
28
+ FPGA_AN521,
29
} MPS2TZFPGAType;
30
31
typedef struct {
32
@@ -XXX,XX +XXX,XX @@ typedef struct {
33
SplitIRQ sec_resp_splitter;
34
qemu_or_irq uart_irq_orgate;
35
DeviceState *lan9118;
36
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
37
} MPS2TZMachineState;
38
39
#define TYPE_MPS2TZ_MACHINE "mps2tz"
40
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
41
memory_region_add_subregion(get_system_memory(), base, mr);
42
}
43
44
+static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
45
+{
46
+ /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
47
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
48
+
49
+ assert(irqno < MPS2TZ_NUMIRQ);
50
+
51
+ switch (mmc->fpga_type) {
52
+ case FPGA_AN505:
53
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
54
+ case FPGA_AN521:
55
+ return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
56
+ default:
57
+ g_assert_not_reached();
58
+ }
59
+}
60
+
61
/* Most of the devices in the AN505 FPGA image sit behind
62
* Peripheral Protection Controllers. These data structures
63
* define the layout of which devices sit behind which PPCs.
64
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
65
int txirqno = i * 2 + 1;
66
int combirqno = i + 10;
67
SysBusDevice *s;
68
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
70
71
sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
72
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
73
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
74
object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
75
s = SYS_BUS_DEVICE(uart);
76
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
77
- "EXP_IRQ", txirqno));
78
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
79
- "EXP_IRQ", rxirqno));
80
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
81
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
82
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
83
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
84
- sysbus_connect_irq(s, 4, qdev_get_gpio_in_named(iotkitdev,
85
- "EXP_IRQ", combirqno));
86
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
87
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
88
}
89
90
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
91
const char *name, hwaddr size)
92
{
93
SysBusDevice *s;
94
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
95
NICInfo *nd = &nd_table[0];
96
97
/* In hardware this is a LAN9220; the LAN9118 is software compatible
98
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
99
qdev_init_nofail(mms->lan9118);
100
101
s = SYS_BUS_DEVICE(mms->lan9118);
102
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
103
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
104
return sysbus_mmio_get_region(s, 0);
105
}
106
107
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
108
109
s = SYS_BUS_DEVICE(dma);
110
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
111
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
112
- "EXP_IRQ", 58 + i * 3));
113
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
114
- "EXP_IRQ", 56 + i * 3));
115
- sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev,
116
- "EXP_IRQ", 57 + i * 3));
117
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
118
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
119
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
120
121
g_free(mscname);
122
return sysbus_mmio_get_region(s, 0);
123
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
124
*/
125
PL022State *spi = opaque;
126
int i = spi - &mms->spi[0];
127
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
128
SysBusDevice *s;
129
130
sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
131
TYPE_PL022);
132
object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
133
s = SYS_BUS_DEVICE(spi);
134
- sysbus_connect_irq(s, 0,
135
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i));
136
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
137
return sysbus_mmio_get_region(s, 0);
138
}
139
140
static void mps2tz_common_init(MachineState *machine)
141
{
142
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
143
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
144
MachineClass *mc = MACHINE_GET_CLASS(machine);
145
MemoryRegion *system_memory = get_system_memory();
146
DeviceState *iotkitdev;
147
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
148
iotkitdev = DEVICE(&mms->iotkit);
149
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
150
"memory", &error_abort);
151
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", 92);
152
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
153
qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
154
object_property_set_bool(OBJECT(&mms->iotkit), true, "realized",
155
&error_fatal);
156
157
+ /*
158
+ * The AN521 needs us to create splitters to feed the IRQ inputs
159
+ * for each CPU in the SSE-200 from each device in the board.
160
+ */
161
+ if (mmc->fpga_type == FPGA_AN521) {
162
+ for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
163
+ char *name = g_strdup_printf("mps2-irq-splitter%d", i);
164
+ SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
165
+
166
+ object_initialize_child(OBJECT(machine), name,
167
+ splitter, sizeof(*splitter),
168
+ TYPE_SPLIT_IRQ, &error_fatal, NULL);
169
+ g_free(name);
170
+
171
+ object_property_set_int(OBJECT(splitter), 2, "num-lines",
172
+ &error_fatal);
173
+ object_property_set_bool(OBJECT(splitter), true, "realized",
174
+ &error_fatal);
175
+ qdev_connect_gpio_out(DEVICE(splitter), 0,
176
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
177
+ "EXP_IRQ", i));
178
+ qdev_connect_gpio_out(DEVICE(splitter), 1,
179
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
180
+ "EXP_CPU1_IRQ", i));
181
+ }
182
+ }
183
+
184
/* The sec_resp_cfg output from the IoTKit must be split into multiple
185
* lines, one for each of the PPCs we create here, plus one per MSC.
186
*/
187
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
188
object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true,
189
"realized", &error_fatal);
190
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
191
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 15));
192
+ get_sse_irq_in(mms, 15));
193
194
/* Most of the devices in the FPGA are behind Peripheral Protection
195
* Controllers. The required order for initializing things is:
196
--
197
2.20.1
198
199
diff view generated by jsdifflib
Deleted patch
1
Add a model of the MPS2 FPGA image described in Application Note
2
AN521. This is identical to the AN505 image, except that it uses
3
the SSE-200 rather than the IoTKit and so has two Cortex-M33 CPUs.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-24-peter.maydell@linaro.org
8
---
9
hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++++++--
10
1 file changed, 36 insertions(+), 2 deletions(-)
11
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
15
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@
17
* as seen by the guest depend significantly on the FPGA image.
18
* This source file covers the following FPGA images, for TrustZone cores:
19
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
20
+ * "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
21
*
22
* Links to the TRM for the board itself and to the various Application
23
* Notes which document the FPGA images can be found here:
24
@@ -XXX,XX +XXX,XX @@
25
* http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
26
* Application Note AN505:
27
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
28
+ * Application Note AN521:
29
+ * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
30
*
31
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
32
* (ARM ECM0601256) for the details of some of the device layout:
33
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
34
+ * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
35
+ * most of the device layout:
36
+ * 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
37
+ *
38
*/
39
40
#include "qemu/osdep.h"
41
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
MachineClass parent;
43
MPS2TZFPGAType fpga_type;
44
uint32_t scc_id;
45
+ const char *armsse_type;
46
} MPS2TZMachineClass;
47
48
typedef struct {
49
@@ -XXX,XX +XXX,XX @@ typedef struct {
50
51
#define TYPE_MPS2TZ_MACHINE "mps2tz"
52
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
53
+#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
54
55
#define MPS2TZ_MACHINE(obj) \
56
OBJECT_CHECK(MPS2TZMachineState, obj, TYPE_MPS2TZ_MACHINE)
57
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
58
}
59
60
sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
61
- sizeof(mms->iotkit), TYPE_IOTKIT);
62
+ sizeof(mms->iotkit), mmc->armsse_type);
63
iotkitdev = DEVICE(&mms->iotkit);
64
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
65
"memory", &error_abort);
66
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
67
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
68
69
mc->init = mps2tz_common_init;
70
- mc->max_cpus = 1;
71
iic->check = mps2_tz_idau_check;
72
}
73
74
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
75
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
76
77
mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
78
+ mc->default_cpus = 1;
79
+ mc->min_cpus = mc->default_cpus;
80
+ mc->max_cpus = mc->default_cpus;
81
mmc->fpga_type = FPGA_AN505;
82
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
83
mmc->scc_id = 0x41045050;
84
+ mmc->armsse_type = TYPE_IOTKIT;
85
+}
86
+
87
+static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
88
+{
89
+ MachineClass *mc = MACHINE_CLASS(oc);
90
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
91
+
92
+ mc->desc = "ARM MPS2 with AN521 FPGA image for dual Cortex-M33";
93
+ mc->default_cpus = 2;
94
+ mc->min_cpus = mc->default_cpus;
95
+ mc->max_cpus = mc->default_cpus;
96
+ mmc->fpga_type = FPGA_AN521;
97
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
98
+ mmc->scc_id = 0x41045210;
99
+ mmc->armsse_type = TYPE_SSE200;
100
}
101
102
static const TypeInfo mps2tz_info = {
103
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an505_info = {
104
.class_init = mps2tz_an505_class_init,
105
};
106
107
+static const TypeInfo mps2tz_an521_info = {
108
+ .name = TYPE_MPS2TZ_AN521_MACHINE,
109
+ .parent = TYPE_MPS2TZ_MACHINE,
110
+ .class_init = mps2tz_an521_class_init,
111
+};
112
+
113
static void mps2tz_machine_init(void)
114
{
115
type_register_static(&mps2tz_info);
116
type_register_static(&mps2tz_an505_info);
117
+ type_register_static(&mps2tz_an521_info);
118
}
119
120
type_init(mps2tz_machine_init);
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
The "system instructions" and "system register move" subcategories
2
of "branches, exception generating and system instructions" for A64
3
only apply if bits [23:22] are zero; other values are currently
4
unallocated. Correctly UNDEF these unallocated encodings.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-2-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 6 +++++-
12
1 file changed, 5 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
19
break;
20
case 0x6a: /* Exception generation / System */
21
if (insn & (1 << 24)) {
22
- disas_system(s, insn);
23
+ if (extract32(insn, 22, 2) == 0) {
24
+ disas_system(s, insn);
25
+ } else {
26
+ unallocated_encoding(s);
27
+ }
28
} else {
29
disas_exc(s, insn);
30
}
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
Deleted patch
1
The PRFM prefetch insn in the load/store with imm9 encodings
2
requires idx field 0b00; we were underdecoding this by
3
only checking !is_unpriv (which is equivalent to idx != 2).
4
Correctly UNDEF the unallocated encodings where idx == 0b01
5
and 0b11 as well as 0b10.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-3-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
20
} else {
21
if (size == 3 && opc == 2) {
22
/* PRFM - prefetch */
23
- if (is_unpriv) {
24
+ if (idx != 0) {
25
unallocated_encoding(s);
26
return;
27
}
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD load/store multiple structures encodings,
2
the non-post-indexed case should have zeroes in [20:16]
3
(which is the Rm field for the post-indexed case).
4
Correctly UNDEF the currently unallocated encodings which
5
have non-zeroes in those bits.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-4-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 7 ++++++-
13
1 file changed, 6 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
20
{
21
int rt = extract32(insn, 0, 5);
22
int rn = extract32(insn, 5, 5);
23
+ int rm = extract32(insn, 16, 5);
24
int size = extract32(insn, 10, 2);
25
int opcode = extract32(insn, 12, 4);
26
bool is_store = !extract32(insn, 22, 1);
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
28
return;
29
}
30
31
+ if (!is_postidx && rm != 0) {
32
+ unallocated_encoding(s);
33
+ return;
34
+ }
35
+
36
/* From the shared decode logic */
37
switch (opcode) {
38
case 0x0:
39
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
40
}
41
42
if (is_postidx) {
43
- int rm = extract32(insn, 16, 5);
44
if (rm == 31) {
45
tcg_gen_mov_i64(tcg_rn, tcg_addr);
46
} else {
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD load/store single structure encodings, the
2
non-post-indexed case should have zeroes in [20:16] (which is the
3
Rm field for the post-indexed case). Bit 31 must also be zero
4
(a check we got right in ldst_multiple but not here). Correctly
5
UNDEF these unallocated encodings.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-5-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 11 ++++++++++-
13
1 file changed, 10 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
20
{
21
int rt = extract32(insn, 0, 5);
22
int rn = extract32(insn, 5, 5);
23
+ int rm = extract32(insn, 16, 5);
24
int size = extract32(insn, 10, 2);
25
int S = extract32(insn, 12, 1);
26
int opc = extract32(insn, 13, 3);
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
28
int ebytes, xs;
29
TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
30
31
+ if (extract32(insn, 31, 1)) {
32
+ unallocated_encoding(s);
33
+ return;
34
+ }
35
+ if (!is_postidx && rm != 0) {
36
+ unallocated_encoding(s);
37
+ return;
38
+ }
39
+
40
switch (scale) {
41
case 3:
42
if (!is_load || S) {
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
44
}
45
46
if (is_postidx) {
47
- int rm = extract32(insn, 16, 5);
48
if (rm == 31) {
49
tcg_gen_mov_i64(tcg_rn, tcg_addr);
50
} else {
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
In the "add/subtract (extended register)" encoding group, the "opt"
2
field in bits [23:22] must be zero. Correctly UNDEF the unallocated
3
encodings where this field is not zero.
4
1
5
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Message-id: 20190125182626.9221-6-peter.maydell@linaro.org
9
---
10
target/arm/translate-a64.c | 3 ++-
11
1 file changed, 2 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
18
int imm3 = extract32(insn, 10, 3);
19
int option = extract32(insn, 13, 3);
20
int rm = extract32(insn, 16, 5);
21
+ int opt = extract32(insn, 22, 2);
22
bool setflags = extract32(insn, 29, 1);
23
bool sub_op = extract32(insn, 30, 1);
24
bool sf = extract32(insn, 31, 1);
25
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
26
TCGv_i64 tcg_rd;
27
TCGv_i64 tcg_result;
28
29
- if (imm3 > 4) {
30
+ if (imm3 > 4 || opt != 0) {
31
unallocated_encoding(s);
32
return;
33
}
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
In the encoding groups
2
* floating-point data-processing (1 source)
3
* floating-point data-processing (2 source)
4
* floating-point data-processing (3 source)
5
* floating-point immediate
6
* floating-point compare
7
* floating-ponit conditional compare
8
* floating-point conditional select
9
1
10
bit 31 is M and bit 29 is S (and bit 30 is 0, already checked at
11
this point in the decode). None of these groups allocate any
12
encoding for M=1 or S=1. We checked this in disas_fp_compare(),
13
disas_fp_ccomp() and disas_fp_csel(), but missed it in disas_fp_1src(),
14
disas_fp_2src(), disas_fp_3src() and disas_fp_imm().
15
16
We also missed that in the fp immediate encoding the imm5 field
17
must be all zeroes.
18
19
Correctly UNDEF the unallocated encodings here.
20
21
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
24
Message-id: 20190125182626.9221-7-peter.maydell@linaro.org
25
---
26
target/arm/translate-a64.c | 22 +++++++++++++++++++++-
27
1 file changed, 21 insertions(+), 1 deletion(-)
28
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
34
*/
35
static void disas_fp_1src(DisasContext *s, uint32_t insn)
36
{
37
+ int mos = extract32(insn, 29, 3);
38
int type = extract32(insn, 22, 2);
39
int opcode = extract32(insn, 15, 6);
40
int rn = extract32(insn, 5, 5);
41
int rd = extract32(insn, 0, 5);
42
43
+ if (mos) {
44
+ unallocated_encoding(s);
45
+ return;
46
+ }
47
+
48
switch (opcode) {
49
case 0x4: case 0x5: case 0x7:
50
{
51
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_half(DisasContext *s, int opcode,
52
*/
53
static void disas_fp_2src(DisasContext *s, uint32_t insn)
54
{
55
+ int mos = extract32(insn, 29, 3);
56
int type = extract32(insn, 22, 2);
57
int rd = extract32(insn, 0, 5);
58
int rn = extract32(insn, 5, 5);
59
int rm = extract32(insn, 16, 5);
60
int opcode = extract32(insn, 12, 4);
61
62
- if (opcode > 8) {
63
+ if (opcode > 8 || mos) {
64
unallocated_encoding(s);
65
return;
66
}
67
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
68
*/
69
static void disas_fp_3src(DisasContext *s, uint32_t insn)
70
{
71
+ int mos = extract32(insn, 29, 3);
72
int type = extract32(insn, 22, 2);
73
int rd = extract32(insn, 0, 5);
74
int rn = extract32(insn, 5, 5);
75
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
76
bool o0 = extract32(insn, 15, 1);
77
bool o1 = extract32(insn, 21, 1);
78
79
+ if (mos) {
80
+ unallocated_encoding(s);
81
+ return;
82
+ }
83
+
84
switch (type) {
85
case 0:
86
if (!fp_access_check(s)) {
87
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8)
88
static void disas_fp_imm(DisasContext *s, uint32_t insn)
89
{
90
int rd = extract32(insn, 0, 5);
91
+ int imm5 = extract32(insn, 5, 5);
92
int imm8 = extract32(insn, 13, 8);
93
int type = extract32(insn, 22, 2);
94
+ int mos = extract32(insn, 29, 3);
95
uint64_t imm;
96
TCGv_i64 tcg_res;
97
TCGMemOp sz;
98
99
+ if (mos || imm5) {
100
+ unallocated_encoding(s);
101
+ return;
102
+ }
103
+
104
switch (type) {
105
case 0:
106
sz = MO_32;
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD scalar x indexed element and vector x indexed element
2
encoding group, the SDOT and UDOT instructions are vector only,
3
and their opcode is unallocated in the scalar group. Correctly
4
UNDEF this unallocated encoding.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-8-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
19
break;
20
case 0x0e: /* SDOT */
21
case 0x1e: /* UDOT */
22
- if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
23
+ if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
24
unallocated_encoding(s);
25
return;
26
}
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
The tcg_register_iommu_notifier() code has a GArray of
2
TCGIOMMUNotifier structs which it has registered by passing
3
memory_region_register_iommu_notifier() a pointer to the embedded
4
IOMMUNotifier field. Unfortunately, if we need to enlarge the
5
array via g_array_set_size() this can cause a realloc(), which
6
invalidates the pointer that memory_region_register_iommu_notifier()
7
put into the MemoryRegion's iommu_notify list. This can result
8
in segfaults.
9
1
10
Switch the GArray to holding pointers to the TCGIOMMUNotifier
11
structs, so that we can individually allocate and free them.
12
13
Cc: qemu-stable@nongnu.org
14
Fixes: 1f871c5e6b0f30644a60a ("exec.c: Handle IOMMUs in address_space_translate_for_iotlb()")
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190128174241.5860-1-peter.maydell@linaro.org
18
---
19
exec.c | 10 ++++++----
20
1 file changed, 6 insertions(+), 4 deletions(-)
21
22
diff --git a/exec.c b/exec.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/exec.c
25
+++ b/exec.c
26
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
27
int i;
28
29
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
30
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
31
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
32
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
33
break;
34
}
35
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
36
if (i == cpu->iommu_notifiers->len) {
37
/* Not found, add a new entry at the end of the array */
38
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
39
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
40
+ notifier = g_new0(TCGIOMMUNotifier, 1);
41
+ g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
42
43
notifier->mr = mr;
44
notifier->iommu_idx = iommu_idx;
45
@@ -XXX,XX +XXX,XX @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
46
TCGIOMMUNotifier *notifier;
47
48
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
49
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
50
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
51
memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
52
+ g_free(notifier);
53
}
54
g_array_free(cpu->iommu_notifiers, true);
55
}
56
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
57
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
58
}
59
60
- cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
61
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier *));
62
#endif
63
}
64
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
Deleted patch
1
The FCMLA (by element) instruction exists in the
2
"vector x indexed element" encoding group, but not in
3
the "scalar x indexed element" group. Correctly UNDEF
4
the unallocated encodings.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190129140411.682-2-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
19
case 0x13: /* FCMLA #90 */
20
case 0x15: /* FCMLA #180 */
21
case 0x17: /* FCMLA #270 */
22
- if (!dc_isar_feature(aa64_fcma, s)) {
23
+ if (is_scalar || !dc_isar_feature(aa64_fcma, s)) {
24
unallocated_encoding(s);
25
return;
26
}
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
In disas_simd_indexed(), for the case of "complex fp", each indexable
2
element is a complex pair, so the total size is twice that indicated
3
in the 'size' field in the encoding. We were trying to do this
4
"double the size" operation with a left shift by 1, but this is
5
incorrect because the 'size' field is a MO_8/MO_16/MO_32/MO_64
6
value, and doubling the size should be done by a simple increment.
7
1
8
This meant we were mishandling FCMLA (by element) of values where
9
the real and imaginary parts are 32-bit floats, and would incorrectly
10
UNDEF this encoding. (No other insns take this code path, and for
11
16-bit floats it happens that 1 << 1 and 1 + 1 are both the same).
12
13
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
16
Message-id: 20190129140411.682-3-peter.maydell@linaro.org
17
---
18
target/arm/translate-a64.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
26
27
case 2: /* complex fp */
28
/* Each indexable element is a complex pair. */
29
- size <<= 1;
30
+ size += 1;
31
switch (size) {
32
case MO_32:
33
if (h && !is_q) {
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
1
3
Whenever we notice that a counter overflow has occurred, send an
4
interrupt. This is made more reliable with the addition of a timer in a
5
follow-on commit.
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190124162401.5111-2-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.c | 61 +++++++++++++++++++++++++++++++++++++--------
13
1 file changed, 51 insertions(+), 10 deletions(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
20
/* Definitions for the PMU registers */
21
#define PMCRN_MASK 0xf800
22
#define PMCRN_SHIFT 11
23
+#define PMCRLC 0x40
24
#define PMCRDP 0x10
25
#define PMCRD 0x8
26
#define PMCRC 0x4
27
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
28
return enabled && !prohibited && !filtered;
29
}
30
31
+static void pmu_update_irq(CPUARMState *env)
32
+{
33
+ ARMCPU *cpu = arm_env_get_cpu(env);
34
+ qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
35
+ (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
36
+}
37
+
38
/*
39
* Ensure c15_ccnt is the guest-visible count so that operations such as
40
* enabling/disabling the counter or filtering, modifying the count itself,
41
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
42
eff_cycles /= 64;
43
}
44
45
- env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
46
+ uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
47
+
48
+ uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
49
+ 1ull << 63 : 1ull << 31;
50
+ if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
51
+ env->cp15.c9_pmovsr |= (1 << 31);
52
+ pmu_update_irq(env);
53
+ }
54
+
55
+ env->cp15.c15_ccnt = new_pmccntr;
56
}
57
env->cp15.c15_ccnt_delta = cycles;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
60
}
61
62
if (pmu_counter_enabled(env, counter)) {
63
- env->cp15.c14_pmevcntr[counter] =
64
- count - env->cp15.c14_pmevcntr_delta[counter];
65
+ uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
66
+
67
+ if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
68
+ env->cp15.c9_pmovsr |= (1 << counter);
69
+ pmu_update_irq(env);
70
+ }
71
+ env->cp15.c14_pmevcntr[counter] = new_pmevcntr;
72
}
73
env->cp15.c14_pmevcntr_delta[counter] = count;
74
}
75
@@ -XXX,XX +XXX,XX @@ static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
/* counter is SW_INCR */
77
(env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
78
pmevcntr_op_start(env, i);
79
- env->cp15.c14_pmevcntr[i]++;
80
+
81
+ /*
82
+ * Detect if this write causes an overflow since we can't predict
83
+ * PMSWINC overflows like we can for other events
84
+ */
85
+ uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
86
+
87
+ if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
88
+ env->cp15.c9_pmovsr |= (1 << i);
89
+ pmu_update_irq(env);
90
+ }
91
+
92
+ env->cp15.c14_pmevcntr[i] = new_pmswinc;
93
+
94
pmevcntr_op_finish(env, i);
95
}
96
}
97
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
98
{
99
value &= pmu_counter_mask(env);
100
env->cp15.c9_pmovsr &= ~value;
101
+ pmu_update_irq(env);
102
}
103
104
static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
105
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
106
{
107
value &= pmu_counter_mask(env);
108
env->cp15.c9_pmovsr |= value;
109
+ pmu_update_irq(env);
110
}
111
112
static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
113
@@ -XXX,XX +XXX,XX @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
114
/* We have no event counters so only the C bit can be changed */
115
value &= pmu_counter_mask(env);
116
env->cp15.c9_pminten |= value;
117
+ pmu_update_irq(env);
118
}
119
120
static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
121
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
122
{
123
value &= pmu_counter_mask(env);
124
env->cp15.c9_pminten &= ~value;
125
+ pmu_update_irq(env);
126
}
127
128
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
129
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
130
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
131
.writefn = pmcntenclr_write },
132
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
133
- .access = PL0_RW,
134
+ .access = PL0_RW, .type = ARM_CP_IO,
135
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
136
.accessfn = pmreg_access,
137
.writefn = pmovsr_write,
138
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
139
{ .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
140
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
141
.access = PL0_RW, .accessfn = pmreg_access,
142
- .type = ARM_CP_ALIAS,
143
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
144
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
145
.writefn = pmovsr_write,
146
.raw_writefn = raw_write },
147
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
148
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
149
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
150
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
151
.writefn = pmswinc_write },
152
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
153
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
154
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
155
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
156
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
157
.writefn = pmswinc_write },
158
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
159
.access = PL0_RW, .type = ARM_CP_ALIAS,
160
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
161
/* PMOVSSET is not implemented in v7 before v7ve */
162
{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
163
.access = PL0_RW, .accessfn = pmreg_access,
164
- .type = ARM_CP_ALIAS,
165
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
166
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
167
.writefn = pmovsset_write,
168
.raw_writefn = raw_write },
169
{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
170
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
171
.access = PL0_RW, .accessfn = pmreg_access,
172
- .type = ARM_CP_ALIAS,
173
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
174
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
175
.writefn = pmovsset_write,
176
.raw_writefn = raw_write },
177
--
178
2.20.1
179
180
diff view generated by jsdifflib
Deleted patch
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
1
3
Make PMU overflow interrupts more accurate by using a timer to predict
4
when they will overflow rather than waiting for an event to occur which
5
allows us to otherwise check them.
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190124162401.5111-3-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 10 +++++++
13
target/arm/cpu.c | 12 ++++++++
14
target/arm/helper.c | 72 +++++++++++++++++++++++++++++++++++++++++++--
15
3 files changed, 92 insertions(+), 2 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
22
23
/* Timers used by the generic (architected) timer */
24
QEMUTimer *gt_timer[NUM_GTIMERS];
25
+ /*
26
+ * Timer used by the PMU. Its state is restored after migration by
27
+ * pmu_op_finish() - it does not need other handling during migration
28
+ */
29
+ QEMUTimer *pmu_timer;
30
/* GPIO outputs for generic timer */
31
qemu_irq gt_timer_outputs[NUM_GTIMERS];
32
/* GPIO output for GICv3 maintenance interrupt signal */
33
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env);
34
void pmu_op_start(CPUARMState *env);
35
void pmu_op_finish(CPUARMState *env);
36
37
+/*
38
+ * Called when a PMU counter is due to overflow
39
+ */
40
+void arm_pmu_timer_cb(void *opaque);
41
+
42
/**
43
* Functions to register as EL change hooks for PMU mode filtering
44
*/
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_finalizefn(Object *obj)
50
QLIST_REMOVE(hook, node);
51
g_free(hook);
52
}
53
+#ifndef CONFIG_USER_ONLY
54
+ if (cpu->pmu_timer) {
55
+ timer_del(cpu->pmu_timer);
56
+ timer_deinit(cpu->pmu_timer);
57
+ timer_free(cpu->pmu_timer);
58
+ }
59
+#endif
60
}
61
62
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
63
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
64
arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
65
arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
66
}
67
+
68
+#ifndef CONFIG_USER_ONLY
69
+ cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, arm_pmu_timer_cb,
70
+ cpu);
71
+#endif
72
} else {
73
cpu->id_aa64dfr0 &= ~0xf00;
74
cpu->pmceid0 = 0;
75
diff --git a/target/arm/helper.c b/target/arm/helper.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/helper.c
78
+++ b/target/arm/helper.c
79
@@ -XXX,XX +XXX,XX @@ typedef struct pm_event {
80
* counters hold a difference from the return value from this function
81
*/
82
uint64_t (*get_count)(CPUARMState *);
83
+ /*
84
+ * Return how many nanoseconds it will take (at a minimum) for count events
85
+ * to occur. A negative value indicates the counter will never overflow, or
86
+ * that the counter has otherwise arranged for the overflow bit to be set
87
+ * and the PMU interrupt to be raised on overflow.
88
+ */
89
+ int64_t (*ns_per_count)(uint64_t);
90
} pm_event;
91
92
static bool event_always_supported(CPUARMState *env)
93
@@ -XXX,XX +XXX,XX @@ static uint64_t swinc_get_count(CPUARMState *env)
94
return 0;
95
}
96
97
+static int64_t swinc_ns_per(uint64_t ignored)
98
+{
99
+ return -1;
100
+}
101
+
102
/*
103
* Return the underlying cycle count for the PMU cycle counters. If we're in
104
* usermode, simply return 0.
105
@@ -XXX,XX +XXX,XX @@ static uint64_t cycles_get_count(CPUARMState *env)
106
}
107
108
#ifndef CONFIG_USER_ONLY
109
+static int64_t cycles_ns_per(uint64_t cycles)
110
+{
111
+ return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
112
+}
113
+
114
static bool instructions_supported(CPUARMState *env)
115
{
116
return use_icount == 1 /* Precise instruction counting */;
117
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
118
{
119
return (uint64_t)cpu_get_icount_raw();
120
}
121
+
122
+static int64_t instructions_ns_per(uint64_t icount)
123
+{
124
+ return cpu_icount_to_ns((int64_t)icount);
125
+}
126
#endif
127
128
static const pm_event pm_events[] = {
129
{ .number = 0x000, /* SW_INCR */
130
.supported = event_always_supported,
131
.get_count = swinc_get_count,
132
+ .ns_per_count = swinc_ns_per,
133
},
134
#ifndef CONFIG_USER_ONLY
135
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
136
.supported = instructions_supported,
137
.get_count = instructions_get_count,
138
+ .ns_per_count = instructions_ns_per,
139
},
140
{ .number = 0x011, /* CPU_CYCLES, Cycle */
141
.supported = event_always_supported,
142
.get_count = cycles_get_count,
143
+ .ns_per_count = cycles_ns_per,
144
}
145
#endif
146
};
147
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
148
void pmccntr_op_finish(CPUARMState *env)
149
{
150
if (pmu_counter_enabled(env, 31)) {
151
- uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
152
+#ifndef CONFIG_USER_ONLY
153
+ /* Calculate when the counter will next overflow */
154
+ uint64_t remaining_cycles = -env->cp15.c15_ccnt;
155
+ if (!(env->cp15.c9_pmcr & PMCRLC)) {
156
+ remaining_cycles = (uint32_t)remaining_cycles;
157
+ }
158
+ int64_t overflow_in = cycles_ns_per(remaining_cycles);
159
160
+ if (overflow_in > 0) {
161
+ int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
162
+ overflow_in;
163
+ ARMCPU *cpu = arm_env_get_cpu(env);
164
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
165
+ }
166
+#endif
167
+
168
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
169
if (env->cp15.c9_pmcr & PMCRD) {
170
/* Increment once every 64 processor clock cycles */
171
prev_cycles /= 64;
172
}
173
-
174
env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
175
}
176
}
177
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
178
static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
179
{
180
if (pmu_counter_enabled(env, counter)) {
181
+#ifndef CONFIG_USER_ONLY
182
+ uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
183
+ uint16_t event_idx = supported_event_map[event];
184
+ uint64_t delta = UINT32_MAX -
185
+ (uint32_t)env->cp15.c14_pmevcntr[counter] + 1;
186
+ int64_t overflow_in = pm_events[event_idx].ns_per_count(delta);
187
+
188
+ if (overflow_in > 0) {
189
+ int64_t overflow_at = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
190
+ overflow_in;
191
+ ARMCPU *cpu = arm_env_get_cpu(env);
192
+ timer_mod_anticipate_ns(cpu->pmu_timer, overflow_at);
193
+ }
194
+#endif
195
+
196
env->cp15.c14_pmevcntr_delta[counter] -=
197
env->cp15.c14_pmevcntr[counter];
198
}
199
@@ -XXX,XX +XXX,XX @@ void pmu_post_el_change(ARMCPU *cpu, void *ignored)
200
pmu_op_finish(&cpu->env);
201
}
202
203
+void arm_pmu_timer_cb(void *opaque)
204
+{
205
+ ARMCPU *cpu = opaque;
206
+
207
+ /*
208
+ * Update all the counter values based on the current underlying counts,
209
+ * triggering interrupts to be raised, if necessary. pmu_op_finish() also
210
+ * has the effect of setting the cpu->pmu_timer to the next earliest time a
211
+ * counter may expire.
212
+ */
213
+ pmu_op_start(&cpu->env);
214
+ pmu_op_finish(&cpu->env);
215
+}
216
+
217
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
218
uint64_t value)
219
{
220
--
221
2.20.1
222
223
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
These bits become writable with the ARMv8.3-PAuth extension.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190129143511.12311-1-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
18
if (cpu_isar_feature(aa64_lor, cpu)) {
19
valid_mask |= SCR_TLOR;
20
}
21
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
22
+ valid_mask |= SCR_API | SCR_APK;
23
+ }
24
25
/* Clear all-context RES0 bits. */
26
value &= valid_mask;
27
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
28
if (cpu_isar_feature(aa64_lor, cpu)) {
29
valid_mask |= HCR_TLOR;
30
}
31
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
32
+ valid_mask |= HCR_API | HCR_APK;
33
+ }
34
35
/* Clear RES0 bits. */
36
value &= valid_mask;
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Julia Suvorova <jusual@mail.ru>
2
1
3
Until now, the set_pc logic was unclear, which raised questions about
4
whether it should be used directly, applying a value to PC or adding
5
additional checks, for example, set the Thumb bit in Arm cpu. Let's set
6
the set_pc logic for “Configure the PC, as was done in the ELF file”
7
and implement synchronize_with_tb hook for preserving PC to cpu_tb_exec.
8
9
Signed-off-by: Julia Suvorova <jusual@mail.ru>
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 20190129121817.7109-1-jusual@mail.ru
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/qom/cpu.h | 16 ++++++++++++++--
16
hw/arm/boot.c | 4 ----
17
target/arm/arm-powerctl.c | 3 ---
18
target/arm/cpu.c | 26 +++++++++++++++++++++++++-
19
target/arm/cpu64.c | 15 ---------------
20
5 files changed, 39 insertions(+), 25 deletions(-)
21
22
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/qom/cpu.h
25
+++ b/include/qom/cpu.h
26
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
27
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
28
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
29
* @get_memory_mapping: Callback for obtaining the memory mappings.
30
- * @set_pc: Callback for setting the Program Counter register.
31
+ * @set_pc: Callback for setting the Program Counter register. This
32
+ * should have the semantics used by the target architecture when
33
+ * setting the PC from a source such as an ELF file entry point;
34
+ * for example on Arm it will also set the Thumb mode bit based
35
+ * on the least significant bit of the new PC value.
36
+ * If the target behaviour here is anything other than "set
37
+ * the PC register to the value passed in" then the target must
38
+ * also implement the synchronize_from_tb hook.
39
* @synchronize_from_tb: Callback for synchronizing state from a TCG
40
- * #TranslationBlock.
41
+ * #TranslationBlock. This is called when we abandon execution
42
+ * of a TB before starting it, and must set all parts of the CPU
43
+ * state which the previous TB in the chain may not have updated.
44
+ * This always includes at least the program counter; some targets
45
+ * will need to do more. If this hook is not implemented then the
46
+ * default is to call @set_pc(tb->pc).
47
* @handle_mmu_fault: Callback for handling an MMU fault.
48
* @get_phys_page_debug: Callback for obtaining a physical address.
49
* @get_phys_page_attrs_debug: Callback for obtaining a physical address and the
50
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/boot.c
53
+++ b/hw/arm/boot.c
54
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
55
g_assert_not_reached();
56
}
57
58
- if (!env->aarch64) {
59
- env->thumb = info->entry & 1;
60
- entry &= 0xfffffffe;
61
- }
62
cpu_set_pc(cs, entry);
63
} else {
64
/* If we are booting Linux then we need to check whether we are
65
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/arm-powerctl.c
68
+++ b/target/arm/arm-powerctl.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
70
71
if (info->target_aa64) {
72
target_cpu->env.xregs[0] = info->context_id;
73
- target_cpu->env.thumb = false;
74
} else {
75
target_cpu->env.regs[0] = info->context_id;
76
- target_cpu->env.thumb = info->entry & 1;
77
- info->entry &= 0xfffffffe;
78
}
79
80
/* Start the new CPU at the requested address */
81
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/cpu.c
84
+++ b/target/arm/cpu.c
85
@@ -XXX,XX +XXX,XX @@
86
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
87
{
88
ARMCPU *cpu = ARM_CPU(cs);
89
+ CPUARMState *env = &cpu->env;
90
91
- cpu->env.regs[15] = value;
92
+ if (is_a64(env)) {
93
+ env->pc = value;
94
+ env->thumb = 0;
95
+ } else {
96
+ env->regs[15] = value & ~1;
97
+ env->thumb = value & 1;
98
+ }
99
+}
100
+
101
+static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
102
+{
103
+ ARMCPU *cpu = ARM_CPU(cs);
104
+ CPUARMState *env = &cpu->env;
105
+
106
+ /*
107
+ * It's OK to look at env for the current mode here, because it's
108
+ * never possible for an AArch64 TB to chain to an AArch32 TB.
109
+ */
110
+ if (is_a64(env)) {
111
+ env->pc = tb->pc;
112
+ } else {
113
+ env->regs[15] = tb->pc;
114
+ }
115
}
116
117
static bool arm_cpu_has_work(CPUState *cs)
118
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
119
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
120
cc->dump_state = arm_cpu_dump_state;
121
cc->set_pc = arm_cpu_set_pc;
122
+ cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
123
cc->gdb_read_register = arm_cpu_gdb_read_register;
124
cc->gdb_write_register = arm_cpu_gdb_write_register;
125
#ifdef CONFIG_USER_ONLY
126
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/cpu64.c
129
+++ b/target/arm/cpu64.c
130
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_finalizefn(Object *obj)
131
{
132
}
133
134
-static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
135
-{
136
- ARMCPU *cpu = ARM_CPU(cs);
137
- /* It's OK to look at env for the current mode here, because it's
138
- * never possible for an AArch64 TB to chain to an AArch32 TB.
139
- * (Otherwise we would need to use synchronize_from_tb instead.)
140
- */
141
- if (is_a64(&cpu->env)) {
142
- cpu->env.pc = value;
143
- } else {
144
- cpu->env.regs[15] = value;
145
- }
146
-}
147
-
148
static gchar *aarch64_gdb_arch_name(CPUState *cs)
149
{
150
return g_strdup("aarch64");
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
152
CPUClass *cc = CPU_CLASS(oc);
153
154
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
155
- cc->set_pc = aarch64_cpu_set_pc;
156
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
157
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
158
cc->gdb_num_core_regs = 34;
159
--
160
2.20.1
161
162
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Drop the pac properties. This approach cannot work as written
4
because the properties are applied before arm_cpu_reset, which
5
zeros SCTLR_EL1 (amongst everything else).
6
7
We can re-introduce the properties if they turn out to be useful.
8
But since linux 5.0 enables all of the keys, they may not be.
9
10
Fixes: 1ae9cfbd470
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/cpu.c | 3 +++
16
target/arm/cpu64.c | 60 ----------------------------------------------
17
2 files changed, 3 insertions(+), 60 deletions(-)
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
24
env->pstate = PSTATE_MODE_EL0t;
25
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
26
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
27
+ /* Enable all PAC keys. */
28
+ env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
29
+ SCTLR_EnDA | SCTLR_EnDB);
30
/* Enable all PAC instructions */
31
env->cp15.hcr_el2 |= HCR_API;
32
env->cp15.scr_el3 |= SCR_API;
33
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu64.c
36
+++ b/target/arm/cpu64.c
37
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
38
error_propagate(errp, err);
39
}
40
41
-#ifdef CONFIG_USER_ONLY
42
-static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
43
- void *opaque, Error **errp)
44
-{
45
- ARMCPU *cpu = ARM_CPU(obj);
46
- const uint64_t *bit = opaque;
47
- bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
48
-
49
- visit_type_bool(v, name, &enabled, errp);
50
-}
51
-
52
-static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
53
- void *opaque, Error **errp)
54
-{
55
- ARMCPU *cpu = ARM_CPU(obj);
56
- Error *err = NULL;
57
- const uint64_t *bit = opaque;
58
- bool enabled;
59
-
60
- visit_type_bool(v, name, &enabled, errp);
61
-
62
- if (!err) {
63
- if (enabled) {
64
- cpu->env.cp15.sctlr_el[1] |= *bit;
65
- } else {
66
- cpu->env.cp15.sctlr_el[1] &= ~*bit;
67
- }
68
- }
69
- error_propagate(errp, err);
70
-}
71
-#endif
72
-
73
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
74
* otherwise, a CPU with as many features enabled as our emulation supports.
75
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
77
*/
78
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
79
cpu->dcz_blocksize = 7; /* 512 bytes */
80
-
81
- /*
82
- * Note that Linux will enable enable all of the keys at once.
83
- * But doing it this way will allow experimentation beyond that.
84
- */
85
- {
86
- static const uint64_t apia_bit = SCTLR_EnIA;
87
- static const uint64_t apib_bit = SCTLR_EnIB;
88
- static const uint64_t apda_bit = SCTLR_EnDA;
89
- static const uint64_t apdb_bit = SCTLR_EnDB;
90
-
91
- object_property_add(obj, "apia", "bool", cpu_max_get_packey,
92
- cpu_max_set_packey, NULL,
93
- (void *)&apia_bit, &error_fatal);
94
- object_property_add(obj, "apib", "bool", cpu_max_get_packey,
95
- cpu_max_set_packey, NULL,
96
- (void *)&apib_bit, &error_fatal);
97
- object_property_add(obj, "apda", "bool", cpu_max_get_packey,
98
- cpu_max_set_packey, NULL,
99
- (void *)&apda_bit, &error_fatal);
100
- object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
101
- cpu_max_set_packey, NULL,
102
- (void *)&apdb_bit, &error_fatal);
103
-
104
- /* Enable all PAC keys by default. */
105
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
106
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
107
- }
108
#endif
109
110
cpu->sve_max_vq = ARM_MAX_VQ;
111
--
112
2.20.1
113
114
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
linux-user/elfload.c | 9 +++++++++
8
1 file changed, 9 insertions(+)
9
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
13
+++ b/linux-user/elfload.c
14
@@ -XXX,XX +XXX,XX @@ enum {
15
ARM_HWCAP_A64_ASIMDDP = 1 << 20,
16
ARM_HWCAP_A64_SHA512 = 1 << 21,
17
ARM_HWCAP_A64_SVE = 1 << 22,
18
+ ARM_HWCAP_A64_ASIMDFHM = 1 << 23,
19
+ ARM_HWCAP_A64_DIT = 1 << 24,
20
+ ARM_HWCAP_A64_USCAT = 1 << 25,
21
+ ARM_HWCAP_A64_ILRCPC = 1 << 26,
22
+ ARM_HWCAP_A64_FLAGM = 1 << 27,
23
+ ARM_HWCAP_A64_SSBS = 1 << 28,
24
+ ARM_HWCAP_A64_SB = 1 << 29,
25
+ ARM_HWCAP_A64_PACA = 1 << 30,
26
+ ARM_HWCAP_A64_PACG = 1UL << 31,
27
};
28
29
#define ELF_HWCAP get_elf_hwcap()
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
linux-user/elfload.c | 1 +
8
1 file changed, 1 insertion(+)
9
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
13
+++ b/linux-user/elfload.c
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
15
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
18
+ GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
19
20
#undef GET_FEATURE_ID
21
22
--
23
2.20.1
24
25
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Initialize the keys to a non-zero value on process start.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
linux-user/aarch64/target_syscall.h | 2 ++
10
linux-user/aarch64/cpu_loop.c | 31 +++++++++++++++++++++++++++--
11
2 files changed, 31 insertions(+), 2 deletions(-)
12
13
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/aarch64/target_syscall.h
16
+++ b/linux-user/aarch64/target_syscall.h
17
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
18
#define TARGET_PR_SVE_SET_VL 50
19
#define TARGET_PR_SVE_GET_VL 51
20
21
+void arm_init_pauth_key(ARMPACKey *key);
22
+
23
#endif /* AARCH64_TARGET_SYSCALL_H */
24
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/linux-user/aarch64/cpu_loop.c
27
+++ b/linux-user/aarch64/cpu_loop.c
28
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
29
}
30
}
31
32
+static uint64_t arm_rand64(void)
33
+{
34
+ int shift = 64 - clz64(RAND_MAX);
35
+ int i, n = 64 / shift + (64 % shift != 0);
36
+ uint64_t ret = 0;
37
+
38
+ for (i = 0; i < n; i++) {
39
+ ret = (ret << shift) | rand();
40
+ }
41
+ return ret;
42
+}
43
+
44
+void arm_init_pauth_key(ARMPACKey *key)
45
+{
46
+ key->lo = arm_rand64();
47
+ key->hi = arm_rand64();
48
+}
49
+
50
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
51
{
52
- CPUState *cpu = ENV_GET_CPU(env);
53
- TaskState *ts = cpu->opaque;
54
+ ARMCPU *cpu = arm_env_get_cpu(env);
55
+ CPUState *cs = CPU(cpu);
56
+ TaskState *ts = cs->opaque;
57
struct image_info *info = ts->info;
58
int i;
59
60
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
61
}
62
#endif
63
64
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
65
+ arm_init_pauth_key(&env->apia_key);
66
+ arm_init_pauth_key(&env->apib_key);
67
+ arm_init_pauth_key(&env->apda_key);
68
+ arm_init_pauth_key(&env->apdb_key);
69
+ arm_init_pauth_key(&env->apga_key);
70
+ }
71
+
72
ts->stack_base = info->start_stack;
73
ts->heap_base = info->brk;
74
/* This will be filled in on the first SYS_HEAPINFO call. */
75
--
76
2.20.1
77
78
diff view generated by jsdifflib
Deleted patch
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
2
1
3
Since QEMU does not support the ARMv8.2-LVA, Large Virtual Address,
4
extension (yet), the VA address space is 48-bits plus a sign bit. User
5
mode can only handle the positive half of the address space, so that
6
makes a limit of 48 bits.
7
8
(With LVA, it would be 53 and 52 bits respectively.)
9
10
The incorrectly large address space conflicts with PAuth instructions,
11
which use bits 48-54 and 56-63 for the pointer authentication code. This
12
also conflicts with (as yet unsupported by QEMU) data tagging and with
13
the ARMv8.5-MTE extension.
14
15
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/cpu.h | 2 +-
20
1 file changed, 1 insertion(+), 1 deletion(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu);
27
28
#if defined(TARGET_AARCH64)
29
# define TARGET_PHYS_ADDR_SPACE_BITS 48
30
-# define TARGET_VIRT_ADDR_SPACE_BITS 64
31
+# define TARGET_VIRT_ADDR_SPACE_BITS 48
32
#else
33
# define TARGET_PHYS_ADDR_SPACE_BITS 40
34
# define TARGET_VIRT_ADDR_SPACE_BITS 32
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
2
1
3
A flawed test lead to the instructions always being treated as
4
unallocated encodings.
5
6
Fixes: https://bugs.launchpad.net/bugs/1813460
7
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
19
if (!dc_isar_feature(aa64_pauth, s)) {
20
goto do_unallocated;
21
}
22
- if (op3 != 2 || op3 != 3) {
23
+ if ((op3 & ~1) != 2) {
24
goto do_unallocated;
25
}
26
if (s->pauth_active) {
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
The nRF51 contains three regions of non-volatile memory (NVM):
4
- CODE (R/W): contains code
5
- FICR (R): Factory information like code size, chip id etc.
6
- UICR (R/W): Changeable configuration data. Lock bits, Code
7
protection configuration, Bootloader address, Nordic SoftRadio
8
configuration, Firmware configuration.
9
10
Read and write access to the memories is managed by the
11
Non-volatile memory controller.
12
13
Memory schema:
14
[ CPU ] -+- [ NVM, either FICR, UICR or CODE ]
15
| |
16
\- [ NVMC ]
17
18
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
Tested-by: Joel Stanley <joel@jms.id.au>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20190201023357.22596-2-stefanha@redhat.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/nvram/Makefile.objs | 1 +
26
include/hw/nvram/nrf51_nvm.h | 64 ++++++
27
hw/nvram/nrf51_nvm.c | 388 +++++++++++++++++++++++++++++++++++
28
3 files changed, 453 insertions(+)
29
create mode 100644 include/hw/nvram/nrf51_nvm.h
30
create mode 100644 hw/nvram/nrf51_nvm.c
31
32
diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/nvram/Makefile.objs
35
+++ b/hw/nvram/Makefile.objs
36
@@ -XXX,XX +XXX,XX @@ common-obj-y += fw_cfg.o
37
common-obj-y += chrp_nvram.o
38
common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
39
obj-$(CONFIG_PSERIES) += spapr_nvram.o
40
+obj-$(CONFIG_NRF51_SOC) += nrf51_nvm.o
41
diff --git a/include/hw/nvram/nrf51_nvm.h b/include/hw/nvram/nrf51_nvm.h
42
new file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/include/hw/nvram/nrf51_nvm.h
46
@@ -XXX,XX +XXX,XX @@
47
+/*
48
+ * Nordic Semiconductor nRF51 non-volatile memory
49
+ *
50
+ * It provides an interface to erase regions in flash memory.
51
+ * Furthermore it provides the user and factory information registers.
52
+ *
53
+ * QEMU interface:
54
+ * + sysbus MMIO regions 0: NVMC peripheral registers
55
+ * + sysbus MMIO regions 1: FICR peripheral registers
56
+ * + sysbus MMIO regions 2: UICR peripheral registers
57
+ * + flash-size property: flash size in bytes.
58
+ *
59
+ * Accuracy of the peripheral model:
60
+ * + Code regions (MPU configuration) are disregarded.
61
+ *
62
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
63
+ *
64
+ * This code is licensed under the GPL version 2 or later. See
65
+ * the COPYING file in the top-level directory.
66
+ *
67
+ */
68
+#ifndef NRF51_NVM_H
69
+#define NRF51_NVM_H
70
+
71
+#include "hw/sysbus.h"
72
+#define TYPE_NRF51_NVM "nrf51_soc.nvm"
73
+#define NRF51_NVM(obj) OBJECT_CHECK(NRF51NVMState, (obj), TYPE_NRF51_NVM)
74
+
75
+#define NRF51_UICR_FIXTURE_SIZE 64
76
+
77
+#define NRF51_NVMC_SIZE 0x1000
78
+
79
+#define NRF51_NVMC_READY 0x400
80
+#define NRF51_NVMC_READY_READY 0x01
81
+#define NRF51_NVMC_CONFIG 0x504
82
+#define NRF51_NVMC_CONFIG_MASK 0x03
83
+#define NRF51_NVMC_CONFIG_WEN 0x01
84
+#define NRF51_NVMC_CONFIG_EEN 0x02
85
+#define NRF51_NVMC_ERASEPCR1 0x508
86
+#define NRF51_NVMC_ERASEPCR0 0x510
87
+#define NRF51_NVMC_ERASEALL 0x50C
88
+#define NRF51_NVMC_ERASEUICR 0x514
89
+#define NRF51_NVMC_ERASE 0x01
90
+
91
+#define NRF51_UICR_SIZE 0x100
92
+
93
+typedef struct NRF51NVMState {
94
+ SysBusDevice parent_obj;
95
+
96
+ MemoryRegion mmio;
97
+ MemoryRegion ficr;
98
+ MemoryRegion uicr;
99
+ MemoryRegion flash;
100
+
101
+ uint32_t uicr_content[NRF51_UICR_FIXTURE_SIZE];
102
+ uint32_t flash_size;
103
+ uint8_t *storage;
104
+
105
+ uint32_t config;
106
+
107
+} NRF51NVMState;
108
+
109
+
110
+#endif
111
diff --git a/hw/nvram/nrf51_nvm.c b/hw/nvram/nrf51_nvm.c
112
new file mode 100644
113
index XXXXXXX..XXXXXXX
114
--- /dev/null
115
+++ b/hw/nvram/nrf51_nvm.c
116
@@ -XXX,XX +XXX,XX @@
117
+/*
118
+ * Nordic Semiconductor nRF51 non-volatile memory
119
+ *
120
+ * It provides an interface to erase regions in flash memory.
121
+ * Furthermore it provides the user and factory information registers.
122
+ *
123
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
124
+ *
125
+ * See nRF51 reference manual and product sheet sections:
126
+ * + Non-Volatile Memory Controller (NVMC)
127
+ * + Factory Information Configuration Registers (FICR)
128
+ * + User Information Configuration Registers (UICR)
129
+ *
130
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
131
+ *
132
+ * This code is licensed under the GPL version 2 or later. See
133
+ * the COPYING file in the top-level directory.
134
+ */
135
+
136
+#include "qemu/osdep.h"
137
+#include "qapi/error.h"
138
+#include "qemu/log.h"
139
+#include "exec/address-spaces.h"
140
+#include "hw/arm/nrf51.h"
141
+#include "hw/nvram/nrf51_nvm.h"
142
+
143
+/*
144
+ * FICR Registers Assignments
145
+ * CODEPAGESIZE 0x010
146
+ * CODESIZE 0x014
147
+ * CLENR0 0x028
148
+ * PPFC 0x02C
149
+ * NUMRAMBLOCK 0x034
150
+ * SIZERAMBLOCKS 0x038
151
+ * SIZERAMBLOCK[0] 0x038
152
+ * SIZERAMBLOCK[1] 0x03C
153
+ * SIZERAMBLOCK[2] 0x040
154
+ * SIZERAMBLOCK[3] 0x044
155
+ * CONFIGID 0x05C
156
+ * DEVICEID[0] 0x060
157
+ * DEVICEID[1] 0x064
158
+ * ER[0] 0x080
159
+ * ER[1] 0x084
160
+ * ER[2] 0x088
161
+ * ER[3] 0x08C
162
+ * IR[0] 0x090
163
+ * IR[1] 0x094
164
+ * IR[2] 0x098
165
+ * IR[3] 0x09C
166
+ * DEVICEADDRTYPE 0x0A0
167
+ * DEVICEADDR[0] 0x0A4
168
+ * DEVICEADDR[1] 0x0A8
169
+ * OVERRIDEEN 0x0AC
170
+ * NRF_1MBIT[0] 0x0B0
171
+ * NRF_1MBIT[1] 0x0B4
172
+ * NRF_1MBIT[2] 0x0B8
173
+ * NRF_1MBIT[3] 0x0BC
174
+ * NRF_1MBIT[4] 0x0C0
175
+ * BLE_1MBIT[0] 0x0EC
176
+ * BLE_1MBIT[1] 0x0F0
177
+ * BLE_1MBIT[2] 0x0F4
178
+ * BLE_1MBIT[3] 0x0F8
179
+ * BLE_1MBIT[4] 0x0FC
180
+ */
181
+static const uint32_t ficr_content[64] = {
182
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
183
+ 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
184
+ 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
185
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
186
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
187
+ 0x12345678, 0x9ABCDEF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
188
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
189
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
190
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
191
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
192
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
193
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
194
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
195
+};
196
+
197
+static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
198
+{
199
+ assert(offset < sizeof(ficr_content));
200
+ return ficr_content[offset / 4];
201
+}
202
+
203
+static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
204
+ unsigned int size)
205
+{
206
+ /* Intentionally do nothing */
207
+}
208
+
209
+static const MemoryRegionOps ficr_ops = {
210
+ .read = ficr_read,
211
+ .write = ficr_write,
212
+ .impl.min_access_size = 4,
213
+ .impl.max_access_size = 4,
214
+ .endianness = DEVICE_LITTLE_ENDIAN
215
+};
216
+
217
+/*
218
+ * UICR Registers Assignments
219
+ * CLENR0 0x000
220
+ * RBPCONF 0x004
221
+ * XTALFREQ 0x008
222
+ * FWID 0x010
223
+ * BOOTLOADERADDR 0x014
224
+ * NRFFW[0] 0x014
225
+ * NRFFW[1] 0x018
226
+ * NRFFW[2] 0x01C
227
+ * NRFFW[3] 0x020
228
+ * NRFFW[4] 0x024
229
+ * NRFFW[5] 0x028
230
+ * NRFFW[6] 0x02C
231
+ * NRFFW[7] 0x030
232
+ * NRFFW[8] 0x034
233
+ * NRFFW[9] 0x038
234
+ * NRFFW[10] 0x03C
235
+ * NRFFW[11] 0x040
236
+ * NRFFW[12] 0x044
237
+ * NRFFW[13] 0x048
238
+ * NRFFW[14] 0x04C
239
+ * NRFHW[0] 0x050
240
+ * NRFHW[1] 0x054
241
+ * NRFHW[2] 0x058
242
+ * NRFHW[3] 0x05C
243
+ * NRFHW[4] 0x060
244
+ * NRFHW[5] 0x064
245
+ * NRFHW[6] 0x068
246
+ * NRFHW[7] 0x06C
247
+ * NRFHW[8] 0x070
248
+ * NRFHW[9] 0x074
249
+ * NRFHW[10] 0x078
250
+ * NRFHW[11] 0x07C
251
+ * CUSTOMER[0] 0x080
252
+ * CUSTOMER[1] 0x084
253
+ * CUSTOMER[2] 0x088
254
+ * CUSTOMER[3] 0x08C
255
+ * CUSTOMER[4] 0x090
256
+ * CUSTOMER[5] 0x094
257
+ * CUSTOMER[6] 0x098
258
+ * CUSTOMER[7] 0x09C
259
+ * CUSTOMER[8] 0x0A0
260
+ * CUSTOMER[9] 0x0A4
261
+ * CUSTOMER[10] 0x0A8
262
+ * CUSTOMER[11] 0x0AC
263
+ * CUSTOMER[12] 0x0B0
264
+ * CUSTOMER[13] 0x0B4
265
+ * CUSTOMER[14] 0x0B8
266
+ * CUSTOMER[15] 0x0BC
267
+ * CUSTOMER[16] 0x0C0
268
+ * CUSTOMER[17] 0x0C4
269
+ * CUSTOMER[18] 0x0C8
270
+ * CUSTOMER[19] 0x0CC
271
+ * CUSTOMER[20] 0x0D0
272
+ * CUSTOMER[21] 0x0D4
273
+ * CUSTOMER[22] 0x0D8
274
+ * CUSTOMER[23] 0x0DC
275
+ * CUSTOMER[24] 0x0E0
276
+ * CUSTOMER[25] 0x0E4
277
+ * CUSTOMER[26] 0x0E8
278
+ * CUSTOMER[27] 0x0EC
279
+ * CUSTOMER[28] 0x0F0
280
+ * CUSTOMER[29] 0x0F4
281
+ * CUSTOMER[30] 0x0F8
282
+ * CUSTOMER[31] 0x0FC
283
+ */
284
+
285
+static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
286
+{
287
+ NRF51NVMState *s = NRF51_NVM(opaque);
288
+
289
+ assert(offset < sizeof(s->uicr_content));
290
+ return s->uicr_content[offset / 4];
291
+}
292
+
293
+static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
294
+ unsigned int size)
295
+{
296
+ NRF51NVMState *s = NRF51_NVM(opaque);
297
+
298
+ assert(offset < sizeof(s->uicr_content));
299
+ s->uicr_content[offset / 4] = value;
300
+}
301
+
302
+static const MemoryRegionOps uicr_ops = {
303
+ .read = uicr_read,
304
+ .write = uicr_write,
305
+ .impl.min_access_size = 4,
306
+ .impl.max_access_size = 4,
307
+ .endianness = DEVICE_LITTLE_ENDIAN
308
+};
309
+
310
+
311
+static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
312
+{
313
+ NRF51NVMState *s = NRF51_NVM(opaque);
314
+ uint64_t r = 0;
315
+
316
+ switch (offset) {
317
+ case NRF51_NVMC_READY:
318
+ r = NRF51_NVMC_READY_READY;
319
+ break;
320
+ case NRF51_NVMC_CONFIG:
321
+ r = s->config;
322
+ break;
323
+ default:
324
+ qemu_log_mask(LOG_GUEST_ERROR,
325
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
326
+ break;
327
+ }
328
+
329
+ return r;
330
+}
331
+
332
+static void io_write(void *opaque, hwaddr offset, uint64_t value,
333
+ unsigned int size)
334
+{
335
+ NRF51NVMState *s = NRF51_NVM(opaque);
336
+
337
+ switch (offset) {
338
+ case NRF51_NVMC_CONFIG:
339
+ s->config = value & NRF51_NVMC_CONFIG_MASK;
340
+ break;
341
+ case NRF51_NVMC_ERASEPCR0:
342
+ case NRF51_NVMC_ERASEPCR1:
343
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
344
+ /* Mask in-page sub address */
345
+ value &= ~(NRF51_PAGE_SIZE - 1);
346
+ if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
347
+ memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
348
+ memory_region_flush_rom_device(&s->flash, value,
349
+ NRF51_PAGE_SIZE);
350
+ }
351
+ } else {
352
+ qemu_log_mask(LOG_GUEST_ERROR,
353
+ "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
354
+ __func__, offset);
355
+ }
356
+ break;
357
+ case NRF51_NVMC_ERASEALL:
358
+ if (value == NRF51_NVMC_ERASE) {
359
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
360
+ memset(s->storage, 0xFF, s->flash_size);
361
+ memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
362
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
363
+ } else {
364
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
365
+ __func__);
366
+ }
367
+ }
368
+ break;
369
+ case NRF51_NVMC_ERASEUICR:
370
+ if (value == NRF51_NVMC_ERASE) {
371
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
372
+ }
373
+ break;
374
+
375
+ default:
376
+ qemu_log_mask(LOG_GUEST_ERROR,
377
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
378
+ }
379
+}
380
+
381
+static const MemoryRegionOps io_ops = {
382
+ .read = io_read,
383
+ .write = io_write,
384
+ .impl.min_access_size = 4,
385
+ .impl.max_access_size = 4,
386
+ .endianness = DEVICE_LITTLE_ENDIAN,
387
+};
388
+
389
+
390
+static void flash_write(void *opaque, hwaddr offset, uint64_t value,
391
+ unsigned int size)
392
+{
393
+ NRF51NVMState *s = NRF51_NVM(opaque);
394
+
395
+ if (s->config & NRF51_NVMC_CONFIG_WEN) {
396
+ uint32_t oldval;
397
+
398
+ assert(offset + size <= s->flash_size);
399
+
400
+ /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
401
+ oldval = ldl_le_p(s->storage + offset);
402
+ oldval &= value;
403
+ stl_le_p(s->storage + offset, oldval);
404
+
405
+ memory_region_flush_rom_device(&s->flash, offset, size);
406
+ } else {
407
+ qemu_log_mask(LOG_GUEST_ERROR,
408
+ "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
409
+ __func__, offset);
410
+ }
411
+}
412
+
413
+
414
+
415
+static const MemoryRegionOps flash_ops = {
416
+ .write = flash_write,
417
+ .valid.min_access_size = 4,
418
+ .valid.max_access_size = 4,
419
+ .endianness = DEVICE_LITTLE_ENDIAN,
420
+};
421
+
422
+static void nrf51_nvm_init(Object *obj)
423
+{
424
+ NRF51NVMState *s = NRF51_NVM(obj);
425
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
426
+
427
+ memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
428
+ NRF51_NVMC_SIZE);
429
+ sysbus_init_mmio(sbd, &s->mmio);
430
+
431
+ memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
432
+ sizeof(ficr_content));
433
+ sysbus_init_mmio(sbd, &s->ficr);
434
+
435
+ memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
436
+ sizeof(s->uicr_content));
437
+ sysbus_init_mmio(sbd, &s->uicr);
438
+}
439
+
440
+static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
441
+{
442
+ NRF51NVMState *s = NRF51_NVM(dev);
443
+ Error *err = NULL;
444
+
445
+ memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
446
+ "nrf51_soc.flash", s->flash_size, &err);
447
+ if (err) {
448
+ error_propagate(errp, err);
449
+ return;
450
+ }
451
+
452
+ s->storage = memory_region_get_ram_ptr(&s->flash);
453
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
454
+}
455
+
456
+static void nrf51_nvm_reset(DeviceState *dev)
457
+{
458
+ NRF51NVMState *s = NRF51_NVM(dev);
459
+
460
+ s->config = 0x00;
461
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
462
+}
463
+
464
+static Property nrf51_nvm_properties[] = {
465
+ DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
466
+ DEFINE_PROP_END_OF_LIST(),
467
+};
468
+
469
+static const VMStateDescription vmstate_nvm = {
470
+ .name = "nrf51_soc.nvm",
471
+ .version_id = 1,
472
+ .minimum_version_id = 1,
473
+ .fields = (VMStateField[]) {
474
+ VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
475
+ NRF51_UICR_FIXTURE_SIZE),
476
+ VMSTATE_UINT32(config, NRF51NVMState),
477
+ VMSTATE_END_OF_LIST()
478
+ }
479
+};
480
+
481
+static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
482
+{
483
+ DeviceClass *dc = DEVICE_CLASS(klass);
484
+
485
+ dc->props = nrf51_nvm_properties;
486
+ dc->vmsd = &vmstate_nvm;
487
+ dc->realize = nrf51_nvm_realize;
488
+ dc->reset = nrf51_nvm_reset;
489
+}
490
+
491
+static const TypeInfo nrf51_nvm_info = {
492
+ .name = TYPE_NRF51_NVM,
493
+ .parent = TYPE_SYS_BUS_DEVICE,
494
+ .instance_size = sizeof(NRF51NVMState),
495
+ .instance_init = nrf51_nvm_init,
496
+ .class_init = nrf51_nvm_class_init
497
+};
498
+
499
+static void nrf51_nvm_register_types(void)
500
+{
501
+ type_register_static(&nrf51_nvm_info);
502
+}
503
+
504
+type_init(nrf51_nvm_register_types)
505
--
506
2.20.1
507
508
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
Instantiates UICR, FICR, FLASH and NVMC in nRF51 SOC.
4
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190201023357.22596-3-stefanha@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/nrf51_soc.h | 2 ++
13
hw/arm/nrf51_soc.c | 41 +++++++++++++++++++++++++++-----------
14
2 files changed, 31 insertions(+), 12 deletions(-)
15
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/nrf51_soc.h
19
+++ b/include/hw/arm/nrf51_soc.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/char/nrf51_uart.h"
22
#include "hw/misc/nrf51_rng.h"
23
#include "hw/gpio/nrf51_gpio.h"
24
+#include "hw/nvram/nrf51_nvm.h"
25
#include "hw/timer/nrf51_timer.h"
26
27
#define TYPE_NRF51_SOC "nrf51-soc"
28
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
29
30
NRF51UARTState uart;
31
NRF51RNGState rng;
32
+ NRF51NVMState nvm;
33
NRF51GPIOState gpio;
34
NRF51TimerState timer[NRF51_NUM_TIMERS];
35
36
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/nrf51_soc.c
39
+++ b/hw/arm/nrf51_soc.c
40
@@ -XXX,XX +XXX,XX @@
41
* are supported in the future, add a sub-class of NRF51SoC for
42
* the specific variants
43
*/
44
-#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
45
-#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
46
+#define NRF51822_FLASH_PAGES 256
47
+#define NRF51822_SRAM_PAGES 16
48
+#define NRF51822_FLASH_SIZE (NRF51822_FLASH_PAGES * NRF51_PAGE_SIZE)
49
+#define NRF51822_SRAM_SIZE (NRF51822_SRAM_PAGES * NRF51_PAGE_SIZE)
50
51
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
52
53
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
54
55
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
56
57
- memory_region_init_rom(&s->flash, OBJECT(s), "nrf51.flash", s->flash_size,
58
- &err);
59
- if (err) {
60
- error_propagate(errp, err);
61
- return;
62
- }
63
- memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
64
-
65
memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
66
&err);
67
if (err) {
68
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
69
qdev_get_gpio_in(DEVICE(&s->cpu),
70
BASE_TO_IRQ(NRF51_RNG_BASE)));
71
72
+ /* UICR, FICR, NVMC, FLASH */
73
+ object_property_set_uint(OBJECT(&s->nvm), s->flash_size, "flash-size",
74
+ &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
+
80
+ object_property_set_bool(OBJECT(&s->nvm), true, "realized", &err);
81
+ if (err) {
82
+ error_propagate(errp, err);
83
+ return;
84
+ }
85
+
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 0);
87
+ memory_region_add_subregion_overlap(&s->container, NRF51_NVMC_BASE, mr, 0);
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 1);
89
+ memory_region_add_subregion_overlap(&s->container, NRF51_FICR_BASE, mr, 0);
90
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 2);
91
+ memory_region_add_subregion_overlap(&s->container, NRF51_UICR_BASE, mr, 0);
92
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 3);
93
+ memory_region_add_subregion_overlap(&s->container, NRF51_FLASH_BASE, mr, 0);
94
+
95
/* GPIO */
96
object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
97
if (err) {
98
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
99
100
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
101
NRF51_IOMEM_SIZE);
102
- create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
103
- NRF51_FICR_SIZE);
104
create_unimplemented_device("nrf51_soc.private",
105
NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
108
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
109
TYPE_NRF51_RNG);
110
111
+ sysbus_init_child_obj(obj, "nvm", &s->nvm, sizeof(s->nvm), TYPE_NRF51_NVM);
112
+
113
sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
114
TYPE_NRF51_GPIO);
115
116
--
117
2.20.1
118
119
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Acked-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190201023357.22596-4-stefanha@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
tests/microbit-test.c | 108 ++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
12
13
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/microbit-test.c
16
+++ b/tests/microbit-test.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/arm/nrf51.h"
19
#include "hw/char/nrf51_uart.h"
20
#include "hw/gpio/nrf51_gpio.h"
21
+#include "hw/nvram/nrf51_nvm.h"
22
#include "hw/timer/nrf51_timer.h"
23
#include "hw/i2c/microbit_i2c.h"
24
25
@@ -XXX,XX +XXX,XX @@ static void test_microbit_i2c(void)
26
qtest_quit(qts);
27
}
28
29
+#define FLASH_SIZE (256 * NRF51_PAGE_SIZE)
30
+
31
+static void fill_and_erase(QTestState *qts, hwaddr base, hwaddr size,
32
+ uint32_t address_reg)
33
+{
34
+ hwaddr i;
35
+
36
+ /* Erase Page */
37
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
38
+ qtest_writel(qts, NRF51_NVMC_BASE + address_reg, base);
39
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
40
+
41
+ /* Check memory */
42
+ for (i = 0; i < size / 4; i++) {
43
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, 0xFFFFFFFF);
44
+ }
45
+
46
+ /* Fill memory */
47
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
48
+ for (i = 0; i < size / 4; i++) {
49
+ qtest_writel(qts, base + i * 4, i);
50
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, i);
51
+ }
52
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
53
+}
54
+
55
+static void test_nrf51_nvmc(void)
56
+{
57
+ uint32_t value;
58
+ hwaddr i;
59
+ QTestState *qts = qtest_init("-M microbit");
60
+
61
+ /* Test always ready */
62
+ value = qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_READY);
63
+ g_assert_cmpuint(value & 0x01, ==, 0x01);
64
+
65
+ /* Test write-read config register */
66
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x03);
67
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
68
+ ==, 0x03);
69
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
70
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
71
+ ==, 0x00);
72
+
73
+ /* Test PCR0 */
74
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
75
+ NRF51_NVMC_ERASEPCR0);
76
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
77
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR0);
78
+
79
+ /* Test PCR1 */
80
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
81
+ NRF51_NVMC_ERASEPCR1);
82
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
83
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR1);
84
+
85
+ /* Erase all */
86
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
87
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
88
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
89
+
90
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
91
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
92
+ qtest_writel(qts, NRF51_FLASH_BASE + i * 4, i);
93
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4), ==, i);
94
+ }
95
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
96
+
97
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
98
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
99
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
100
+
101
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
102
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4),
103
+ ==, 0xFFFFFFFF);
104
+ }
105
+
106
+ /* Erase UICR */
107
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
108
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
109
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
110
+
111
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
112
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
113
+ ==, 0xFFFFFFFF);
114
+ }
115
+
116
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
117
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
118
+ qtest_writel(qts, NRF51_UICR_BASE + i * 4, i);
119
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), ==, i);
120
+ }
121
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
122
+
123
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
124
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
125
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
126
+
127
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
128
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
129
+ ==, 0xFFFFFFFF);
130
+ }
131
+
132
+ qtest_quit(qts);
133
+}
134
+
135
static void test_nrf51_gpio(void)
136
{
137
size_t i;
138
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
139
140
qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart);
141
qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
142
+ qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
143
qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
144
qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c);
145
146
--
147
2.20.1
148
149
diff view generated by jsdifflib