1
A small set of arm bugfixes for rc0.
1
As promised, more Arm patches. The big thing in here is the
2
MPS2-AN521 board model.
2
3
4
thanks
5
-- PMM
3
6
7
The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:
4
8
5
The following changes since commit 5853e92207193e967abf5e4c25b4a551c7604725:
9
Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)
6
10
7
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-cocoa-20171107' into staging (2017-11-07 12:19:48 +0000)
11
are available in the Git repository at:
8
12
9
are available in the git repository at:
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190201
10
14
11
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171107
15
for you to fetch changes up to 7743b70ffe7a8ce168adce2cf50ad156b1fefb8c:
12
16
13
for you to fetch changes up to 8a7348b5d62d7ea16807e6bea54b448a0184bb0f:
17
tests/microbit-test: Add tests for nRF51 NVMC (2019-02-01 15:32:17 +0000)
14
15
hw/intc/arm_gicv3_its: Don't abort on table save failure (2017-11-07 13:03:52 +0000)
16
18
17
----------------------------------------------------------------
19
----------------------------------------------------------------
18
target-arm queue:
20
target-arm queue:
19
* arm_gicv3_its: Don't abort on table save failure
21
* New machine mps2-an521 -- this is a model of the AN521 FPGA image for the MPS2 devboard
20
* arm_gicv3_its: Fix the VM termination in vm_change_state_handler()
22
* Fix various places where we failed to UNDEF invalid A64 instructions
21
* translate.c: Fix usermode big-endian AArch32 LDREXD and STREXD
23
* Don't UNDEF a valid FCMLA on 32-bit inputs
22
* hw/arm: Mark the "fsl,imx31/25/6" devices with user_creatable = false
24
* Fix some bugs in the newly-added PAuth implementation
23
* arm: implement cache/shareability attribute bits for PAR registers
25
* microbit: Implement NVMC non-volatile memory controller
24
26
25
----------------------------------------------------------------
27
----------------------------------------------------------------
26
Andrew Baumann (1):
28
Aaron Lindsay OS (2):
27
arm: implement cache/shareability attribute bits for PAR registers
29
target/arm: Send interrupts on PMU counter overflow
30
target/arm: Add a timer to predict PMU counter overflow
28
31
29
Eric Auger (1):
32
Julia Suvorova (1):
30
hw/intc/arm_gicv3_its: Don't abort on table save failure
33
arm: Clarify the logic of set_pc()
31
34
32
Peter Maydell (1):
35
Peter Maydell (33):
33
translate.c: Fix usermode big-endian AArch32 LDREXD and STREXD
36
armv7m: Don't assume the NVIC's CPU is CPU 0
37
armv7m: Make cpu object a child of the armv7m container
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
34
69
35
Shanker Donthineni (1):
70
Remi Denis-Courmont (2):
36
hw/intc/arm_gicv3_its: Fix the VM termination in vm_change_state_handler()
71
target/arm: fix AArch64 virtual address space size
72
target/arm: fix decoding of B{,L}RA{A,B}
37
73
38
Thomas Huth (3):
74
Richard Henderson (5):
39
hw/arm: Mark the "fsl,imx6" device with user_creatable = false
75
target/arm: Enable API, APK bits in SCR, HCR
40
hw/arm: Mark the "fsl,imx25" device with user_creatable = false
76
target/arm: Always enable pac keys for user-only
41
hw/arm: Mark the "fsl,imx31" device with user_creatable = false
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
42
80
43
hw/arm/fsl-imx25.c | 6 +-
81
Steffen Görtz (3):
44
hw/arm/fsl-imx31.c | 6 +-
82
hw/nvram/nrf51_nvm: Add nRF51 non-volatile memories
45
hw/arm/fsl-imx6.c | 3 +-
83
arm: Instantiate NRF51 special NVM's and NVMC
46
hw/intc/arm_gicv3_its_kvm.c | 12 +--
84
tests/microbit-test: Add tests for nRF51 NVMC
47
target/arm/helper.c | 178 ++++++++++++++++++++++++++++++++++++++++----
48
target/arm/translate.c | 39 ++++++++--
49
6 files changed, 214 insertions(+), 30 deletions(-)
50
85
86
kumar sourav (1):
87
hw/arm/nrf51_soc: set object owner in memory_region_init_ram
88
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
New patch
1
From: kumar sourav <sourav.jb1988@gmail.com>
1
2
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
New 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.
1
7
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
New 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.
1
5
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
New 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.)
1
6
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
New patch
1
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
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
New 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.)
1
8
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
New patch
1
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
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
New 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.
1
4
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
New 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.)
1
8
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
New 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.
1
4
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
New 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).
1
5
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
New 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.
1
8
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
New 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
1
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-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
New 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).
1
4
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
New 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.
1
5
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
New 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.
1
4
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
New patch
1
Add unimplemented-device stubs for the various Power Policy Unit
2
devices that the SSE-200 has.
1
3
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
New 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.
1
3
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
New 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.)
1
6
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
New patch
1
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
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
New patch
1
Instantiate a copy of the CPU_IDENTITY register block for each CPU
2
in an SSE-200.
1
3
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
New 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.
1
3
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
New 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.
1
4
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
New 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.
1
4
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
New 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.
1
5
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
New 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.
1
6
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
New 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.
1
6
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
New 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.
1
6
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
New 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.
1
4
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
New 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
1
9
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
New 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.
1
5
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
1
For AArch32 LDREXD and STREXD, architecturally the 32-bit word at the
1
The tcg_register_iommu_notifier() code has a GArray of
2
lowest address is always Rt and the one at addr+4 is Rt2, even if the
2
TCGIOMMUNotifier structs which it has registered by passing
3
CPU is big-endian. Our implementation does these with a single
3
memory_region_register_iommu_notifier() a pointer to the embedded
4
64-bit store, so if we're big-endian then we need to put the two
4
IOMMUNotifier field. Unfortunately, if we need to enlarge the
5
32-bit halves together in the opposite order to little-endian,
5
array via g_array_set_size() this can cause a realloc(), which
6
so that they end up in the right places. We were trying to do
6
invalidates the pointer that memory_region_register_iommu_notifier()
7
this with the gen_aa32_frob64() function, but that is not correct
7
put into the MemoryRegion's iommu_notify list. This can result
8
for the usermode emulator, because there there is a distinction
8
in segfaults.
9
between "load a 64 bit value" (which does a BE 64-bit access
10
and doesn't need swapping) and "load two 32 bit values as one
11
64 bit access" (where we still need to do the swapping, like
12
system mode BE32).
13
9
14
Fixes: https://bugs.launchpad.net/qemu/+bug/1725267
10
Switch the GArray to holding pointers to the TCGIOMMUNotifier
11
structs, so that we can individually allocate and free them.
12
15
Cc: qemu-stable@nongnu.org
13
Cc: qemu-stable@nongnu.org
14
Fixes: 1f871c5e6b0f30644a60a ("exec.c: Handle IOMMUs in address_space_translate_for_iotlb()")
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 1509622400-13351-1-git-send-email-peter.maydell@linaro.org
17
Message-id: 20190128174241.5860-1-peter.maydell@linaro.org
19
---
18
---
20
target/arm/translate.c | 39 ++++++++++++++++++++++++++++++++++-----
19
exec.c | 10 ++++++----
21
1 file changed, 34 insertions(+), 5 deletions(-)
20
1 file changed, 6 insertions(+), 4 deletions(-)
22
21
23
diff --git a/target/arm/translate.c b/target/arm/translate.c
22
diff --git a/exec.c b/exec.c
24
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate.c
24
--- a/exec.c
26
+++ b/target/arm/translate.c
25
+++ b/exec.c
27
@@ -XXX,XX +XXX,XX @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
26
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
28
TCGv_i32 tmp2 = tcg_temp_new_i32();
27
int i;
29
TCGv_i64 t64 = tcg_temp_new_i64();
28
30
29
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
31
- gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
30
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
32
+ /* For AArch32, architecturally the 32-bit word at the lowest
31
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
33
+ * address is always Rt and the one at addr+4 is Rt2, even if
32
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
34
+ * the CPU is big-endian. That means we don't want to do a
33
break;
35
+ * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
34
}
36
+ * for an architecturally 64-bit access, but instead do a
35
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
37
+ * 64-bit access using MO_BE if appropriate and then split
36
if (i == cpu->iommu_notifiers->len) {
38
+ * the two halves.
37
/* Not found, add a new entry at the end of the array */
39
+ * This only makes a difference for BE32 user-mode, where
38
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
40
+ * frob64() must not flip the two halves of the 64-bit data
39
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
41
+ * but this code must treat BE32 user-mode like BE32 system.
40
+ notifier = g_new0(TCGIOMMUNotifier, 1);
42
+ */
41
+ g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
43
+ TCGv taddr = gen_aa32_addr(s, addr, opc);
42
44
+
43
notifier->mr = mr;
45
+ tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
44
notifier->iommu_idx = iommu_idx;
46
+ tcg_temp_free(taddr);
45
@@ -XXX,XX +XXX,XX @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
47
tcg_gen_mov_i64(cpu_exclusive_val, t64);
46
TCGIOMMUNotifier *notifier;
48
- tcg_gen_extr_i64_i32(tmp, tmp2, t64);
47
49
+ if (s->be_data == MO_BE) {
48
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
50
+ tcg_gen_extr_i64_i32(tmp2, tmp, t64);
49
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
51
+ } else {
50
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
52
+ tcg_gen_extr_i64_i32(tmp, tmp2, t64);
51
memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
53
+ }
52
+ g_free(notifier);
54
tcg_temp_free_i64(t64);
53
}
55
54
g_array_free(cpu->iommu_notifiers, true);
56
store_reg(s, rt2, tmp2);
55
}
57
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
56
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
58
TCGv_i64 n64 = tcg_temp_new_i64();
57
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
59
58
}
60
t2 = load_reg(s, rt2);
59
61
- tcg_gen_concat_i32_i64(n64, t1, t2);
60
- cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
62
+ /* For AArch32, architecturally the 32-bit word at the lowest
61
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier *));
63
+ * address is always Rt and the one at addr+4 is Rt2, even if
62
#endif
64
+ * the CPU is big-endian. Since we're going to treat this as a
63
}
65
+ * single 64-bit BE store, we need to put the two halves in the
66
+ * opposite order for BE to LE, so that they end up in the right
67
+ * places.
68
+ * We don't want gen_aa32_frob64() because that does the wrong
69
+ * thing for BE32 usermode.
70
+ */
71
+ if (s->be_data == MO_BE) {
72
+ tcg_gen_concat_i32_i64(n64, t2, t1);
73
+ } else {
74
+ tcg_gen_concat_i32_i64(n64, t1, t2);
75
+ }
76
tcg_temp_free_i32(t2);
77
- gen_aa32_frob64(s, n64);
78
79
tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
80
get_mem_index(s), opc);
81
tcg_temp_free_i64(n64);
82
83
- gen_aa32_frob64(s, o64);
84
tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
85
tcg_gen_extrl_i64_i32(t0, o64);
86
64
87
--
65
--
88
2.7.4
66
2.20.1
89
67
90
68
diff view generated by jsdifflib
New 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.
1
5
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
New 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.
1
7
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
1
From: Andrew Baumann <Andrew.Baumann@microsoft.com>
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
2
3
On a successful address translation instruction, PAR is supposed to
3
Whenever we notice that a counter overflow has occurred, send an
4
contain cacheability and shareability attributes determined by the
4
interrupt. This is made more reliable with the addition of a timer in a
5
translation. We previously returned 0 for these bits (in line with the
5
follow-on commit.
6
general strategy of ignoring caches and memory attributes), but some
7
guest OSes may depend on them.
8
6
9
This patch collects the attribute bits in the page-table walk, and
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
updates PAR with the correct attributes for all LPAE translations.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Short descriptor formats still return 0 for these bits, as in the
9
Message-id: 20190124162401.5111-2-aaron@os.amperecomputing.com
12
prior implementation.
13
14
Signed-off-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
15
Message-id: 20171031223830.4608-1-Andrew.Baumann@microsoft.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
target/arm/helper.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++-----
12
target/arm/helper.c | 61 +++++++++++++++++++++++++++++++++++++--------
20
1 file changed, 164 insertions(+), 14 deletions(-)
13
1 file changed, 51 insertions(+), 10 deletions(-)
21
14
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
27
#define ARM_CPU_FREQ 1000000000 /* FIXME: 1 GHz, should be configurable */
20
/* Definitions for the PMU registers */
28
21
#define PMCRN_MASK 0xf800
29
#ifndef CONFIG_USER_ONLY
22
#define PMCRN_SHIFT 11
30
+/* Cacheability and shareability attributes for a memory access */
23
+#define PMCRLC 0x40
31
+typedef struct ARMCacheAttrs {
24
#define PMCRDP 0x10
32
+ unsigned int attrs:8; /* as in the MAIR register encoding */
25
#define PMCRD 0x8
33
+ unsigned int shareability:2; /* as in the SH field of the VMSAv8-64 PTEs */
26
#define PMCRC 0x4
34
+} ARMCacheAttrs;
27
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
35
+
28
return enabled && !prohibited && !filtered;
36
static bool get_phys_addr(CPUARMState *env, target_ulong address,
37
MMUAccessType access_type, ARMMMUIdx mmu_idx,
38
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
39
target_ulong *page_size, uint32_t *fsr,
40
- ARMMMUFaultInfo *fi);
41
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
42
43
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
44
MMUAccessType access_type, ARMMMUIdx mmu_idx,
45
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
46
target_ulong *page_size_ptr, uint32_t *fsr,
47
- ARMMMUFaultInfo *fi);
48
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
49
50
/* Security attributes for an address, as returned by v8m_security_lookup. */
51
typedef struct V8M_SAttributes {
52
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
53
uint64_t par64;
54
MemTxAttrs attrs = {};
55
ARMMMUFaultInfo fi = {};
56
+ ARMCacheAttrs cacheattrs = {};
57
58
- ret = get_phys_addr(env, value, access_type, mmu_idx,
59
- &phys_addr, &attrs, &prot, &page_size, &fsr, &fi);
60
+ ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
61
+ &prot, &page_size, &fsr, &fi, &cacheattrs);
62
if (extended_addresses_enabled(env)) {
63
/* fsr is a DFSR/IFSR value for the long descriptor
64
* translation table format, but with WnR always clear.
65
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
66
if (!attrs.secure) {
67
par64 |= (1 << 9); /* NS */
68
}
69
- /* We don't set the ATTR or SH fields in the PAR. */
70
+ par64 |= (uint64_t)cacheattrs.attrs << 56; /* ATTR */
71
+ par64 |= cacheattrs.shareability << 7; /* SH */
72
} else {
73
par64 |= 1; /* F */
74
par64 |= (fsr & 0x3f) << 1; /* FS */
75
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
76
return false;
77
}
78
if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx,
79
- &physaddr, &attrs, &prot, &page_size, &fsr, &fi)) {
80
+ &physaddr, &attrs, &prot, &page_size, &fsr, &fi, NULL)) {
81
/* the MPU lookup failed */
82
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
83
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
84
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
85
int ret;
86
87
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
88
- &txattrs, &s2prot, &s2size, fsr, fi);
89
+ &txattrs, &s2prot, &s2size, fsr, fi, NULL);
90
if (ret) {
91
fi->s2addr = addr;
92
fi->stage2 = true;
93
@@ -XXX,XX +XXX,XX @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
94
return true;
95
}
29
}
96
30
97
+/* Translate from the 4-bit stage 2 representation of
31
+static void pmu_update_irq(CPUARMState *env)
98
+ * memory attributes (without cache-allocation hints) to
99
+ * the 8-bit representation of the stage 1 MAIR registers
100
+ * (which includes allocation hints).
101
+ *
102
+ * ref: shared/translation/attrs/S2AttrDecode()
103
+ * .../S2ConvertAttrsHints()
104
+ */
105
+static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
106
+{
32
+{
107
+ uint8_t hiattr = extract32(s2attrs, 2, 2);
33
+ ARMCPU *cpu = arm_env_get_cpu(env);
108
+ uint8_t loattr = extract32(s2attrs, 0, 2);
34
+ qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
109
+ uint8_t hihint = 0, lohint = 0;
35
+ (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
110
+
111
+ if (hiattr != 0) { /* normal memory */
112
+ if ((env->cp15.hcr_el2 & HCR_CD) != 0) { /* cache disabled */
113
+ hiattr = loattr = 1; /* non-cacheable */
114
+ } else {
115
+ if (hiattr != 1) { /* Write-through or write-back */
116
+ hihint = 3; /* RW allocate */
117
+ }
118
+ if (loattr != 1) { /* Write-through or write-back */
119
+ lohint = 3; /* RW allocate */
120
+ }
121
+ }
122
+ }
123
+
124
+ return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
125
+}
36
+}
126
+
37
+
127
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
38
/*
128
MMUAccessType access_type, ARMMMUIdx mmu_idx,
39
* Ensure c15_ccnt is the guest-visible count so that operations such as
129
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
40
* enabling/disabling the counter or filtering, modifying the count itself,
130
target_ulong *page_size_ptr, uint32_t *fsr,
41
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
131
- ARMMMUFaultInfo *fi)
42
eff_cycles /= 64;
132
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
43
}
133
{
44
134
ARMCPU *cpu = arm_env_get_cpu(env);
45
- env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
135
CPUState *cs = CPU(cpu);
46
+ uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
136
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
137
*/
138
txattrs->secure = false;
139
}
140
+
47
+
141
+ if (cacheattrs != NULL) {
48
+ uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
142
+ if (mmu_idx == ARMMMUIdx_S2NS) {
49
+ 1ull << 63 : 1ull << 31;
143
+ cacheattrs->attrs = convert_stage2_attrs(env,
50
+ if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
144
+ extract32(attrs, 0, 4));
51
+ env->cp15.c9_pmovsr |= (1 << 31);
145
+ } else {
52
+ pmu_update_irq(env);
146
+ /* Index into MAIR registers for cache attributes */
147
+ uint8_t attrindx = extract32(attrs, 0, 3);
148
+ uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
149
+ assert(attrindx <= 7);
150
+ cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
151
+ }
152
+ cacheattrs->shareability = extract32(attrs, 6, 2);
153
+ }
154
+
155
*phys_ptr = descaddr;
156
*page_size_ptr = page_size;
157
return false;
158
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
159
return false;
160
}
161
162
+/* Combine either inner or outer cacheability attributes for normal
163
+ * memory, according to table D4-42 and pseudocode procedure
164
+ * CombineS1S2AttrHints() of ARM DDI 0487B.b (the ARMv8 ARM).
165
+ *
166
+ * NB: only stage 1 includes allocation hints (RW bits), leading to
167
+ * some asymmetry.
168
+ */
169
+static uint8_t combine_cacheattr_nibble(uint8_t s1, uint8_t s2)
170
+{
171
+ if (s1 == 4 || s2 == 4) {
172
+ /* non-cacheable has precedence */
173
+ return 4;
174
+ } else if (extract32(s1, 2, 2) == 0 || extract32(s1, 2, 2) == 2) {
175
+ /* stage 1 write-through takes precedence */
176
+ return s1;
177
+ } else if (extract32(s2, 2, 2) == 2) {
178
+ /* stage 2 write-through takes precedence, but the allocation hint
179
+ * is still taken from stage 1
180
+ */
181
+ return (2 << 2) | extract32(s1, 0, 2);
182
+ } else { /* write-back */
183
+ return s1;
184
+ }
185
+}
186
+
187
+/* Combine S1 and S2 cacheability/shareability attributes, per D4.5.4
188
+ * and CombineS1S2Desc()
189
+ *
190
+ * @s1: Attributes from stage 1 walk
191
+ * @s2: Attributes from stage 2 walk
192
+ */
193
+static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
194
+{
195
+ uint8_t s1lo = extract32(s1.attrs, 0, 4), s2lo = extract32(s2.attrs, 0, 4);
196
+ uint8_t s1hi = extract32(s1.attrs, 4, 4), s2hi = extract32(s2.attrs, 4, 4);
197
+ ARMCacheAttrs ret;
198
+
199
+ /* Combine shareability attributes (table D4-43) */
200
+ if (s1.shareability == 2 || s2.shareability == 2) {
201
+ /* if either are outer-shareable, the result is outer-shareable */
202
+ ret.shareability = 2;
203
+ } else if (s1.shareability == 3 || s2.shareability == 3) {
204
+ /* if either are inner-shareable, the result is inner-shareable */
205
+ ret.shareability = 3;
206
+ } else {
207
+ /* both non-shareable */
208
+ ret.shareability = 0;
209
+ }
210
+
211
+ /* Combine memory type and cacheability attributes */
212
+ if (s1hi == 0 || s2hi == 0) {
213
+ /* Device has precedence over normal */
214
+ if (s1lo == 0 || s2lo == 0) {
215
+ /* nGnRnE has precedence over anything */
216
+ ret.attrs = 0;
217
+ } else if (s1lo == 4 || s2lo == 4) {
218
+ /* non-Reordering has precedence over Reordering */
219
+ ret.attrs = 4; /* nGnRE */
220
+ } else if (s1lo == 8 || s2lo == 8) {
221
+ /* non-Gathering has precedence over Gathering */
222
+ ret.attrs = 8; /* nGRE */
223
+ } else {
224
+ ret.attrs = 0xc; /* GRE */
225
+ }
53
+ }
226
+
54
+
227
+ /* Any location for which the resultant memory type is any
55
+ env->cp15.c15_ccnt = new_pmccntr;
228
+ * type of Device memory is always treated as Outer Shareable.
56
}
229
+ */
57
env->cp15.c15_ccnt_delta = cycles;
230
+ ret.shareability = 2;
58
}
231
+ } else { /* Normal memory */
59
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
232
+ /* Outer/inner cacheability combine independently */
60
}
233
+ ret.attrs = combine_cacheattr_nibble(s1hi, s2hi) << 4
61
234
+ | combine_cacheattr_nibble(s1lo, s2lo);
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];
235
+
66
+
236
+ if (ret.attrs == 0x44) {
67
+ if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
237
+ /* Any location for which the resultant memory type is Normal
68
+ env->cp15.c9_pmovsr |= (1 << counter);
238
+ * Inner Non-cacheable, Outer Non-cacheable is always treated
69
+ pmu_update_irq(env);
239
+ * as Outer Shareable.
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
240
+ */
84
+ */
241
+ ret.shareability = 2;
85
+ uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
242
+ }
243
+ }
244
+
86
+
245
+ return ret;
87
+ if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
246
+}
88
+ env->cp15.c9_pmovsr |= (1 << i);
247
+
89
+ pmu_update_irq(env);
248
+
249
/* get_phys_addr - get the physical address for this virtual address
250
*
251
* Find the physical address corresponding to the given virtual address,
252
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
253
* @prot: set to the permissions for the page containing phys_ptr
254
* @page_size: set to the size of the page containing phys_ptr
255
* @fsr: set to the DFSR/IFSR value on failure
256
+ * @fi: set to fault info if the translation fails
257
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
258
*/
259
static bool get_phys_addr(CPUARMState *env, target_ulong address,
260
MMUAccessType access_type, ARMMMUIdx mmu_idx,
261
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
262
target_ulong *page_size, uint32_t *fsr,
263
- ARMMMUFaultInfo *fi)
264
+ ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
265
{
266
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
267
/* Call ourselves recursively to do the stage 1 and then stage 2
268
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
269
hwaddr ipa;
270
int s2_prot;
271
int ret;
272
+ ARMCacheAttrs cacheattrs2 = {};
273
274
ret = get_phys_addr(env, address, access_type,
275
stage_1_mmu_idx(mmu_idx), &ipa, attrs,
276
- prot, page_size, fsr, fi);
277
+ prot, page_size, fsr, fi, cacheattrs);
278
279
/* If S1 fails or S2 is disabled, return early. */
280
if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) {
281
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
282
/* S1 is done. Now do S2 translation. */
283
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
284
phys_ptr, attrs, &s2_prot,
285
- page_size, fsr, fi);
286
+ page_size, fsr, fi,
287
+ cacheattrs != NULL ? &cacheattrs2 : NULL);
288
fi->s2addr = ipa;
289
/* Combine the S1 and S2 perms. */
290
*prot &= s2_prot;
291
+
292
+ /* Combine the S1 and S2 cache attributes, if needed */
293
+ if (!ret && cacheattrs != NULL) {
294
+ *cacheattrs = combine_cacheattrs(*cacheattrs, cacheattrs2);
295
+ }
90
+ }
296
+
91
+
297
return ret;
92
+ env->cp15.c14_pmevcntr[i] = new_pmswinc;
298
} else {
93
+
299
/*
94
pmevcntr_op_finish(env, i);
300
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
95
}
301
96
}
302
if (regime_using_lpae_format(env, mmu_idx)) {
97
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
303
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
98
{
304
- attrs, prot, page_size, fsr, fi);
99
value &= pmu_counter_mask(env);
305
+ attrs, prot, page_size, fsr, fi, cacheattrs);
100
env->cp15.c9_pmovsr &= ~value;
306
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
101
+ pmu_update_irq(env);
307
return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
102
}
308
attrs, prot, page_size, fsr, fi);
103
309
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
104
static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
310
105
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
311
ret = get_phys_addr(env, address, access_type,
106
{
312
core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
107
value &= pmu_counter_mask(env);
313
- &attrs, &prot, &page_size, fsr, fi);
108
env->cp15.c9_pmovsr |= value;
314
+ &attrs, &prot, &page_size, fsr, fi, NULL);
109
+ pmu_update_irq(env);
315
if (!ret) {
110
}
316
/* Map a single [sub]page. */
111
317
phys_addr &= TARGET_PAGE_MASK;
112
static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
318
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
113
@@ -XXX,XX +XXX,XX @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
319
*attrs = (MemTxAttrs) {};
114
/* We have no event counters so only the C bit can be changed */
320
115
value &= pmu_counter_mask(env);
321
ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
116
env->cp15.c9_pminten |= value;
322
- attrs, &prot, &page_size, &fsr, &fi);
117
+ pmu_update_irq(env);
323
+ attrs, &prot, &page_size, &fsr, &fi, NULL);
118
}
324
119
325
if (ret) {
120
static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
326
return -1;
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 },
327
--
177
--
328
2.7.4
178
2.20.1
329
179
330
180
diff view generated by jsdifflib
New patch
1
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
2
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
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
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
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Julia Suvorova <jusual@mail.ru>
2
2
3
The ITS is not fully properly reset at the moment. Caches are
3
Until now, the set_pc logic was unclear, which raised questions about
4
not emptied.
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.
5
8
6
After a reset, in case we attempt to save the state before
9
Signed-off-by: Julia Suvorova <jusual@mail.ru>
7
the bound devices have registered their MSIs and after the
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
8
1st level table has been allocated by the ITS driver
11
Message-id: 20190129121817.7109-1-jusual@mail.ru
9
(device BASER is valid), the first level entries are still
10
invalid. If the device cache is not empty (devices registered
11
before the reset), vgic_its_save_device_tables fails with -EINVAL.
12
This causes a QEMU abort().
13
14
Cc: qemu-stable@nongnu.org
15
Signed-off-by: Eric Auger <eric.auger@redhat.com>
16
Reported-by: wanghaibin <wanghaibin.wang@huawei.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
14
---
20
hw/intc/arm_gicv3_its_kvm.c | 8 ++------
15
include/qom/cpu.h | 16 ++++++++++++++--
21
1 file changed, 2 insertions(+), 6 deletions(-)
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(-)
22
21
23
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
22
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
24
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/arm_gicv3_its_kvm.c
24
--- a/include/qom/cpu.h
26
+++ b/hw/intc/arm_gicv3_its_kvm.c
25
+++ b/include/qom/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static void vm_change_state_handler(void *opaque, int running,
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)
28
{
87
{
29
GICv3ITSState *s = (GICv3ITSState *)opaque;
88
ARMCPU *cpu = ARM_CPU(cs);
30
Error *err = NULL;
89
+ CPUARMState *env = &cpu->env;
31
- int ret;
90
32
91
- cpu->env.regs[15] = value;
33
if (running) {
92
+ if (is_a64(env)) {
34
return;
93
+ env->pc = value;
35
}
94
+ env->thumb = 0;
36
95
+ } else {
37
- ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
96
+ env->regs[15] = value & ~1;
38
- KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
97
+ env->thumb = value & 1;
39
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
98
+ }
40
+ KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
99
+}
41
if (err) {
100
+
42
error_report_err(err);
101
+static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
43
}
102
+{
44
- if (ret < 0 && ret != -EFAULT) {
103
+ ARMCPU *cpu = ARM_CPU(cs);
45
- abort();
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;
46
- }
145
- }
47
}
146
-}
48
147
-
49
static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
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;
50
--
159
--
51
2.7.4
160
2.20.1
52
161
53
162
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This device causes QEMU to abort if the user tries to instantiate it:
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).
4
6
5
$ qemu-system-aarch64 -M sabrelite -smp 1,maxcpus=2 -device fsl,,imx6
7
We can re-introduce the properties if they turn out to be useful.
6
Unexpected error in qemu_chr_fe_init() at chardev/char-fe.c:222:
8
But since linux 5.0 enables all of the keys, they may not be.
7
qemu-system-aarch64: -device fsl,,imx6: Device 'serial0' is in use
8
Aborted (core dumped)
9
9
10
The device uses serial_hds[] directly in its realize function, so it
10
Fixes: 1ae9cfbd470
11
can not be instantiated again by the user.
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
13
Signed-off-by: Thomas Huth <thuth@redhat.com>
14
Message-id: 1509519537-6964-2-git-send-email-thuth@redhat.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
hw/arm/fsl-imx6.c | 3 ++-
15
target/arm/cpu.c | 3 +++
19
1 file changed, 2 insertions(+), 1 deletion(-)
16
target/arm/cpu64.c | 60 ----------------------------------------------
17
2 files changed, 3 insertions(+), 60 deletions(-)
20
18
21
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/fsl-imx6.c
21
--- a/target/arm/cpu.c
24
+++ b/hw/arm/fsl-imx6.c
22
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_class_init(ObjectClass *oc, void *data)
23
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
26
DeviceClass *dc = DEVICE_CLASS(oc);
24
env->pstate = PSTATE_MODE_EL0t;
27
25
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
28
dc->realize = fsl_imx6_realize;
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;
29
-
48
-
30
dc->desc = "i.MX6 SOC";
49
- visit_type_bool(v, name, &enabled, errp);
31
+ /* Reason: Uses serial_hds[] in the realize() function */
50
-}
32
+ dc->user_creatable = false;
51
-
33
}
52
-static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
34
53
- void *opaque, Error **errp)
35
static const TypeInfo fsl_imx6_type_info = {
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;
36
--
111
--
37
2.7.4
112
2.20.1
38
113
39
114
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
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
1
From: Thomas Huth <thuth@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
QEMU currently crashes when the user tries to instantiate the fsl,imx31
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
device manually:
5
6
$ aarch64-softmmu/qemu-system-aarch64 -M kzm -device fsl,,imx31
7
**
8
ERROR:/home/thuth/devel/qemu/tcg/tcg.c:538:tcg_register_thread:
9
assertion failed: (n < max_cpus)
10
Aborted (core dumped)
11
12
The kzm board (which is the one that uses this CPU type) only supports
13
one CPU, and the realize function of the "fsl,imx31" device also uses
14
serial_hds[] directly, so this device clearly can not be instantiated
15
twice and thus we should mark it with user_creatable = false.
16
17
Signed-off-by: Thomas Huth <thuth@redhat.com>
18
Message-id: 1509519537-6964-4-git-send-email-thuth@redhat.com
19
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
6
---
22
hw/arm/fsl-imx31.c | 6 +++++-
7
linux-user/elfload.c | 1 +
23
1 file changed, 5 insertions(+), 1 deletion(-)
8
1 file changed, 1 insertion(+)
24
9
25
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
26
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/fsl-imx31.c
12
--- a/linux-user/elfload.c
28
+++ b/hw/arm/fsl-imx31.c
13
+++ b/linux-user/elfload.c
29
@@ -XXX,XX +XXX,XX @@ static void fsl_imx31_class_init(ObjectClass *oc, void *data)
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
30
DeviceClass *dc = DEVICE_CLASS(oc);
15
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
31
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
32
dc->realize = fsl_imx31_realize;
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
33
-
18
+ GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
34
dc->desc = "i.MX31 SOC";
19
35
+ /*
20
#undef GET_FEATURE_ID
36
+ * Reason: uses serial_hds in realize and the kzm board does not
21
37
+ * support multiple CPUs
38
+ */
39
+ dc->user_creatable = false;
40
}
41
42
static const TypeInfo fsl_imx31_type_info = {
43
--
22
--
44
2.7.4
23
2.20.1
45
24
46
25
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
QEMU currently crashes when the user tries to instantiate the fsl,imx25
3
Initialize the keys to a non-zero value on process start.
4
device manually:
5
4
6
$ aarch64-softmmu/qemu-system-aarch64 -S -M imx25-pdk -device fsl,,imx25
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
**
8
ERROR:/home/thuth/devel/qemu/tcg/tcg.c:538:tcg_register_thread:
9
assertion failed: (n < max_cpus)
10
11
The imx25-pdk board (which is the one that uses this CPU type) only
12
supports one CPU, and the realize function of the "fsl,imx25" device
13
also uses serial_hds[] directly, so this device clearly can not be
14
instantiated twice and thus we should mark it with user_creatable = 0.
15
16
Signed-off-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 1509519537-6964-3-git-send-email-thuth@redhat.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
8
---
21
hw/arm/fsl-imx25.c | 6 +++++-
9
linux-user/aarch64/target_syscall.h | 2 ++
22
1 file changed, 5 insertions(+), 1 deletion(-)
10
linux-user/aarch64/cpu_loop.c | 31 +++++++++++++++++++++++++++--
11
2 files changed, 31 insertions(+), 2 deletions(-)
23
12
24
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
13
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
25
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/fsl-imx25.c
15
--- a/linux-user/aarch64/target_syscall.h
27
+++ b/hw/arm/fsl-imx25.c
16
+++ b/linux-user/aarch64/target_syscall.h
28
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_class_init(ObjectClass *oc, void *data)
17
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
29
DeviceClass *dc = DEVICE_CLASS(oc);
18
#define TARGET_PR_SVE_SET_VL 50
30
19
#define TARGET_PR_SVE_GET_VL 51
31
dc->realize = fsl_imx25_realize;
20
32
-
21
+void arm_init_pauth_key(ARMPACKey *key);
33
dc->desc = "i.MX25 SOC";
22
+
34
+ /*
23
#endif /* AARCH64_TARGET_SYSCALL_H */
35
+ * Reason: uses serial_hds in realize and the imx25 board does not
24
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
36
+ * support multiple CPUs
25
index XXXXXXX..XXXXXXX 100644
37
+ */
26
--- a/linux-user/aarch64/cpu_loop.c
38
+ dc->user_creatable = false;
27
+++ b/linux-user/aarch64/cpu_loop.c
28
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
29
}
39
}
30
}
40
31
41
static const TypeInfo fsl_imx25_type_info = {
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. */
42
--
75
--
43
2.7.4
76
2.20.1
44
77
45
78
diff view generated by jsdifflib
New patch
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
1
2
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
New patch
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
1
2
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
New patch
1
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
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
New patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
1
2
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
1
From: Shanker Donthineni <shankerd@codeaurora.org>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
The commit cddafd8f353d ("hw/intc/arm_gicv3_its: Implement state save
3
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
4
/restore") breaks the backward compatibility with the older kernels
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
where vITS save/restore support is not available. The vmstate function
5
Acked-by: Thomas Huth <thuth@redhat.com>
6
vm_change_state_handler() should not be registered if the running kernel
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
doesn't support ITS save/restore feature. Otherwise VM instance will be
7
Message-id: 20190201023357.22596-4-stefanha@redhat.com
8
killed whenever vmstate callback function is invoked.
9
10
Observed a virtual machine shutdown with QEMU-2.10+linux-4.11 when testing
11
the reboot command "virsh reboot <domain> --mode acpi" instead of reboot.
12
13
KVM Error: 'KVM_SET_DEVICE_ATTR failed: Group 4 attr 0x00000000000001'
14
15
Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
16
Reviewed-by: Eric Auger <eric.auger@redhat.com>
17
Message-id: 1509712671-16299-1-git-send-email-shankerd@codeaurora.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
9
---
20
hw/intc/arm_gicv3_its_kvm.c | 4 ++--
10
tests/microbit-test.c | 108 ++++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 108 insertions(+)
22
12
23
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
13
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
24
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/arm_gicv3_its_kvm.c
15
--- a/tests/microbit-test.c
26
+++ b/hw/intc/arm_gicv3_its_kvm.c
16
+++ b/tests/microbit-test.c
27
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@
28
error_free(s->migration_blocker);
18
#include "hw/arm/nrf51.h"
29
return;
19
#include "hw/char/nrf51_uart.h"
30
}
20
#include "hw/gpio/nrf51_gpio.h"
31
+ } else {
21
+#include "hw/nvram/nrf51_nvm.h"
32
+ qemu_add_vm_change_state_handler(vm_change_state_handler, s);
22
#include "hw/timer/nrf51_timer.h"
33
}
23
#include "hw/i2c/microbit_i2c.h"
34
24
35
kvm_msi_use_devid = true;
25
@@ -XXX,XX +XXX,XX @@ static void test_microbit_i2c(void)
36
kvm_gsi_direct_mapping = false;
26
qtest_quit(qts);
37
kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
38
-
39
- qemu_add_vm_change_state_handler(vm_change_state_handler, s);
40
}
27
}
41
28
42
/**
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
43
--
146
--
44
2.7.4
147
2.20.1
45
148
46
149
diff view generated by jsdifflib