1
As promised, more Arm patches. The big thing in here is the
1
Hi; here's a target-arm pullreq for rc0; these are all bugfixes
2
MPS2-AN521 board model.
2
and similar minor stuff.
3
3
4
thanks
4
thanks
5
-- PMM
5
-- PMM
6
6
7
The following changes since commit cfe6c547690b06fbce54a6d0f7b05dd7f18e36ea:
7
The following changes since commit 0462a32b4f63b2448b4a196381138afd50719dc4:
8
8
9
Merge remote-tracking branch 'remotes/xanclic/tags/pull-block-2019-01-31' into staging (2019-01-31 19:26:09 +0000)
9
Merge tag 'for-upstream' of https://repo.or.cz/qemu/kevin into staging (2025-03-14 09:31:13 +0800)
10
10
11
are available in the Git repository at:
11
are available in the Git repository at:
12
12
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190201
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20250314-1
14
14
15
for you to fetch changes up to 7743b70ffe7a8ce168adce2cf50ad156b1fefb8c:
15
for you to fetch changes up to a019e15edfd62beae1e2f6adc0fa7415ba20b14c:
16
16
17
tests/microbit-test: Add tests for nRF51 NVMC (2019-02-01 15:32:17 +0000)
17
meson.build: Set RUST_BACKTRACE for all tests (2025-03-14 12:54:33 +0000)
18
18
19
----------------------------------------------------------------
19
----------------------------------------------------------------
20
target-arm queue:
20
target-arm queue:
21
* New machine mps2-an521 -- this is a model of the AN521 FPGA image for the MPS2 devboard
21
* Correctly handle corner cases of guest attempting an exception
22
* Fix various places where we failed to UNDEF invalid A64 instructions
22
return to AArch32 when target EL is AArch64 only
23
* Don't UNDEF a valid FCMLA on 32-bit inputs
23
* MAINTAINERS: Fix status for Arm boards I "maintain"
24
* Fix some bugs in the newly-added PAuth implementation
24
* tests/functional: Bump up arm_replay timeout
25
* microbit: Implement NVMC non-volatile memory controller
25
* Revert "hw/char/pl011: Warn when using disabled receiver"
26
* util/cacheflush: Make first DSB unconditional on aarch64
27
* target/arm: Fix SVE/SME access check logic
28
* meson.build: Set RUST_BACKTRACE for all tests
26
29
27
----------------------------------------------------------------
30
----------------------------------------------------------------
28
Aaron Lindsay OS (2):
31
Joe Komlodi (1):
29
target/arm: Send interrupts on PMU counter overflow
32
util/cacheflush: Make first DSB unconditional on aarch64
30
target/arm: Add a timer to predict PMU counter overflow
31
33
32
Julia Suvorova (1):
34
Paolo Bonzini (1):
33
arm: Clarify the logic of set_pc()
35
Revert "hw/char/pl011: Warn when using disabled receiver"
34
36
35
Peter Maydell (33):
37
Peter Maydell (13):
36
armv7m: Don't assume the NVIC's CPU is CPU 0
38
target/arm: Move A32_BANKED_REG_{GET,SET} macros to cpregs.h
37
armv7m: Make cpu object a child of the armv7m container
39
target/arm: Un-inline access_secure_reg()
38
armv7m: Pass through start-powered-off CPU property
40
linux-user/aarch64: Remove unused get/put_user macros
39
hw/arm/iotkit: Rename IoTKit to ARMSSE
41
linux-user/arm: Remove unused get_put_user macros
40
hw/arm/iotkit: Refactor into abstract base class and subclass
42
target/arm: Move arm_cpu_data_is_big_endian() etc to internals.h
41
hw/arm/iotkit: Rename 'iotkit' local variables and functions
43
target/arm: Move arm_current_el() and arm_el_is_aa64() to internals.h
42
hw/arm/iotkit: Rename files to hw/arm/armsse.[ch]
44
target/arm: SCR_EL3.RW should be treated as 1 if EL2 doesn't support AArch32
43
hw/misc/iotkit-secctl: Support 4 internal MPCs
45
target/arm: HCR_EL2.RW should be RAO/WI if EL1 doesn't support AArch32
44
hw/arm/armsse: Make number of SRAM banks parameterised
46
target/arm: Add cpu local variable to exception_return helper
45
hw/arm/armsse: Make SRAM bank size configurable
47
target/arm: Forbid return to AArch32 when CPU is AArch64-only
46
hw/arm/armsse: Support dual-CPU configuration
48
MAINTAINERS: Fix status for Arm boards I "maintain"
47
hw/arm/armsse: Give each CPU its own view of memory
49
tests/functional: Bump up arm_replay timeout
48
hw/arm/armsse: Put each CPU in its own cluster object
50
meson.build: Set RUST_BACKTRACE for all tests
49
iotkit-sysinfo: Make SYS_VERSION and SYS_CONFIG configurable
50
hw/arm/armsse: Add unimplemented-device stubs for MHUs
51
hw/arm/armsse: Add unimplemented-device stubs for PPUs
52
hw/arm/armsse: Add unimplemented-device stub for cache control registers
53
hw/arm/armsse: Add unimplemented-device stub for CPU local control registers
54
hw/misc/armsse-cpuid: Implement SSE-200 CPU_IDENTITY register block
55
hw/arm/armsse: Add CPU_IDENTITY block to SSE-200
56
hw/arm/armsse: Add SSE-200 model
57
hw/arm/mps2-tz: Add IRQ infrastructure to support SSE-200
58
hw/arm/mps2-tz: Add mps2-an521 model
59
target/arm/translate-a64: Don't underdecode system instructions
60
target/arm/translate-a64: Don't underdecode PRFM
61
target/arm/translate-a64: Don't underdecode SIMD ld/st multiple
62
target/arm/translate-a64: Don't underdecode SIMD ld/st single
63
target/arm/translate-a64: Don't underdecode add/sub extended register
64
target/arm/translate-a64: Don't underdecode FP insns
65
target/arm/translate-a64: Don't underdecode SDOT and UDOT
66
exec.c: Don't reallocate IOMMUNotifiers that are in use
67
target/arm/translate-a64: Fix FCMLA decoding error
68
target/arm/translate-a64: Fix mishandling of size in FCMLA decode
69
51
70
Remi Denis-Courmont (2):
52
Richard Henderson (2):
71
target/arm: fix AArch64 virtual address space size
53
target/arm: Make DisasContext.{fp, sve}_access_checked tristate
72
target/arm: fix decoding of B{,L}RA{A,B}
54
target/arm: Simplify pstate_sm check in sve_access_check
73
55
74
Richard Henderson (5):
56
MAINTAINERS | 14 ++--
75
target/arm: Enable API, APK bits in SCR, HCR
57
meson.build | 9 ++-
76
target/arm: Always enable pac keys for user-only
58
target/arm/cpregs.h | 28 +++++++
77
aarch64-linux-user: Update HWCAP bits from linux 5.0-rc1
59
target/arm/cpu.h | 153 +-----------------------------------
78
aarch64-linux-user: Enable HWCAP bits for PAuth
60
target/arm/internals.h | 135 +++++++++++++++++++++++++++++++
79
linux-user: Initialize aarch64 pac keys
61
target/arm/tcg/translate-a64.h | 2 +-
80
62
target/arm/tcg/translate.h | 10 ++-
81
Steffen Görtz (3):
63
hw/char/pl011.c | 19 ++---
82
hw/nvram/nrf51_nvm: Add nRF51 non-volatile memories
64
hw/intc/arm_gicv3_cpuif.c | 1 +
83
arm: Instantiate NRF51 special NVM's and NVMC
65
linux-user/aarch64/cpu_loop.c | 48 -----------
84
tests/microbit-test: Add tests for nRF51 NVMC
66
linux-user/arm/cpu_loop.c | 43 +---------
85
67
target/arm/arch_dump.c | 1 +
86
kumar sourav (1):
68
target/arm/helper.c | 16 +++-
87
hw/arm/nrf51_soc: set object owner in memory_region_init_ram
69
target/arm/tcg/helper-a64.c | 12 ++-
88
70
target/arm/tcg/hflags.c | 9 +++
89
hw/arm/Makefile.objs | 2 +-
71
target/arm/tcg/translate-a64.c | 37 ++++-----
90
hw/misc/Makefile.objs | 1 +
72
util/cacheflush.c | 4 +-
91
hw/nvram/Makefile.objs | 1 +
73
.gitlab-ci.d/buildtest-template.yml | 1 -
92
include/hw/arm/{iotkit.h => armsse.h} | 113 ++-
74
18 files changed, 257 insertions(+), 285 deletions(-)
93
include/hw/arm/armv7m.h | 1 +
94
include/hw/arm/nrf51_soc.h | 2 +
95
include/hw/misc/armsse-cpuid.h | 41 ++
96
include/hw/misc/iotkit-secctl.h | 6 +-
97
include/hw/misc/iotkit-sysinfo.h | 6 +
98
include/hw/nvram/nrf51_nvm.h | 64 ++
99
include/qom/cpu.h | 16 +-
100
linux-user/aarch64/target_syscall.h | 2 +
101
target/arm/cpu.h | 12 +-
102
exec.c | 10 +-
103
hw/arm/armsse.c | 1241 +++++++++++++++++++++++++++++++++
104
hw/arm/armv7m.c | 23 +-
105
hw/arm/boot.c | 4 -
106
hw/arm/iotkit.c | 759 --------------------
107
hw/arm/mps2-tz.c | 121 +++-
108
hw/arm/nrf51_soc.c | 44 +-
109
hw/intc/armv7m_nvic.c | 3 +-
110
hw/misc/armsse-cpuid.c | 134 ++++
111
hw/misc/iotkit-secctl.c | 5 +-
112
hw/misc/iotkit-sysinfo.c | 15 +-
113
hw/nvram/nrf51_nvm.c | 388 +++++++++++
114
linux-user/aarch64/cpu_loop.c | 31 +-
115
linux-user/elfload.c | 10 +
116
target/arm/arm-powerctl.c | 3 -
117
target/arm/cpu.c | 41 +-
118
target/arm/cpu64.c | 75 --
119
target/arm/helper.c | 139 +++-
120
target/arm/translate-a64.c | 59 +-
121
tests/microbit-test.c | 108 +++
122
MAINTAINERS | 6 +-
123
default-configs/arm-softmmu.mak | 3 +-
124
hw/misc/trace-events | 4 +
125
36 files changed, 2552 insertions(+), 941 deletions(-)
126
rename include/hw/arm/{iotkit.h => armsse.h} (53%)
127
create mode 100644 include/hw/misc/armsse-cpuid.h
128
create mode 100644 include/hw/nvram/nrf51_nvm.h
129
create mode 100644 hw/arm/armsse.c
130
delete mode 100644 hw/arm/iotkit.c
131
create mode 100644 hw/misc/armsse-cpuid.c
132
create mode 100644 hw/nvram/nrf51_nvm.c
133
diff view generated by jsdifflib
Deleted patch
1
From: kumar sourav <sourav.jb1988@gmail.com>
2
1
3
set object owner in memory_region_init_ram() instead
4
of NULL.
5
6
Signed-off-by: kumar sourav <sourav.jb1988@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190125155630.17430-1-sourav.jb1988@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/nrf51_soc.c | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/nrf51_soc.c
18
+++ b/hw/arm/nrf51_soc.c
19
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
20
}
21
memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
22
23
- memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
24
+ memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
25
+ &err);
26
if (err) {
27
error_propagate(errp, err);
28
return;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
Currently the ARMv7M NVIC object's realize method assumes that the
2
CPU the NVIC is attached to is CPU 0, because it thinks there can
3
only ever be one CPU in the system. To allow a dual-Cortex-M33
4
setup we need to remove this assumption; instead the armv7m
5
wrapper object tells the NVIC its CPU, in the same way that it
6
already tells the CPU what the NVIC is.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190121185118.18550-2-peter.maydell@linaro.org
12
---
13
hw/arm/armv7m.c | 6 ++++--
14
hw/intc/armv7m_nvic.c | 3 +--
15
2 files changed, 5 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/armv7m.c
20
+++ b/hw/arm/armv7m.c
21
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
22
}
23
}
24
25
- /* Tell the CPU where the NVIC is; it will fail realize if it doesn't
26
- * have one.
27
+ /*
28
+ * Tell the CPU where the NVIC is; it will fail realize if it doesn't
29
+ * have one. Similarly, tell the NVIC where its CPU is.
30
*/
31
s->cpu->env.nvic = &s->nvic;
32
+ s->nvic.cpu = s->cpu;
33
34
object_property_set_bool(OBJECT(s->cpu), true, "realized", &err);
35
if (err != NULL) {
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/armv7m_nvic.c
39
+++ b/hw/intc/armv7m_nvic.c
40
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
41
Error *err = NULL;
42
int regionlen;
43
44
- s->cpu = ARM_CPU(qemu_get_cpu(0));
45
-
46
+ /* The armv7m container object will have set our CPU pointer */
47
if (!s->cpu || !arm_feature(&s->cpu->env, ARM_FEATURE_M)) {
48
error_setg(errp, "The NVIC can only be used with a Cortex-M CPU");
49
return;
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
Rather than just creating the CPUs with object_new, make them child
2
objects of the armv7m container. This will allow the cluster code to
3
find the CPUs if an armv7m object is made a child of a cluster object.
4
object_new_with_props() will do the parenting for us.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190121185118.18550-3-peter.maydell@linaro.org
10
---
11
hw/arm/armv7m.c | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/armv7m.c
17
+++ b/hw/arm/armv7m.c
18
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
19
20
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
21
22
- s->cpu = ARM_CPU(object_new(s->cpu_type));
23
+ s->cpu = ARM_CPU(object_new_with_props(s->cpu_type, OBJECT(s), "cpu",
24
+ &err, NULL));
25
+ if (err != NULL) {
26
+ error_propagate(errp, err);
27
+ return;
28
+ }
29
30
object_property_set_link(OBJECT(s->cpu), OBJECT(&s->container), "memory",
31
&error_abort);
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
Expose "start-powered-off" as a property of the ARMv7M container,
2
which we just pass through to the CPU object in the same way that we
3
do for "init-svtor" and "idau". (We want this for the SSE-200, which
4
powers up only the first CPU at reset and leaves the second powered
5
down.)
6
1
7
As with the other CPU properties here, we can't just use alias
8
properties, because the CPU QOM object is not created until armv7m
9
realize time.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-4-peter.maydell@linaro.org
14
---
15
include/hw/arm/armv7m.h | 1 +
16
hw/arm/armv7m.c | 10 ++++++++++
17
2 files changed, 11 insertions(+)
18
19
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/armv7m.h
22
+++ b/include/hw/arm/armv7m.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
24
Object *idau;
25
uint32_t init_svtor;
26
bool enable_bitband;
27
+ bool start_powered_off;
28
} ARMv7MState;
29
30
#endif
31
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/armv7m.c
34
+++ b/hw/arm/armv7m.c
35
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
36
return;
37
}
38
}
39
+ if (object_property_find(OBJECT(s->cpu), "start-powered-off", NULL)) {
40
+ object_property_set_bool(OBJECT(s->cpu), s->start_powered_off,
41
+ "start-powered-off", &err);
42
+ if (err != NULL) {
43
+ error_propagate(errp, err);
44
+ return;
45
+ }
46
+ }
47
48
/*
49
* Tell the CPU where the NVIC is; it will fail realize if it doesn't
50
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
51
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
52
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
53
DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
54
+ DEFINE_PROP_BOOL("start-powered-off", ARMv7MState, start_powered_off,
55
+ false),
56
DEFINE_PROP_END_OF_LIST(),
57
};
58
59
--
60
2.20.1
61
62
diff view generated by jsdifflib
Deleted patch
1
The Arm IoTKit was effectively the forerunner of a series of
2
subsystems for embedded SoCs, named the SSE-050, SSE-100 and SSE-200:
3
https://developer.arm.com/products/system-design/subsystems
4
These are generally quite similar, though later iterations have
5
extra devices that earlier ones do not.
6
1
7
We want to add a model of the SSE-200, which means refactoring the
8
IoTKit code into an abstract base class and subclasses (using the
9
same design that the bcm283x SoC and Aspeed SoC family
10
implementations do). As a first step, rename the IoTKit struct and
11
QOM macros to ARMSSE, which is what we're going to name the base
12
class. We temporarily retain TYPE_IOTKIT to avoid changing the
13
code that instantiates a TYPE_IOTKIT device here and then changing
14
it back again when it is re-introduced as a subclass.
15
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190121185118.18550-5-peter.maydell@linaro.org
20
---
21
include/hw/arm/iotkit.h | 22 ++++++++++-----
22
hw/arm/iotkit.c | 59 +++++++++++++++++++++--------------------
23
hw/arm/mps2-tz.c | 2 +-
24
3 files changed, 47 insertions(+), 36 deletions(-)
25
26
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/arm/iotkit.h
29
+++ b/include/hw/arm/iotkit.h
30
@@ -XXX,XX +XXX,XX @@
31
/*
32
- * ARM IoT Kit
33
+ * ARM SSE (Subsystems for Embedded): IoTKit
34
*
35
* Copyright (c) 2018 Linaro Limited
36
* Written by Peter Maydell
37
@@ -XXX,XX +XXX,XX @@
38
* (at your option) any later version.
39
*/
40
41
-/* This is a model of the Arm IoT Kit which is documented in
42
+/*
43
+ * This is a model of the Arm "Subsystems for Embedded" family of
44
+ * hardware, which include the IoT Kit and the SSE-050, SSE-100 and
45
+ * SSE-200. Currently we model only the Arm IoT Kit which is documented in
46
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
47
* It contains:
48
* a Cortex-M33
49
@@ -XXX,XX +XXX,XX @@
50
#include "hw/or-irq.h"
51
#include "hw/core/split-irq.h"
52
53
-#define TYPE_IOTKIT "iotkit"
54
-#define IOTKIT(obj) OBJECT_CHECK(IoTKit, (obj), TYPE_IOTKIT)
55
+#define TYPE_ARMSSE "iotkit"
56
+#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
57
+
58
+/*
59
+ * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
60
+ * latter's underlying name is left as "iotkit"); in a later
61
+ * commit it will become a subclass of TYPE_ARMSSE.
62
+ */
63
+#define TYPE_IOTKIT TYPE_ARMSSE
64
65
/* We have an IRQ splitter and an OR gate input for each external PPC
66
* and the 2 internal PPCs
67
@@ -XXX,XX +XXX,XX @@
68
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
69
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
70
71
-typedef struct IoTKit {
72
+typedef struct ARMSSE {
73
/*< private >*/
74
SysBusDevice parent_obj;
75
76
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKit {
77
MemoryRegion *board_memory;
78
uint32_t exp_numirq;
79
uint32_t mainclk_frq;
80
-} IoTKit;
81
+} ARMSSE;
82
83
#endif
84
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/iotkit.c
87
+++ b/hw/arm/iotkit.c
88
@@ -XXX,XX +XXX,XX @@
89
/*
90
- * Arm IoT Kit
91
+ * Arm SSE (Subsystems for Embedded): IoTKit
92
*
93
* Copyright (c) 2018 Linaro Limited
94
* Written by Peter Maydell
95
@@ -XXX,XX +XXX,XX @@
96
/* Create an alias region of @size bytes starting at @base
97
* which mirrors the memory starting at @orig.
98
*/
99
-static void make_alias(IoTKit *s, MemoryRegion *mr, const char *name,
100
+static void make_alias(ARMSSE *s, MemoryRegion *mr, const char *name,
101
hwaddr base, hwaddr size, hwaddr orig)
102
{
103
memory_region_init_alias(mr, NULL, name, &s->container, orig, size);
104
@@ -XXX,XX +XXX,XX @@ static void irq_status_forwarder(void *opaque, int n, int level)
105
106
static void nsccfg_handler(void *opaque, int n, int level)
107
{
108
- IoTKit *s = IOTKIT(opaque);
109
+ ARMSSE *s = ARMSSE(opaque);
110
111
s->nsccfg = level;
112
}
113
114
-static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
115
+static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
116
{
117
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
118
- * system using the IoTKit has a collection of control lines which
119
+ * system using the ARMSSE has a collection of control lines which
120
* are provided by the security controller and which we want to
121
- * expose as control lines on the IoTKit device itself, so the
122
- * code using the IoTKit can wire them up to the PPCs.
123
+ * expose as control lines on the ARMSSE device itself, so the
124
+ * code using the ARMSSE can wire them up to the PPCs.
125
*/
126
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
127
DeviceState *iotkitdev = DEVICE(s);
128
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(IoTKit *s, const char *ppcname, int ppcnum)
129
g_free(name);
130
}
131
132
-static void iotkit_forward_sec_resp_cfg(IoTKit *s)
133
+static void iotkit_forward_sec_resp_cfg(ARMSSE *s)
134
{
135
/* Forward the 3rd output from the splitter device as a
136
* named GPIO output of the iotkit object.
137
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_sec_resp_cfg(IoTKit *s)
138
139
static void iotkit_init(Object *obj)
140
{
141
- IoTKit *s = IOTKIT(obj);
142
+ ARMSSE *s = ARMSSE(obj);
143
int i;
144
145
memory_region_init(&s->container, obj, "iotkit-container", UINT64_MAX);
146
@@ -XXX,XX +XXX,XX @@ static void iotkit_init(Object *obj)
147
148
static void iotkit_exp_irq(void *opaque, int n, int level)
149
{
150
- IoTKit *s = IOTKIT(opaque);
151
+ ARMSSE *s = ARMSSE(opaque);
152
153
qemu_set_irq(s->exp_irqs[n], level);
154
}
155
156
static void iotkit_mpcexp_status(void *opaque, int n, int level)
157
{
158
- IoTKit *s = IOTKIT(opaque);
159
+ ARMSSE *s = ARMSSE(opaque);
160
qemu_set_irq(s->mpcexp_status_in[n], level);
161
}
162
163
static void iotkit_realize(DeviceState *dev, Error **errp)
164
{
165
- IoTKit *s = IOTKIT(dev);
166
+ ARMSSE *s = ARMSSE(dev);
167
int i;
168
MemoryRegion *mr;
169
Error *err = NULL;
170
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
171
* devices exist in both address spaces but with hard-wired security
172
* permissions that will cause the CPU to fault for non-secure accesses.
173
*
174
- * The IoTKit has an IDAU (Implementation Defined Access Unit),
175
+ * The ARMSSE has an IDAU (Implementation Defined Access Unit),
176
* which specifies hard-wired security permissions for different
177
- * areas of the physical address space. For the IoTKit IDAU, the
178
+ * areas of the physical address space. For the ARMSSE IDAU, the
179
* top 4 bits of the physical address are the IDAU region ID, and
180
* if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
181
* region, otherwise it is an S region.
182
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
183
* 0x20000000..0x2007ffff 32KB FPGA block RAM
184
* 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
185
* 0x40000000..0x4000ffff base peripheral region 1
186
- * 0x40010000..0x4001ffff CPU peripherals (none for IoTKit)
187
+ * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
188
* 0x40020000..0x4002ffff system control element peripherals
189
* 0x40080000..0x400fffff base peripheral region 2
190
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
191
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
192
qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
193
194
/* The sec_resp_cfg output from the security controller must be split into
195
- * multiple lines, one for each of the PPCs within the IoTKit and one
196
- * that will be an output from the IoTKit to the system.
197
+ * multiple lines, one for each of the PPCs within the ARMSSE and one
198
+ * that will be an output from the ARMSSE to the system.
199
*/
200
object_property_set_int(OBJECT(&s->sec_resp_splitter), 3,
201
"num-lines", &err);
202
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
203
204
/* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
205
206
- /* 0x40020000 .. 0x4002ffff : IoTKit system control peripheral region */
207
+ /* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
208
/* Devices behind APB PPC1:
209
* 0x4002f000: S32K timer
210
*/
211
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
212
qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0));
213
sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000);
214
215
- /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */
216
+ /* 0x40080000 .. 0x4008ffff : ARMSSE second Base peripheral region */
217
218
qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq);
219
object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err);
220
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
221
* Expose our container region to the board model; this corresponds
222
* to the AHB Slave Expansion ports which allow bus master devices
223
* (eg DMA controllers) in the board model to make transactions into
224
- * devices in the IoTKit.
225
+ * devices in the ARMSSE.
226
*/
227
sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
228
229
@@ -XXX,XX +XXX,XX @@ static void iotkit_realize(DeviceState *dev, Error **errp)
230
static void iotkit_idau_check(IDAUInterface *ii, uint32_t address,
231
int *iregion, bool *exempt, bool *ns, bool *nsc)
232
{
233
- /* For IoTKit systems the IDAU responses are simple logical functions
234
+ /*
235
+ * For ARMSSE systems the IDAU responses are simple logical functions
236
* of the address bits. The NSC attribute is guest-adjustable via the
237
* NSCCFG register in the security controller.
238
*/
239
- IoTKit *s = IOTKIT(ii);
240
+ ARMSSE *s = ARMSSE(ii);
241
int region = extract32(address, 28, 4);
242
243
*ns = !(region & 1);
244
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription iotkit_vmstate = {
245
.version_id = 1,
246
.minimum_version_id = 1,
247
.fields = (VMStateField[]) {
248
- VMSTATE_UINT32(nsccfg, IoTKit),
249
+ VMSTATE_UINT32(nsccfg, ARMSSE),
250
VMSTATE_END_OF_LIST()
251
}
252
};
253
254
static Property iotkit_properties[] = {
255
- DEFINE_PROP_LINK("memory", IoTKit, board_memory, TYPE_MEMORY_REGION,
256
+ DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
257
MemoryRegion *),
258
- DEFINE_PROP_UINT32("EXP_NUMIRQ", IoTKit, exp_numirq, 64),
259
- DEFINE_PROP_UINT32("MAINCLK", IoTKit, mainclk_frq, 0),
260
+ DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
261
+ DEFINE_PROP_UINT32("MAINCLK", ARMSSE, mainclk_frq, 0),
262
DEFINE_PROP_END_OF_LIST()
263
};
264
265
static void iotkit_reset(DeviceState *dev)
266
{
267
- IoTKit *s = IOTKIT(dev);
268
+ ARMSSE *s = ARMSSE(dev);
269
270
s->nsccfg = 0;
271
}
272
@@ -XXX,XX +XXX,XX @@ static void iotkit_class_init(ObjectClass *klass, void *data)
273
}
274
275
static const TypeInfo iotkit_info = {
276
- .name = TYPE_IOTKIT,
277
+ .name = TYPE_ARMSSE,
278
.parent = TYPE_SYS_BUS_DEVICE,
279
- .instance_size = sizeof(IoTKit),
280
+ .instance_size = sizeof(ARMSSE),
281
.instance_init = iotkit_init,
282
.class_init = iotkit_class_init,
283
.interfaces = (InterfaceInfo[]) {
284
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
285
index XXXXXXX..XXXXXXX 100644
286
--- a/hw/arm/mps2-tz.c
287
+++ b/hw/arm/mps2-tz.c
288
@@ -XXX,XX +XXX,XX @@ typedef struct {
289
typedef struct {
290
MachineState parent;
291
292
- IoTKit iotkit;
293
+ ARMSSE iotkit;
294
MemoryRegion psram;
295
MemoryRegion ssram[3];
296
MemoryRegion ssram1_m;
297
--
298
2.20.1
299
300
diff view generated by jsdifflib
1
The SSE-200 has 4 banks of SRAM, each with its own internal
1
The A32_BANKED_REG_{GET,SET} macros are only used inside target/arm;
2
Memory Protection Controller. The interrupt status for these
2
move their definitions to cpregs.h. There's no need to have them
3
extra MPCs appears in the same security controller SECMPCINTSTATUS
3
defined in all the code that includes cpu.h.
4
register as the MPC for the IoTKit's single SRAM bank. Enhance the
5
iotkit-secctl device to allow 4 MPCs. (If the particular IoTKit/SSE
6
variant in use does not have all 4 MPCs then the unused inputs will
7
simply result in the SECMPCINTSTATUS bits being zero as required.)
8
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
4
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190121185118.18550-9-peter.maydell@linaro.org
16
---
7
---
17
include/hw/misc/iotkit-secctl.h | 6 +++---
8
target/arm/cpregs.h | 28 ++++++++++++++++++++++++++++
18
hw/arm/armsse.c | 6 +++---
9
target/arm/cpu.h | 27 ---------------------------
19
hw/misc/iotkit-secctl.c | 5 +++--
10
2 files changed, 28 insertions(+), 27 deletions(-)
20
3 files changed, 9 insertions(+), 8 deletions(-)
21
11
22
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
12
diff --git a/target/arm/cpregs.h b/target/arm/cpregs.h
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/misc/iotkit-secctl.h
14
--- a/target/arm/cpregs.h
25
+++ b/include/hw/misc/iotkit-secctl.h
15
+++ b/target/arm/cpregs.h
26
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpreg_traps_in_nv(const ARMCPRegInfo *ri)
27
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
17
return ri->opc1 == 4 || ri->opc1 == 5;
28
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
18
}
29
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
19
30
- * Controlling the MPC in the IoTKit:
20
+/* Macros for accessing a specified CP register bank */
31
- * + named GPIO input mpc_status
21
+#define A32_BANKED_REG_GET(_env, _regname, _secure) \
32
+ * Controlling the (up to) 4 MPCs in the IoTKit/SSE:
22
+ ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
33
+ * + named GPIO inputs mpc_status[0..3]
23
+
34
* Controlling each of the 16 expansion MPCs which a system using the IoTKit
24
+#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \
35
* might provide:
25
+ do { \
36
* + named GPIO inputs mpcexp_status[0..15]
26
+ if (_secure) { \
37
@@ -XXX,XX +XXX,XX @@
27
+ (_env)->cp15._regname##_s = (_val); \
38
#define IOTS_NUM_APB_EXP_PPC 4
28
+ } else { \
39
#define IOTS_NUM_AHB_EXP_PPC 4
29
+ (_env)->cp15._regname##_ns = (_val); \
40
#define IOTS_NUM_EXP_MPC 16
30
+ } \
41
-#define IOTS_NUM_MPC 1
31
+ } while (0)
42
+#define IOTS_NUM_MPC 4
32
+
43
#define IOTS_NUM_EXP_MSC 16
33
+/*
44
34
+ * Macros for automatically accessing a specific CP register bank depending on
45
typedef struct IoTKitSecCtl IoTKitSecCtl;
35
+ * the current secure state of the system. These macros are not intended for
46
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
36
+ * supporting instruction translation reads/writes as these are dependent
37
+ * solely on the SCR.NS bit and not the mode.
38
+ */
39
+#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \
40
+ A32_BANKED_REG_GET((_env), _regname, \
41
+ (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)))
42
+
43
+#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \
44
+ A32_BANKED_REG_SET((_env), _regname, \
45
+ (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \
46
+ (_val))
47
+
48
#endif /* TARGET_ARM_CPREGS_H */
49
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
47
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/armsse.c
51
--- a/target/arm/cpu.h
49
+++ b/hw/arm/armsse.c
52
+++ b/target/arm/cpu.h
50
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
53
@@ -XXX,XX +XXX,XX @@ static inline bool access_secure_reg(CPUARMState *env)
51
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
54
return ret;
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
}
55
}
88
56
89
static void iotkit_secctl_mpcexp_status(void *opaque, int n, int level)
57
-/* Macros for accessing a specified CP register bank */
90
@@ -XXX,XX +XXX,XX @@ static void iotkit_secctl_init(Object *obj)
58
-#define A32_BANKED_REG_GET(_env, _regname, _secure) \
91
qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
59
- ((_secure) ? (_env)->cp15._regname##_s : (_env)->cp15._regname##_ns)
92
qdev_init_gpio_out_named(dev, &s->nsc_cfg_irq, "nsc_cfg", 1);
60
-
93
61
-#define A32_BANKED_REG_SET(_env, _regname, _secure, _val) \
94
- qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status", 1);
62
- do { \
95
+ qdev_init_gpio_in_named(dev, iotkit_secctl_mpc_status, "mpc_status",
63
- if (_secure) { \
96
+ IOTS_NUM_MPC);
64
- (_env)->cp15._regname##_s = (_val); \
97
qdev_init_gpio_in_named(dev, iotkit_secctl_mpcexp_status,
65
- } else { \
98
"mpcexp_status", IOTS_NUM_EXP_MPC);
66
- (_env)->cp15._regname##_ns = (_val); \
67
- } \
68
- } while (0)
69
-
70
-/* Macros for automatically accessing a specific CP register bank depending on
71
- * the current secure state of the system. These macros are not intended for
72
- * supporting instruction translation reads/writes as these are dependent
73
- * solely on the SCR.NS bit and not the mode.
74
- */
75
-#define A32_BANKED_CURRENT_REG_GET(_env, _regname) \
76
- A32_BANKED_REG_GET((_env), _regname, \
77
- (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)))
78
-
79
-#define A32_BANKED_CURRENT_REG_SET(_env, _regname, _val) \
80
- A32_BANKED_REG_SET((_env), _regname, \
81
- (arm_is_secure(_env) && !arm_el_is_aa64((_env), 3)), \
82
- (_val))
83
-
84
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
85
uint32_t cur_el, bool secure);
99
86
100
--
87
--
101
2.20.1
88
2.43.0
102
103
diff view generated by jsdifflib
1
Add a model of the MPS2 FPGA image described in Application Note
1
We would like to move arm_el_is_aa64() to internals.h; however, it is
2
AN521. This is identical to the AN505 image, except that it uses
2
used by access_secure_reg(). Make that function not be inline, so
3
the SSE-200 rather than the IoTKit and so has two Cortex-M33 CPUs.
3
that it can stay in cpu.h.
4
5
access_secure_reg() is used only in two places:
6
* in hflags.c
7
* in the user-mode arm emulators, to decide whether to store
8
the TLS value in the secure or non-secure banked field
9
10
The second of these is not on a super-hot path that would care about
11
the inlining (and incidentally will always use the NS banked field
12
because our user-mode CPUs never set ARM_FEATURE_EL3); put the
13
definition of access_secure_reg() in hflags.c, near its only use
14
inside target/arm.
4
15
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-24-peter.maydell@linaro.org
8
---
18
---
9
hw/arm/mps2-tz.c | 38 ++++++++++++++++++++++++++++++++++++--
19
target/arm/cpu.h | 12 +++---------
10
1 file changed, 36 insertions(+), 2 deletions(-)
20
target/arm/tcg/hflags.c | 9 +++++++++
21
2 files changed, 12 insertions(+), 9 deletions(-)
11
22
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
25
--- a/target/arm/cpu.h
15
+++ b/hw/arm/mps2-tz.c
26
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
17
* as seen by the guest depend significantly on the FPGA image.
28
return aa64;
18
* This source file covers the following FPGA images, for TrustZone cores:
29
}
19
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
30
20
+ * "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
31
-/* Function for determining whether guest cp register reads and writes should
21
*
32
+/*
22
* Links to the TRM for the board itself and to the various Application
33
+ * Function for determining whether guest cp register reads and writes should
23
* Notes which document the FPGA images can be found here:
34
* access the secure or non-secure bank of a cp register. When EL3 is
24
@@ -XXX,XX +XXX,XX @@
35
* operating in AArch32 state, the NS-bit determines whether the secure
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
36
* instance of a cp register should be used. When EL3 is AArch64 (or if
26
* Application Note AN505:
37
* it doesn't exist at all) then there is no register banking, and all
27
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
38
* accesses are to the non-secure version.
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
*/
39
40
-static inline bool access_secure_reg(CPUARMState *env)
40
#include "qemu/osdep.h"
41
-{
41
@@ -XXX,XX +XXX,XX @@ typedef struct {
42
- bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
42
MachineClass parent;
43
- !arm_el_is_aa64(env, 3) &&
43
MPS2TZFPGAType fpga_type;
44
- !(env->cp15.scr_el3 & SCR_NS));
44
uint32_t scc_id;
45
-
45
+ const char *armsse_type;
46
- return ret;
46
} MPS2TZMachineClass;
47
-}
47
48
+bool access_secure_reg(CPUARMState *env);
48
typedef struct {
49
49
@@ -XXX,XX +XXX,XX @@ typedef struct {
50
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
50
51
uint32_t cur_el, bool secure);
51
#define TYPE_MPS2TZ_MACHINE "mps2tz"
52
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
52
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
53
index XXXXXXX..XXXXXXX 100644
53
+#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
54
--- a/target/arm/tcg/hflags.c
54
55
+++ b/target/arm/tcg/hflags.c
55
#define MPS2TZ_MACHINE(obj) \
56
@@ -XXX,XX +XXX,XX @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
56
OBJECT_CHECK(MPS2TZMachineState, obj, TYPE_MPS2TZ_MACHINE)
57
#endif
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
}
58
}
73
59
74
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
60
+bool access_secure_reg(CPUARMState *env)
75
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
61
+{
76
62
+ bool ret = (arm_feature(env, ARM_FEATURE_EL3) &&
77
mc->desc = "ARM MPS2 with AN505 FPGA image for Cortex-M33";
63
+ !arm_el_is_aa64(env, 3) &&
78
+ mc->default_cpus = 1;
64
+ !(env->cp15.scr_el3 & SCR_NS));
79
+ mc->min_cpus = mc->default_cpus;
65
+
80
+ mc->max_cpus = mc->default_cpus;
66
+ return ret;
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
+}
67
+}
86
+
68
+
87
+static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
69
static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
88
+{
70
ARMMMUIdx mmu_idx,
89
+ MachineClass *mc = MACHINE_CLASS(oc);
71
CPUARMTBFlags flags)
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
--
72
--
122
2.20.1
73
2.43.0
123
124
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
At the top of linux-user/aarch64/cpu_loop.c we define a set of
2
macros for reading and writing data and code words, but we never
3
use these macros. Delete them.
2
4
3
Initialize the keys to a non-zero value on process start.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
linux-user/aarch64/cpu_loop.c | 48 -----------------------------------
9
1 file changed, 48 deletions(-)
4
10
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
linux-user/aarch64/target_syscall.h | 2 ++
10
linux-user/aarch64/cpu_loop.c | 31 +++++++++++++++++++++++++++--
11
2 files changed, 31 insertions(+), 2 deletions(-)
12
13
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/linux-user/aarch64/target_syscall.h
16
+++ b/linux-user/aarch64/target_syscall.h
17
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
18
#define TARGET_PR_SVE_SET_VL 50
19
#define TARGET_PR_SVE_GET_VL 51
20
21
+void arm_init_pauth_key(ARMPACKey *key);
22
+
23
#endif /* AARCH64_TARGET_SYSCALL_H */
24
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
11
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
25
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
26
--- a/linux-user/aarch64/cpu_loop.c
13
--- a/linux-user/aarch64/cpu_loop.c
27
+++ b/linux-user/aarch64/cpu_loop.c
14
+++ b/linux-user/aarch64/cpu_loop.c
28
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
15
@@ -XXX,XX +XXX,XX @@
29
}
16
#include "target/arm/syndrome.h"
30
}
17
#include "target/arm/cpu-features.h"
31
18
32
+static uint64_t arm_rand64(void)
19
-#define get_user_code_u32(x, gaddr, env) \
33
+{
20
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
34
+ int shift = 64 - clz64(RAND_MAX);
21
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
35
+ int i, n = 64 / shift + (64 % shift != 0);
22
- (x) = bswap32(x); \
36
+ uint64_t ret = 0;
23
- } \
37
+
24
- __r; \
38
+ for (i = 0; i < n; i++) {
25
- })
39
+ ret = (ret << shift) | rand();
26
-
40
+ }
27
-#define get_user_code_u16(x, gaddr, env) \
41
+ return ret;
28
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
42
+}
29
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
43
+
30
- (x) = bswap16(x); \
44
+void arm_init_pauth_key(ARMPACKey *key)
31
- } \
45
+{
32
- __r; \
46
+ key->lo = arm_rand64();
33
- })
47
+ key->hi = arm_rand64();
34
-
48
+}
35
-#define get_user_data_u32(x, gaddr, env) \
49
+
36
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
50
void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
37
- if (!__r && arm_cpu_bswap_data(env)) { \
38
- (x) = bswap32(x); \
39
- } \
40
- __r; \
41
- })
42
-
43
-#define get_user_data_u16(x, gaddr, env) \
44
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
45
- if (!__r && arm_cpu_bswap_data(env)) { \
46
- (x) = bswap16(x); \
47
- } \
48
- __r; \
49
- })
50
-
51
-#define put_user_data_u32(x, gaddr, env) \
52
- ({ typeof(x) __x = (x); \
53
- if (arm_cpu_bswap_data(env)) { \
54
- __x = bswap32(__x); \
55
- } \
56
- put_user_u32(__x, (gaddr)); \
57
- })
58
-
59
-#define put_user_data_u16(x, gaddr, env) \
60
- ({ typeof(x) __x = (x); \
61
- if (arm_cpu_bswap_data(env)) { \
62
- __x = bswap16(__x); \
63
- } \
64
- put_user_u16(__x, (gaddr)); \
65
- })
66
-
67
/* AArch64 main loop */
68
void cpu_loop(CPUARMState *env)
51
{
69
{
52
- CPUState *cpu = ENV_GET_CPU(env);
53
- TaskState *ts = cpu->opaque;
54
+ ARMCPU *cpu = arm_env_get_cpu(env);
55
+ CPUState *cs = CPU(cpu);
56
+ TaskState *ts = cs->opaque;
57
struct image_info *info = ts->info;
58
int i;
59
60
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
61
}
62
#endif
63
64
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
65
+ arm_init_pauth_key(&env->apia_key);
66
+ arm_init_pauth_key(&env->apib_key);
67
+ arm_init_pauth_key(&env->apda_key);
68
+ arm_init_pauth_key(&env->apdb_key);
69
+ arm_init_pauth_key(&env->apga_key);
70
+ }
71
+
72
ts->stack_base = info->start_stack;
73
ts->heap_base = info->brk;
74
/* This will be filled in on the first SYS_HEAPINFO call. */
75
--
70
--
76
2.20.1
71
2.43.0
77
78
diff view generated by jsdifflib
1
The Arm SSE-200 Subsystem for Embedded is a revised and
1
In linux-user/arm/cpu_loop.c we define a full set of get/put
2
extended version of the older IoTKit SoC. Prepare for
2
macros for both code and data (since the endianness handling
3
adding a model of it by refactoring the IoTKit code into
3
is different between the two). However the only one we actually
4
an abstract base class which contains the functionality,
4
use is get_user_code_u32(). Remove the rest.
5
driven by a class data block specific to each subclass.
5
6
(This is the same approach used by the existing bcm283x
6
We leave a comment noting how data-side accesses should be handled
7
SoC family implementation.)
7
for big-endian, because that's a subtle point and we just removed the
8
macros that were effectively documenting it.
8
9
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
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>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190121185118.18550-6-peter.maydell@linaro.org
13
---
12
---
14
include/hw/arm/iotkit.h | 22 +++++++++++++++++-----
13
linux-user/arm/cpu_loop.c | 43 ++++-----------------------------------
15
hw/arm/iotkit.c | 34 +++++++++++++++++++++++++++++-----
14
1 file changed, 4 insertions(+), 39 deletions(-)
16
2 files changed, 46 insertions(+), 10 deletions(-)
17
15
18
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
16
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/iotkit.h
18
--- a/linux-user/arm/cpu_loop.c
21
+++ b/include/hw/arm/iotkit.h
19
+++ b/linux-user/arm/cpu_loop.c
22
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
23
#include "hw/or-irq.h"
21
__r; \
24
#include "hw/core/split-irq.h"
22
})
25
23
26
-#define TYPE_ARMSSE "iotkit"
24
-#define get_user_code_u16(x, gaddr, env) \
27
+#define TYPE_ARMSSE "arm-sse"
25
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
28
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
26
- if (!__r && bswap_code(arm_sctlr_b(env))) { \
27
- (x) = bswap16(x); \
28
- } \
29
- __r; \
30
- })
31
-
32
-#define get_user_data_u32(x, gaddr, env) \
33
- ({ abi_long __r = get_user_u32((x), (gaddr)); \
34
- if (!__r && arm_cpu_bswap_data(env)) { \
35
- (x) = bswap32(x); \
36
- } \
37
- __r; \
38
- })
39
-
40
-#define get_user_data_u16(x, gaddr, env) \
41
- ({ abi_long __r = get_user_u16((x), (gaddr)); \
42
- if (!__r && arm_cpu_bswap_data(env)) { \
43
- (x) = bswap16(x); \
44
- } \
45
- __r; \
46
- })
47
-
48
-#define put_user_data_u32(x, gaddr, env) \
49
- ({ typeof(x) __x = (x); \
50
- if (arm_cpu_bswap_data(env)) { \
51
- __x = bswap32(__x); \
52
- } \
53
- put_user_u32(__x, (gaddr)); \
54
- })
55
-
56
-#define put_user_data_u16(x, gaddr, env) \
57
- ({ typeof(x) __x = (x); \
58
- if (arm_cpu_bswap_data(env)) { \
59
- __x = bswap16(__x); \
60
- } \
61
- put_user_u16(__x, (gaddr)); \
62
- })
63
+/*
64
+ * Note that if we need to do data accesses here, they should do a
65
+ * bswap if arm_cpu_bswap_data() returns true.
66
+ */
29
67
30
/*
68
/*
31
- * For the moment TYPE_IOTKIT is a synonym for TYPE_ARMSSE (and the
69
* Similar to code in accel/tcg/user-exec.c, but outside the execution loop.
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
--
70
--
131
2.20.1
71
2.43.0
132
133
diff view generated by jsdifflib
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
1
The arm_cpu_data_is_big_endian() and related functions are now used
2
only in target/arm; they can be moved to internals.h.
2
3
3
Make PMU overflow interrupts more accurate by using a timer to predict
4
The motivation here is that we would like to move arm_current_el()
4
when they will overflow rather than waiting for an event to occur which
5
to internals.h.
5
allows us to otherwise check them.
6
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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
---
9
---
12
target/arm/cpu.h | 10 +++++++
10
target/arm/cpu.h | 48 ------------------------------------------
13
target/arm/cpu.c | 12 ++++++++
11
target/arm/internals.h | 48 ++++++++++++++++++++++++++++++++++++++++++
14
target/arm/helper.c | 72 +++++++++++++++++++++++++++++++++++++++++++--
12
2 files changed, 48 insertions(+), 48 deletions(-)
15
3 files changed, 92 insertions(+), 2 deletions(-)
16
13
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
16
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
18
@@ -XXX,XX +XXX,XX @@ static inline bool arm_sctlr_b(CPUARMState *env)
22
19
23
/* Timers used by the generic (architected) timer */
20
uint64_t arm_sctlr(CPUARMState *env, int el);
24
QEMUTimer *gt_timer[NUM_GTIMERS];
21
22
-static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
23
- bool sctlr_b)
24
-{
25
-#ifdef CONFIG_USER_ONLY
26
- /*
27
- * In system mode, BE32 is modelled in line with the
28
- * architecture (as word-invariant big-endianness), where loads
29
- * and stores are done little endian but from addresses which
30
- * are adjusted by XORing with the appropriate constant. So the
31
- * endianness to use for the raw data access is not affected by
32
- * SCTLR.B.
33
- * In user mode, however, we model BE32 as byte-invariant
34
- * big-endianness (because user-only code cannot tell the
35
- * difference), and so we need to use a data access endianness
36
- * that depends on SCTLR.B.
37
- */
38
- if (sctlr_b) {
39
- return true;
40
- }
41
-#endif
42
- /* In 32bit endianness is determined by looking at CPSR's E bit */
43
- return env->uncached_cpsr & CPSR_E;
44
-}
45
-
46
-static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
47
-{
48
- return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
49
-}
50
-
51
-/* Return true if the processor is in big-endian mode. */
52
-static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
53
-{
54
- if (!is_a64(env)) {
55
- return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
56
- } else {
57
- int cur_el = arm_current_el(env);
58
- uint64_t sctlr = arm_sctlr(env, cur_el);
59
- return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
60
- }
61
-}
62
-
63
#include "exec/cpu-all.h"
64
65
/*
66
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
67
#endif
68
}
69
70
-#ifdef CONFIG_USER_ONLY
71
-static inline bool arm_cpu_bswap_data(CPUARMState *env)
72
-{
73
- return TARGET_BIG_ENDIAN ^ arm_cpu_data_is_big_endian(env);
74
-}
75
-#endif
76
-
77
void cpu_get_tb_cpu_state(CPUARMState *env, vaddr *pc,
78
uint64_t *cs_base, uint32_t *flags);
79
80
diff --git a/target/arm/internals.h b/target/arm/internals.h
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/internals.h
83
+++ b/target/arm/internals.h
84
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
85
return arm_rmode_to_sf_map[rmode];
86
}
87
88
+static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
89
+ bool sctlr_b)
90
+{
91
+#ifdef CONFIG_USER_ONLY
25
+ /*
92
+ /*
26
+ * Timer used by the PMU. Its state is restored after migration by
93
+ * In system mode, BE32 is modelled in line with the
27
+ * pmu_op_finish() - it does not need other handling during migration
94
+ * architecture (as word-invariant big-endianness), where loads
95
+ * and stores are done little endian but from addresses which
96
+ * are adjusted by XORing with the appropriate constant. So the
97
+ * endianness to use for the raw data access is not affected by
98
+ * SCTLR.B.
99
+ * In user mode, however, we model BE32 as byte-invariant
100
+ * big-endianness (because user-only code cannot tell the
101
+ * difference), and so we need to use a data access endianness
102
+ * that depends on SCTLR.B.
28
+ */
103
+ */
29
+ QEMUTimer *pmu_timer;
104
+ if (sctlr_b) {
30
/* GPIO outputs for generic timer */
105
+ return true;
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
+ }
106
+ }
59
+#endif
107
+#endif
60
}
108
+ /* In 32bit endianness is determined by looking at CPSR's E bit */
61
109
+ return env->uncached_cpsr & CPSR_E;
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
+}
110
+}
101
+
111
+
102
/*
112
+static inline bool arm_cpu_data_is_big_endian_a64(int el, uint64_t sctlr)
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
+{
113
+{
111
+ return (ARM_CPU_FREQ / NANOSECONDS_PER_SECOND) * cycles;
114
+ return sctlr & (el ? SCTLR_EE : SCTLR_E0E);
112
+}
115
+}
113
+
116
+
114
static bool instructions_supported(CPUARMState *env)
117
+/* Return true if the processor is in big-endian mode. */
115
{
118
+static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
116
return use_icount == 1 /* Precise instruction counting */;
119
+{
117
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
120
+ if (!is_a64(env)) {
118
{
121
+ return arm_cpu_data_is_big_endian_a32(env, arm_sctlr_b(env));
119
return (uint64_t)cpu_get_icount_raw();
122
+ } else {
120
}
123
+ int cur_el = arm_current_el(env);
124
+ uint64_t sctlr = arm_sctlr(env, cur_el);
125
+ return arm_cpu_data_is_big_endian_a64(cur_el, sctlr);
126
+ }
127
+}
121
+
128
+
122
+static int64_t instructions_ns_per(uint64_t icount)
129
+#ifdef CONFIG_USER_ONLY
130
+static inline bool arm_cpu_bswap_data(CPUARMState *env)
123
+{
131
+{
124
+ return cpu_icount_to_ns((int64_t)icount);
132
+ return TARGET_BIG_ENDIAN ^ arm_cpu_data_is_big_endian(env);
125
+}
133
+}
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
134
+#endif
167
+
135
+
168
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
136
static inline void aarch64_save_sp(CPUARMState *env, int el)
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
{
137
{
180
if (pmu_counter_enabled(env, counter)) {
138
if (env->pstate & PSTATE_SP) {
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
--
139
--
221
2.20.1
140
2.43.0
222
223
diff view generated by jsdifflib
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
1
The functions arm_current_el() and arm_el_is_aa64() are used only in
2
2
target/arm and in hw/intc/arm_gicv3_cpuif.c. They're functions that
3
Since QEMU does not support the ARMv8.2-LVA, Large Virtual Address,
3
query internal state of the CPU. Move them out of cpu.h and into
4
extension (yet), the VA address space is 48-bits plus a sign bit. User
4
internals.h.
5
mode can only handle the positive half of the address space, so that
5
6
makes a limit of 48 bits.
6
This means we need to include internals.h in arm_gicv3_cpuif.c, but
7
7
this is justifiable because that file is implementing the GICv3 CPU
8
(With LVA, it would be 53 and 52 bits respectively.)
8
interface, which really is part of the CPU proper; we just ended up
9
9
implementing it in code in hw/intc/ for historical reasons.
10
The incorrectly large address space conflicts with PAuth instructions,
10
11
which use bits 48-54 and 56-63 for the pointer authentication code. This
11
The motivation for this move is that we'd like to change
12
also conflicts with (as yet unsupported by QEMU) data tagging and with
12
arm_el_is_aa64() to add a condition that uses cpu_isar_feature();
13
the ARMv8.5-MTE extension.
13
but we don't want to include cpu-features.h in cpu.h.
14
14
15
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
17
---
19
target/arm/cpu.h | 2 +-
18
target/arm/cpu.h | 66 --------------------------------------
20
1 file changed, 1 insertion(+), 1 deletion(-)
19
target/arm/internals.h | 67 +++++++++++++++++++++++++++++++++++++++
20
hw/intc/arm_gicv3_cpuif.c | 1 +
21
target/arm/arch_dump.c | 1 +
22
4 files changed, 69 insertions(+), 66 deletions(-)
21
23
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
26
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
27
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu);
28
@@ -XXX,XX +XXX,XX @@ uint64_t arm_hcr_el2_eff_secstate(CPUARMState *env, ARMSecuritySpace space);
27
29
uint64_t arm_hcr_el2_eff(CPUARMState *env);
28
#if defined(TARGET_AARCH64)
30
uint64_t arm_hcrx_el2_eff(CPUARMState *env);
29
# define TARGET_PHYS_ADDR_SPACE_BITS 48
31
30
-# define TARGET_VIRT_ADDR_SPACE_BITS 64
32
-/* Return true if the specified exception level is running in AArch64 state. */
31
+# define TARGET_VIRT_ADDR_SPACE_BITS 48
33
-static inline bool arm_el_is_aa64(CPUARMState *env, int el)
32
#else
34
-{
33
# define TARGET_PHYS_ADDR_SPACE_BITS 40
35
- /* This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
34
# define TARGET_VIRT_ADDR_SPACE_BITS 32
36
- * and if we're not in EL0 then the state of EL0 isn't well defined.)
37
- */
38
- assert(el >= 1 && el <= 3);
39
- bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
40
-
41
- /* The highest exception level is always at the maximum supported
42
- * register width, and then lower levels have a register width controlled
43
- * by bits in the SCR or HCR registers.
44
- */
45
- if (el == 3) {
46
- return aa64;
47
- }
48
-
49
- if (arm_feature(env, ARM_FEATURE_EL3) &&
50
- ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
51
- aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
52
- }
53
-
54
- if (el == 2) {
55
- return aa64;
56
- }
57
-
58
- if (arm_is_el2_enabled(env)) {
59
- aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
60
- }
61
-
62
- return aa64;
63
-}
64
-
65
/*
66
* Function for determining whether guest cp register reads and writes should
67
* access the secure or non-secure bank of a cp register. When EL3 is
68
@@ -XXX,XX +XXX,XX @@ static inline bool arm_v7m_is_handler_mode(CPUARMState *env)
69
return env->v7m.exception != 0;
70
}
71
72
-/* Return the current Exception Level (as per ARMv8; note that this differs
73
- * from the ARMv7 Privilege Level).
74
- */
75
-static inline int arm_current_el(CPUARMState *env)
76
-{
77
- if (arm_feature(env, ARM_FEATURE_M)) {
78
- return arm_v7m_is_handler_mode(env) ||
79
- !(env->v7m.control[env->v7m.secure] & 1);
80
- }
81
-
82
- if (is_a64(env)) {
83
- return extract32(env->pstate, 2, 2);
84
- }
85
-
86
- switch (env->uncached_cpsr & 0x1f) {
87
- case ARM_CPU_MODE_USR:
88
- return 0;
89
- case ARM_CPU_MODE_HYP:
90
- return 2;
91
- case ARM_CPU_MODE_MON:
92
- return 3;
93
- default:
94
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
95
- /* If EL3 is 32-bit then all secure privileged modes run in
96
- * EL3
97
- */
98
- return 3;
99
- }
100
-
101
- return 1;
102
- }
103
-}
104
-
105
/**
106
* write_list_to_cpustate
107
* @cpu: ARMCPU
108
diff --git a/target/arm/internals.h b/target/arm/internals.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/internals.h
111
+++ b/target/arm/internals.h
112
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
113
return arm_rmode_to_sf_map[rmode];
114
}
115
116
+/* Return true if the specified exception level is running in AArch64 state. */
117
+static inline bool arm_el_is_aa64(CPUARMState *env, int el)
118
+{
119
+ /*
120
+ * This isn't valid for EL0 (if we're in EL0, is_a64() is what you want,
121
+ * and if we're not in EL0 then the state of EL0 isn't well defined.)
122
+ */
123
+ assert(el >= 1 && el <= 3);
124
+ bool aa64 = arm_feature(env, ARM_FEATURE_AARCH64);
125
+
126
+ /*
127
+ * The highest exception level is always at the maximum supported
128
+ * register width, and then lower levels have a register width controlled
129
+ * by bits in the SCR or HCR registers.
130
+ */
131
+ if (el == 3) {
132
+ return aa64;
133
+ }
134
+
135
+ if (arm_feature(env, ARM_FEATURE_EL3) &&
136
+ ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
137
+ aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
138
+ }
139
+
140
+ if (el == 2) {
141
+ return aa64;
142
+ }
143
+
144
+ if (arm_is_el2_enabled(env)) {
145
+ aa64 = aa64 && (env->cp15.hcr_el2 & HCR_RW);
146
+ }
147
+
148
+ return aa64;
149
+}
150
+
151
+/*
152
+ * Return the current Exception Level (as per ARMv8; note that this differs
153
+ * from the ARMv7 Privilege Level).
154
+ */
155
+static inline int arm_current_el(CPUARMState *env)
156
+{
157
+ if (arm_feature(env, ARM_FEATURE_M)) {
158
+ return arm_v7m_is_handler_mode(env) ||
159
+ !(env->v7m.control[env->v7m.secure] & 1);
160
+ }
161
+
162
+ if (is_a64(env)) {
163
+ return extract32(env->pstate, 2, 2);
164
+ }
165
+
166
+ switch (env->uncached_cpsr & 0x1f) {
167
+ case ARM_CPU_MODE_USR:
168
+ return 0;
169
+ case ARM_CPU_MODE_HYP:
170
+ return 2;
171
+ case ARM_CPU_MODE_MON:
172
+ return 3;
173
+ default:
174
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
175
+ /* If EL3 is 32-bit then all secure privileged modes run in EL3 */
176
+ return 3;
177
+ }
178
+
179
+ return 1;
180
+ }
181
+}
182
+
183
static inline bool arm_cpu_data_is_big_endian_a32(CPUARMState *env,
184
bool sctlr_b)
185
{
186
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
187
index XXXXXXX..XXXXXXX 100644
188
--- a/hw/intc/arm_gicv3_cpuif.c
189
+++ b/hw/intc/arm_gicv3_cpuif.c
190
@@ -XXX,XX +XXX,XX @@
191
#include "cpu.h"
192
#include "target/arm/cpregs.h"
193
#include "target/arm/cpu-features.h"
194
+#include "target/arm/internals.h"
195
#include "system/tcg.h"
196
#include "system/qtest.h"
197
198
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/arch_dump.c
201
+++ b/target/arm/arch_dump.c
202
@@ -XXX,XX +XXX,XX @@
203
#include "elf.h"
204
#include "system/dump.h"
205
#include "cpu-features.h"
206
+#include "internals.h"
207
208
/* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
209
struct aarch64_user_regs {
35
--
210
--
36
2.20.1
211
2.43.0
37
38
diff view generated by jsdifflib
1
The SSE-200 has two Cortex-M33 CPUs. These see the same view
1
The definition of SCR_EL3.RW says that its effective value is 1 if:
2
of memory, with the exception of the "private CPU region" which
2
- EL2 is implemented and does not support AArch32, and SCR_EL3.NS is 1
3
has per-CPU devices. Internal device interrupts for SSE-200
3
- the effective value of SCR_EL3.{EEL2,NS} is {1,0} (i.e. we are
4
devices are mostly wired up to both CPUs, with the exception of
4
Secure and Secure EL2 is disabled)
5
a few per-CPU devices. External GPIO inputs on the SSE-200
6
device are provided for the second CPU's interrupts above 32,
7
as is already the case for the first CPU.
8
5
9
Refactor the code to support creation of multiple CPUs.
6
We implement the second of these in arm_el_is_aa64(), but forgot the
10
For the moment we leave all CPUs with the same view of
7
first.
11
memory: this will not work in the multiple-CPU case, but
8
12
we will fix this in the following commit.
9
Provide a new function arm_scr_rw_eff() to return the effective
10
value of SCR_EL3.RW, and use it in arm_el_is_aa64() and the other
11
places that currently look directly at the bit value.
12
13
(scr_write() enforces that the RW bit is RAO/WI if neither EL1 nor
14
EL2 have AArch32 support, but if EL1 does but EL2 does not then the
15
bit must still be writeable.)
16
17
This will mean that if code at EL3 attempts to perform an exception
18
return to AArch32 EL2 when EL2 is AArch64-only we will correctly
19
handle this as an illegal exception return: it will be caught by the
20
"return to an EL which is configured for a different register width"
21
check in HELPER(exception_return).
22
23
We do already have some CPU types which don't implement AArch32
24
above EL0, so this is technically a bug; it doesn't seem worth
25
backporting to stable because no sensible guest code will be
26
deliberately attempting to set the RW bit to a value corresponding
27
to an unimplemented execution state and then checking that we
28
did the right thing.
13
29
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20190121185118.18550-12-peter.maydell@linaro.org
17
---
32
---
18
include/hw/arm/armsse.h | 21 +++-
33
target/arm/internals.h | 26 +++++++++++++++++++++++---
19
hw/arm/armsse.c | 206 ++++++++++++++++++++++++++++++++--------
34
target/arm/helper.c | 4 ++--
20
2 files changed, 180 insertions(+), 47 deletions(-)
35
2 files changed, 25 insertions(+), 5 deletions(-)
21
36
22
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
37
diff --git a/target/arm/internals.h b/target/arm/internals.h
23
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/armsse.h
39
--- a/target/arm/internals.h
25
+++ b/include/hw/arm/armsse.h
40
+++ b/target/arm/internals.h
26
@@ -XXX,XX +XXX,XX @@
41
@@ -XXX,XX +XXX,XX @@ static inline FloatRoundMode arm_rmode_to_sf(ARMFPRounding rmode)
27
* + QOM property "memory" is a MemoryRegion containing the devices provided
42
return arm_rmode_to_sf_map[rmode];
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
}
43
}
160
44
161
static void armsse_exp_irq(void *opaque, int n, int level)
45
+/* Return the effective value of SCR_EL3.RW */
162
{
46
+static inline bool arm_scr_rw_eff(CPUARMState *env)
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
+{
47
+{
177
+ /*
48
+ /*
178
+ * Return a qemu_irq which can be used to signal IRQ n to
49
+ * SCR_EL3.RW has an effective value of 1 if:
179
+ * all CPUs in the SSE.
50
+ * - we are NS and EL2 is implemented but doesn't support AArch32
51
+ * - we are S and EL2 is enabled (in which case it must be AArch64)
180
+ */
52
+ */
181
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(s);
53
+ ARMCPU *cpu = env_archcpu(env);
182
+ const ARMSSEInfo *info = asc->info;
183
+
54
+
184
+ assert(irq_is_common[irqno]);
55
+ if (env->cp15.scr_el3 & SCR_RW) {
185
+
56
+ return true;
186
+ if (info->num_cpus == 1) {
57
+ }
187
+ /* Only one CPU -- just connect directly to it */
58
+ if (env->cp15.scr_el3 & SCR_NS) {
188
+ return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
59
+ return arm_feature(env, ARM_FEATURE_EL2) &&
60
+ !cpu_isar_feature(aa64_aa32_el2, cpu);
189
+ } else {
61
+ } else {
190
+ /* Connect to the splitter which feeds all CPUs */
62
+ return env->cp15.scr_el3 & SCR_EEL2;
191
+ return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
192
+ }
63
+ }
193
+}
64
+}
194
+
65
+
195
static void armsse_realize(DeviceState *dev, Error **errp)
66
/* Return true if the specified exception level is running in AArch64 state. */
67
static inline bool arm_el_is_aa64(CPUARMState *env, int el)
196
{
68
{
197
ARMSSE *s = ARMSSE(dev);
69
@@ -XXX,XX +XXX,XX @@ static inline bool arm_el_is_aa64(CPUARMState *env, int el)
198
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
70
return aa64;
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
}
71
}
295
72
296
- /* Connect our EXP_IRQ GPIOs to the NVIC's lines 32 and up. */
73
- if (arm_feature(env, ARM_FEATURE_EL3) &&
297
- s->exp_irqs = g_new(qemu_irq, s->exp_numirq);
74
- ((env->cp15.scr_el3 & SCR_NS) || !(env->cp15.scr_el3 & SCR_EEL2))) {
298
- for (i = 0; i < s->exp_numirq; i++) {
75
- aa64 = aa64 && (env->cp15.scr_el3 & SCR_RW);
299
- s->exp_irqs[i] = qdev_get_gpio_in(DEVICE(&s->armv7m), i + 32);
76
+ if (arm_feature(env, ARM_FEATURE_EL3)) {
300
+ /* Wire up the splitters that connect common IRQs to all CPUs */
77
+ aa64 = aa64 && arm_scr_rw_eff(env);
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
}
78
}
328
- qdev_init_gpio_in_named(dev, armsse_exp_irq, "EXP_IRQ", s->exp_numirq);
79
329
80
if (el == 2) {
330
/* Set up the big aliases first */
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
331
make_alias(s, &s->alias1, "alias 1", 0x10000000, 0x10000000, 0x00000000);
82
index XXXXXXX..XXXXXXX 100644
332
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
83
--- a/target/arm/helper.c
333
return;
84
+++ b/target/arm/helper.c
334
}
85
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
335
qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
86
uint64_t hcr_el2;
336
- qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
87
337
+ armsse_get_common_irq_in(s, 9));
88
if (arm_feature(env, ARM_FEATURE_EL3)) {
338
89
- rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
339
/* Devices behind APB PPC0:
90
+ rw = arm_scr_rw_eff(env);
340
* 0x40000000: timer0
91
} else {
341
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
92
/*
342
return;
93
* Either EL2 is the highest EL (and so the EL2 register width
343
}
94
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
344
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer0), 0,
95
345
- qdev_get_gpio_in(DEVICE(&s->armv7m), 3));
96
switch (new_el) {
346
+ armsse_get_common_irq_in(s, 3));
97
case 3:
347
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->timer0), 0);
98
- is_aa64 = (env->cp15.scr_el3 & SCR_RW) != 0;
348
object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[0]", &err);
99
+ is_aa64 = arm_scr_rw_eff(env);
349
if (err) {
100
break;
350
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
101
case 2:
351
return;
102
hcr = arm_hcr_el2_eff(env);
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
--
103
--
405
2.20.1
104
2.43.0
406
407
diff view generated by jsdifflib
1
From: Aaron Lindsay OS <aaron@os.amperecomputing.com>
1
When EL1 doesn't support AArch32, the HCR_EL2.RW bit is supposed to
2
be RAO/WI. Enforce the RAO/WI behaviour.
2
3
3
Whenever we notice that a counter overflow has occurred, send an
4
Note that we handle "reset value should honour RES1 bits" in the same
4
interrupt. This is made more reliable with the addition of a timer in a
5
way that SCR_EL3 does, via a reset function.
5
follow-on commit.
6
6
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
7
We do already have some CPU types which don't implement AArch32
8
above EL0, so this is technically a bug; it doesn't seem worth
9
backporting to stable because no sensible guest code will be
10
deliberately attempting to set the RW bit to a value corresponding
11
to an unimplemented execution state and then checking that we
12
did the right thing.
13
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190124162401.5111-2-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
target/arm/helper.c | 61 +++++++++++++++++++++++++++++++++++++--------
17
target/arm/helper.c | 12 ++++++++++++
13
1 file changed, 51 insertions(+), 10 deletions(-)
18
1 file changed, 12 insertions(+)
14
19
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
22
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
23
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
24
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
20
/* Definitions for the PMU registers */
25
/* Clear RES0 bits. */
21
#define PMCRN_MASK 0xf800
26
value &= valid_mask;
22
#define PMCRN_SHIFT 11
27
23
+#define PMCRLC 0x40
28
+ /* RW is RAO/WI if EL1 is AArch64 only */
24
#define PMCRDP 0x10
29
+ if (!cpu_isar_feature(aa64_aa32_el1, cpu)) {
25
#define PMCRD 0x8
30
+ value |= HCR_RW;
26
#define PMCRC 0x4
31
+ }
27
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
32
+
28
return enabled && !prohibited && !filtered;
33
/*
34
* These bits change the MMU setup:
35
* HCR_VM enables stage 2 translation
36
@@ -XXX,XX +XXX,XX @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri,
37
do_hcr_write(env, value, MAKE_64BIT_MASK(32, 32));
29
}
38
}
30
39
31
+static void pmu_update_irq(CPUARMState *env)
40
+static void hcr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
32
+{
41
+{
33
+ ARMCPU *cpu = arm_env_get_cpu(env);
42
+ /* hcr_write will set the RES1 bits on an AArch64-only CPU */
34
+ qemu_set_irq(cpu->pmu_interrupt, (env->cp15.c9_pmcr & PMCRE) &&
43
+ hcr_write(env, ri, 0);
35
+ (env->cp15.c9_pminten & env->cp15.c9_pmovsr));
36
+}
44
+}
37
+
45
+
38
/*
46
/*
39
* Ensure c15_ccnt is the guest-visible count so that operations such as
47
* Return the effective value of HCR_EL2, at the given security state.
40
* enabling/disabling the counter or filtering, modifying the count itself,
48
* Bits that are not included here:
41
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
49
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
42
eff_cycles /= 64;
50
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
43
}
51
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.hcr_el2),
44
52
.nv2_redirect_offset = 0x78,
45
- env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
53
+ .resetfn = hcr_reset,
46
+ uint64_t new_pmccntr = eff_cycles - env->cp15.c15_ccnt_delta;
54
.writefn = hcr_write, .raw_writefn = raw_write },
47
+
55
{ .name = "HCR", .state = ARM_CP_STATE_AA32,
48
+ uint64_t overflow_mask = env->cp15.c9_pmcr & PMCRLC ? \
56
.type = ARM_CP_ALIAS | ARM_CP_IO,
49
+ 1ull << 63 : 1ull << 31;
50
+ if (env->cp15.c15_ccnt & ~new_pmccntr & overflow_mask) {
51
+ env->cp15.c9_pmovsr |= (1 << 31);
52
+ pmu_update_irq(env);
53
+ }
54
+
55
+ env->cp15.c15_ccnt = new_pmccntr;
56
}
57
env->cp15.c15_ccnt_delta = cycles;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
60
}
61
62
if (pmu_counter_enabled(env, counter)) {
63
- env->cp15.c14_pmevcntr[counter] =
64
- count - env->cp15.c14_pmevcntr_delta[counter];
65
+ uint32_t new_pmevcntr = count - env->cp15.c14_pmevcntr_delta[counter];
66
+
67
+ if (env->cp15.c14_pmevcntr[counter] & ~new_pmevcntr & INT32_MIN) {
68
+ env->cp15.c9_pmovsr |= (1 << counter);
69
+ pmu_update_irq(env);
70
+ }
71
+ env->cp15.c14_pmevcntr[counter] = new_pmevcntr;
72
}
73
env->cp15.c14_pmevcntr_delta[counter] = count;
74
}
75
@@ -XXX,XX +XXX,XX @@ static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
76
/* counter is SW_INCR */
77
(env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
78
pmevcntr_op_start(env, i);
79
- env->cp15.c14_pmevcntr[i]++;
80
+
81
+ /*
82
+ * Detect if this write causes an overflow since we can't predict
83
+ * PMSWINC overflows like we can for other events
84
+ */
85
+ uint32_t new_pmswinc = env->cp15.c14_pmevcntr[i] + 1;
86
+
87
+ if (env->cp15.c14_pmevcntr[i] & ~new_pmswinc & INT32_MIN) {
88
+ env->cp15.c9_pmovsr |= (1 << i);
89
+ pmu_update_irq(env);
90
+ }
91
+
92
+ env->cp15.c14_pmevcntr[i] = new_pmswinc;
93
+
94
pmevcntr_op_finish(env, i);
95
}
96
}
97
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
98
{
99
value &= pmu_counter_mask(env);
100
env->cp15.c9_pmovsr &= ~value;
101
+ pmu_update_irq(env);
102
}
103
104
static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
105
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
106
{
107
value &= pmu_counter_mask(env);
108
env->cp15.c9_pmovsr |= value;
109
+ pmu_update_irq(env);
110
}
111
112
static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
113
@@ -XXX,XX +XXX,XX @@ static void pmintenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
114
/* We have no event counters so only the C bit can be changed */
115
value &= pmu_counter_mask(env);
116
env->cp15.c9_pminten |= value;
117
+ pmu_update_irq(env);
118
}
119
120
static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
121
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
122
{
123
value &= pmu_counter_mask(env);
124
env->cp15.c9_pminten &= ~value;
125
+ pmu_update_irq(env);
126
}
127
128
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
129
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
130
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
131
.writefn = pmcntenclr_write },
132
{ .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
133
- .access = PL0_RW,
134
+ .access = PL0_RW, .type = ARM_CP_IO,
135
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
136
.accessfn = pmreg_access,
137
.writefn = pmovsr_write,
138
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
139
{ .name = "PMOVSCLR_EL0", .state = ARM_CP_STATE_AA64,
140
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 3,
141
.access = PL0_RW, .accessfn = pmreg_access,
142
- .type = ARM_CP_ALIAS,
143
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
144
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
145
.writefn = pmovsr_write,
146
.raw_writefn = raw_write },
147
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
148
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
149
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
150
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
151
.writefn = pmswinc_write },
152
{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
153
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
154
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
155
+ .access = PL0_W, .accessfn = pmreg_access_swinc,
156
+ .type = ARM_CP_NO_RAW | ARM_CP_IO,
157
.writefn = pmswinc_write },
158
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
159
.access = PL0_RW, .type = ARM_CP_ALIAS,
160
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
161
/* PMOVSSET is not implemented in v7 before v7ve */
162
{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
163
.access = PL0_RW, .accessfn = pmreg_access,
164
- .type = ARM_CP_ALIAS,
165
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
166
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
167
.writefn = pmovsset_write,
168
.raw_writefn = raw_write },
169
{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
170
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
171
.access = PL0_RW, .accessfn = pmreg_access,
172
- .type = ARM_CP_ALIAS,
173
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
174
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
175
.writefn = pmovsset_write,
176
.raw_writefn = raw_write },
177
--
57
--
178
2.20.1
58
2.43.0
179
180
diff view generated by jsdifflib
1
Give each CPU its own container memory region. This is necessary
1
We already call env_archcpu() multiple times within the
2
for two reasons:
2
exception_return helper function, and we're about to want to
3
* some devices are instantiated one per CPU and the CPU sees only
3
add another use of the ARMCPU pointer. Add a local variable
4
its own device
4
cpu so we can call env_archcpu() just once.
5
* since a memory region can only be put into one container, we must
6
give each armv7m object a different MemoryRegion as its 'memory'
7
property, or a dual-CPU configuration will assert on realize when
8
the second armv7m object tries to put the MR into a container when
9
it is already in the first armv7m object's container
10
5
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190121185118.18550-13-peter.maydell@linaro.org
14
---
8
---
15
include/hw/arm/armsse.h | 10 ++++++++++
9
target/arm/tcg/helper-a64.c | 7 ++++---
16
hw/arm/armsse.c | 22 ++++++++++++++++++++--
10
1 file changed, 4 insertions(+), 3 deletions(-)
17
2 files changed, 30 insertions(+), 2 deletions(-)
18
11
19
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
12
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/armsse.h
14
--- a/target/arm/tcg/helper-a64.c
22
+++ b/include/hw/arm/armsse.h
15
+++ b/target/arm/tcg/helper-a64.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
16
@@ -XXX,XX +XXX,XX @@ static void cpsr_write_from_spsr_elx(CPUARMState *env,
24
IoTKitSysCtl sysctl;
17
25
IoTKitSysCtl sysinfo;
18
void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
26
19
{
27
+ /*
20
+ ARMCPU *cpu = env_archcpu(env);
28
+ * 'container' holds all devices seen by all CPUs.
21
int cur_el = arm_current_el(env);
29
+ * 'cpu_container[i]' is the view that CPU i has: this has the
22
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
30
+ * per-CPU devices of that CPU, plus as the background 'container'
23
uint32_t spsr = env->banked_spsr[spsr_idx];
31
+ * (or an alias of it, since we can only use it directly once).
24
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
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
}
25
}
59
26
60
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
27
bql_lock();
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
28
- arm_call_pre_el_change_hook(env_archcpu(env));
62
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
29
+ arm_call_pre_el_change_hook(cpu);
63
*/
30
bql_unlock();
64
31
65
- memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
32
if (!return_to_aa64) {
66
+ memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
33
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
67
34
int tbii;
68
for (i = 0; i < info->num_cpus; i++) {
35
69
DeviceState *cpudev = DEVICE(&s->armv7m[i]);
36
env->aarch64 = true;
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
37
- spsr &= aarch64_pstate_valid_mask(&env_archcpu(env)->isar);
71
return;
38
+ spsr &= aarch64_pstate_valid_mask(&cpu->isar);
72
}
39
pstate_write(env, spsr);
73
}
40
if (!arm_singlestep_active(env)) {
74
- object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
41
env->pstate &= ~PSTATE_SS;
75
+
42
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
76
+ if (i > 0) {
43
aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
77
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
44
78
+ &s->container_alias[i - 1], -1);
45
bql_lock();
79
+ } else {
46
- arm_call_el_change_hook(env_archcpu(env));
80
+ memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
47
+ arm_call_el_change_hook(cpu);
81
+ &s->container, -1);
48
bql_unlock();
82
+ }
49
83
+ object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
50
return;
84
+ "memory", &err);
85
if (err) {
86
error_propagate(errp, err);
87
return;
88
--
51
--
89
2.20.1
52
2.43.0
90
91
diff view generated by jsdifflib
1
For the IoTKit the SRAM bank size is always 32K (15 bits); for the
1
In the Arm ARM, rule R_TYTWB states that returning to AArch32
2
SSE-200 this is a configurable parameter, which defaults to 32K but
2
is an illegal exception return if:
3
can be changed when it is built into a particular SoC. For instance
3
* AArch32 is not supported at any exception level
4
the Musca-B1 board sets it to 128K (17 bits).
4
* the target EL is configured for AArch64 via SCR_EL3.RW
5
or HCR_EL2.RW or via CPU state at reset
5
6
6
Make the bank size a QOM property. We follow the SSE-200 hardware in
7
We check the second of these, but not the first (which can only be
7
naming the parameter SRAM_ADDR_WIDTH, which specifies the number of
8
relevant for the case of a return to EL0, because if AArch32 is not
8
address bits of a single SRAM bank.
9
supported at one of the higher ELs then the RW bits will have an
10
effective value of 1 and the the "configured for AArch64" condition
11
will hold also).
12
13
Add the missing condition. Although this is technically a bug
14
(because we have one AArch64-only CPU: a64fx) it isn't worth
15
backporting to stable because no sensible guest code will
16
deliberately try to return to a nonexistent execution state
17
to check that it gets an illegal exception return.
9
18
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190121185118.18550-11-peter.maydell@linaro.org
13
---
21
---
14
include/hw/arm/armsse.h | 1 +
22
target/arm/tcg/helper-a64.c | 5 +++++
15
hw/arm/armsse.c | 18 ++++++++++++++++--
23
1 file changed, 5 insertions(+)
16
2 files changed, 17 insertions(+), 2 deletions(-)
17
24
18
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
25
diff --git a/target/arm/tcg/helper-a64.c b/target/arm/tcg/helper-a64.c
19
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/armsse.h
27
--- a/target/arm/tcg/helper-a64.c
21
+++ b/include/hw/arm/armsse.h
28
+++ b/target/arm/tcg/helper-a64.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
29
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
23
MemoryRegion *board_memory;
30
goto illegal_return;
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
}
31
}
45
32
46
+ /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
33
+ if (!return_to_aa64 && !cpu_isar_feature(aa64_aa32, cpu)) {
47
+ assert(is_power_of_2(info->sram_banks));
34
+ /* Return to AArch32 when CPU is AArch64-only */
48
+ addr_width_max = 24 - ctz32(info->sram_banks);
35
+ goto illegal_return;
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
+ }
36
+ }
54
+
37
+
55
/* Handling of which devices should be available only to secure
38
if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
56
* code is usually done differently for M profile than for A profile.
39
goto illegal_return;
57
* Instead of putting some devices only into the secure address space,
40
}
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
--
41
--
89
2.20.1
42
2.43.0
90
91
diff view generated by jsdifflib
1
Rename the files that used to be iotkit.[ch] to
1
I'm down as the only listed maintainer for quite a lot of Arm SoC and
2
armsse.[ch] to reflect the fact they new cover
2
board types. In some cases this is only as the "maintainer of last
3
multiple Arm subsystems for embedded.
3
resort" and I'm not in practice doing anything beyond patch review
4
and the odd bit of tidyup.
5
6
Move these entries in MAINTAINERS from "Maintained" to "Odd Fixes",
7
to better represent reality. Entries for other boards and SoCs where
8
I do more actively care (or where there is a listed co-maintainer)
9
remain as they are.
4
10
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20250307152838.3226398-1-peter.maydell@linaro.org
8
Message-id: 20190121185118.18550-8-peter.maydell@linaro.org
9
---
14
---
10
hw/arm/Makefile.objs | 2 +-
15
MAINTAINERS | 14 +++++++-------
11
include/hw/arm/{iotkit.h => armsse.h} | 4 ++--
16
1 file changed, 7 insertions(+), 7 deletions(-)
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
17
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
18
diff --git a/MAINTAINERS b/MAINTAINERS
81
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
82
--- a/MAINTAINERS
20
--- a/MAINTAINERS
83
+++ b/MAINTAINERS
21
+++ b/MAINTAINERS
84
@@ -XXX,XX +XXX,XX @@ F: hw/arm/mps2.c
22
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/kzm.rst
85
F: hw/arm/mps2-tz.c
23
Integrator CP
86
F: hw/misc/mps2-*.c
24
M: Peter Maydell <peter.maydell@linaro.org>
87
F: include/hw/misc/mps2-*.h
25
L: qemu-arm@nongnu.org
88
-F: hw/arm/iotkit.c
26
-S: Maintained
89
-F: include/hw/arm/iotkit.h
27
+S: Odd Fixes
90
+F: hw/arm/armsse.c
28
F: hw/arm/integratorcp.c
91
+F: include/hw/arm/armsse.h
29
F: hw/misc/arm_integrator_debug.c
92
F: hw/misc/iotkit-secctl.c
30
F: include/hw/misc/arm_integrator_debug.h
93
F: include/hw/misc/iotkit-secctl.h
31
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/mps2.rst
94
F: hw/misc/iotkit-sysctl.c
32
Musca
95
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
33
M: Peter Maydell <peter.maydell@linaro.org>
96
index XXXXXXX..XXXXXXX 100644
34
L: qemu-arm@nongnu.org
97
--- a/default-configs/arm-softmmu.mak
35
-S: Maintained
98
+++ b/default-configs/arm-softmmu.mak
36
+S: Odd Fixes
99
@@ -XXX,XX +XXX,XX @@ CONFIG_MPS2_SCC=y
37
F: hw/arm/musca.c
100
CONFIG_TZ_MPC=y
38
F: docs/system/arm/musca.rst
101
CONFIG_TZ_MSC=y
39
102
CONFIG_TZ_PPC=y
40
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_aarch64_raspi4.py
103
-CONFIG_IOTKIT=y
41
Real View
104
+CONFIG_ARMSSE=y
42
M: Peter Maydell <peter.maydell@linaro.org>
105
CONFIG_IOTKIT_SECCTL=y
43
L: qemu-arm@nongnu.org
106
CONFIG_IOTKIT_SYSCTL=y
44
-S: Maintained
107
CONFIG_IOTKIT_SYSINFO=y
45
+S: Odd Fixes
46
F: hw/arm/realview*
47
F: hw/cpu/realview_mpcore.c
48
F: hw/intc/realview_gic.c
49
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_arm_collie.py
50
Stellaris
51
M: Peter Maydell <peter.maydell@linaro.org>
52
L: qemu-arm@nongnu.org
53
-S: Maintained
54
+S: Odd Fixes
55
F: hw/*/stellaris*
56
F: hw/display/ssd03*
57
F: include/hw/input/gamepad.h
58
@@ -XXX,XX +XXX,XX @@ F: docs/system/arm/stm32.rst
59
Versatile Express
60
M: Peter Maydell <peter.maydell@linaro.org>
61
L: qemu-arm@nongnu.org
62
-S: Maintained
63
+S: Odd Fixes
64
F: hw/arm/vexpress.c
65
F: hw/display/sii9022.c
66
F: docs/system/arm/vexpress.rst
67
@@ -XXX,XX +XXX,XX @@ F: tests/functional/test_arm_vexpress.py
68
Versatile PB
69
M: Peter Maydell <peter.maydell@linaro.org>
70
L: qemu-arm@nongnu.org
71
-S: Maintained
72
+S: Odd Fixes
73
F: hw/*/versatile*
74
F: hw/i2c/arm_sbcon_i2c.c
75
F: include/hw/i2c/arm_sbcon_i2c.h
76
@@ -XXX,XX +XXX,XX @@ F: include/hw/hyperv/vmbus*.h
77
OMAP
78
M: Peter Maydell <peter.maydell@linaro.org>
79
L: qemu-arm@nongnu.org
80
-S: Maintained
81
+S: Odd Fixes
82
F: hw/*/omap*
83
F: include/hw/arm/omap.h
84
F: docs/system/arm/sx1.rst
108
--
85
--
109
2.20.1
86
2.43.0
110
87
111
88
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
The guest does not control whether characters are sent on the UART.
4
Sending them before the guest happens to boot will now result in a
5
"guest error" log entry that is only because of timing, even if the
6
guest _would_ later setup the receiver correctly.
7
8
This reverts the bulk of commit abf2b6a028670bd2890bb3aee7e103fe53e4b0df,
9
and instead adds a comment about why we don't check the enable bits.
10
11
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
14
Message-id: 20250311153717.206129-1-pbonzini@redhat.com
15
[PMM: expanded comment]
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
18
---
7
linux-user/elfload.c | 1 +
19
hw/char/pl011.c | 19 ++++++++++---------
8
1 file changed, 1 insertion(+)
20
1 file changed, 10 insertions(+), 9 deletions(-)
9
21
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
22
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
11
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
24
--- a/hw/char/pl011.c
13
+++ b/linux-user/elfload.c
25
+++ b/hw/char/pl011.c
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
26
@@ -XXX,XX +XXX,XX @@ static int pl011_can_receive(void *opaque)
15
GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
27
unsigned fifo_depth = pl011_get_fifo_depth(s);
16
GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
28
unsigned fifo_available = fifo_depth - s->read_count;
17
GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
29
18
+ GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
30
- if (!(s->cr & CR_UARTEN)) {
19
31
- qemu_log_mask(LOG_GUEST_ERROR,
20
#undef GET_FEATURE_ID
32
- "PL011 receiving data on disabled UART\n");
33
- }
34
- if (!(s->cr & CR_RXE)) {
35
- qemu_log_mask(LOG_GUEST_ERROR,
36
- "PL011 receiving data on disabled RX UART\n");
37
- }
38
- trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
39
+ /*
40
+ * In theory we should check the UART and RX enable bits here and
41
+ * return 0 if they are not set (so the guest can't receive data
42
+ * until you have enabled the UART). In practice we suspect there
43
+ * is at least some guest code out there which has been tested only
44
+ * on QEMU and which never bothers to enable the UART because we
45
+ * historically never enforced that. So we effectively keep the
46
+ * UART continuously enabled regardless of the enable bits.
47
+ */
48
49
+ trace_pl011_can_receive(s->lcr, s->read_count, fifo_depth, fifo_available);
50
return fifo_available;
51
}
21
52
22
--
53
--
23
2.20.1
54
2.43.0
24
55
25
56
diff view generated by jsdifflib
1
From: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
1
From: Joe Komlodi <komlodi@google.com>
2
2
3
A flawed test lead to the instructions always being treated as
3
On ARM hosts with CTR_EL0.DIC and CTR_EL0.IDC set, this would only cause
4
unallocated encodings.
4
an ISB to be executed during cache maintenance, which could lead to QEMU
5
executing TBs containing garbage instructions.
5
6
6
Fixes: https://bugs.launchpad.net/bugs/1813460
7
This seems to be because the ISB finishes executing instructions and
7
Signed-off-by: Remi Denis-Courmont <remi.denis.courmont@huawei.com>
8
flushes the pipeline, but the ISB doesn't guarantee that writes from the
9
executed instructions are committed. If a small enough TB is created, it's
10
possible that the writes setting up the TB aren't committed by the time the
11
TB is executed.
12
13
This function is intended to be a port of the gcc implementation
14
(https://github.com/gcc-mirror/gcc/blob/85b46d0795ac76bc192cb8f88b646a647acf98c1/libgcc/config/aarch64/sync-cache.c#L67)
15
which makes the first DSB unconditional, so we can fix the synchronization
16
issue by doing that as well.
17
18
Cc: qemu-stable@nongnu.org
19
Fixes: 664a79735e4deb1 ("util: Specialize flush_idcache_range for aarch64")
20
Signed-off-by: Joe Komlodi <komlodi@google.com>
21
Message-id: 20250310203622.1827940-2-komlodi@google.com
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
25
---
11
target/arm/translate-a64.c | 2 +-
26
util/cacheflush.c | 4 +++-
12
1 file changed, 1 insertion(+), 1 deletion(-)
27
1 file changed, 3 insertions(+), 1 deletion(-)
13
28
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
29
diff --git a/util/cacheflush.c b/util/cacheflush.c
15
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
31
--- a/util/cacheflush.c
17
+++ b/target/arm/translate-a64.c
32
+++ b/util/cacheflush.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
33
@@ -XXX,XX +XXX,XX @@ void flush_idcache_range(uintptr_t rx, uintptr_t rw, size_t len)
19
if (!dc_isar_feature(aa64_pauth, s)) {
34
for (p = rw & -dcache_lsize; p < rw + len; p += dcache_lsize) {
20
goto do_unallocated;
35
asm volatile("dc\tcvau, %0" : : "r" (p) : "memory");
21
}
36
}
22
- if (op3 != 2 || op3 != 3) {
37
- asm volatile("dsb\tish" : : : "memory");
23
+ if ((op3 & ~1) != 2) {
38
}
24
goto do_unallocated;
39
25
}
40
+ /* DSB unconditionally to ensure any outstanding writes are committed. */
26
if (s->pauth_active) {
41
+ asm volatile("dsb\tish" : : : "memory");
42
+
43
/*
44
* If CTR_EL0.DIC is enabled, Instruction cache cleaning to the Point
45
* of Unification is not required for instruction to data coherence.
27
--
46
--
28
2.20.1
47
2.43.0
29
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Drop the pac properties. This approach cannot work as written
3
The check for fp_excp_el in assert_fp_access_checked is
4
because the properties are applied before arm_cpu_reset, which
4
incorrect. For SME, with StreamingMode enabled, the access
5
zeros SCTLR_EL1 (amongst everything else).
5
is really against the streaming mode vectors, and access
6
to the normal fp registers is allowed to be disabled.
7
C.f. sme_enabled_check.
6
8
7
We can re-introduce the properties if they turn out to be useful.
9
Convert sve_access_checked to match, even though we don't
8
But since linux 5.0 enables all of the keys, they may not be.
10
currently check the exception state.
9
11
10
Fixes: 1ae9cfbd470
12
Cc: qemu-stable@nongnu.org
13
Fixes: 3d74825f4d6 ("target/arm: Add SME enablement checks")
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20250307190415.982049-2-richard.henderson@linaro.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
18
---
15
target/arm/cpu.c | 3 +++
19
target/arm/tcg/translate-a64.h | 2 +-
16
target/arm/cpu64.c | 60 ----------------------------------------------
20
target/arm/tcg/translate.h | 10 +++++++---
17
2 files changed, 3 insertions(+), 60 deletions(-)
21
target/arm/tcg/translate-a64.c | 17 +++++++++--------
22
3 files changed, 17 insertions(+), 12 deletions(-)
18
23
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
24
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
26
--- a/target/arm/tcg/translate-a64.h
22
+++ b/target/arm/cpu.c
27
+++ b/target/arm/tcg/translate-a64.h
23
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
28
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
24
env->pstate = PSTATE_MODE_EL0t;
29
static inline void assert_fp_access_checked(DisasContext *s)
25
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
30
{
26
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
31
#ifdef CONFIG_DEBUG_TCG
27
+ /* Enable all PAC keys. */
32
- if (unlikely(!s->fp_access_checked || s->fp_excp_el)) {
28
+ env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
33
+ if (unlikely(s->fp_access_checked <= 0)) {
29
+ SCTLR_EnDA | SCTLR_EnDB);
34
fprintf(stderr, "target-arm: FP access check missing for "
30
/* Enable all PAC instructions */
35
"instruction 0x%08x\n", s->insn);
31
env->cp15.hcr_el2 |= HCR_API;
36
abort();
32
env->cp15.scr_el3 |= SCR_API;
37
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
33
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
34
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu64.c
39
--- a/target/arm/tcg/translate.h
36
+++ b/target/arm/cpu64.c
40
+++ b/target/arm/tcg/translate.h
37
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
38
error_propagate(errp, err);
42
bool aarch64;
43
bool thumb;
44
bool lse2;
45
- /* Because unallocated encodings generate different exception syndrome
46
+ /*
47
+ * Because unallocated encodings generate different exception syndrome
48
* information from traps due to FP being disabled, we can't do a single
49
* "is fp access disabled" check at a high level in the decode tree.
50
* To help in catching bugs where the access check was forgotten in some
51
* code path, we set this flag when the access check is done, and assert
52
* that it is set at the point where we actually touch the FP regs.
53
+ * 0: not checked,
54
+ * 1: checked, access ok
55
+ * -1: checked, access denied
56
*/
57
- bool fp_access_checked;
58
- bool sve_access_checked;
59
+ int8_t fp_access_checked;
60
+ int8_t sve_access_checked;
61
/* ARMv8 single-step state (this is distinct from the QEMU gdbstub
62
* single-step support).
63
*/
64
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/tcg/translate-a64.c
67
+++ b/target/arm/tcg/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static bool fp_access_check_only(DisasContext *s)
69
{
70
if (s->fp_excp_el) {
71
assert(!s->fp_access_checked);
72
- s->fp_access_checked = true;
73
+ s->fp_access_checked = -1;
74
75
gen_exception_insn_el(s, 0, EXCP_UDEF,
76
syn_fp_access_trap(1, 0xe, false, 0),
77
s->fp_excp_el);
78
return false;
79
}
80
- s->fp_access_checked = true;
81
+ s->fp_access_checked = 1;
82
return true;
39
}
83
}
40
84
41
-#ifdef CONFIG_USER_ONLY
85
@@ -XXX,XX +XXX,XX @@ bool sve_access_check(DisasContext *s)
42
-static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
86
syn_sve_access_trap(), s->sve_excp_el);
43
- void *opaque, Error **errp)
87
goto fail_exit;
44
-{
88
}
45
- ARMCPU *cpu = ARM_CPU(obj);
89
- s->sve_access_checked = true;
46
- const uint64_t *bit = opaque;
90
+ s->sve_access_checked = 1;
47
- bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
91
return fp_access_check(s);
48
-
92
49
- visit_type_bool(v, name, &enabled, errp);
93
fail_exit:
50
-}
94
/* Assert that we only raise one exception per instruction. */
51
-
95
assert(!s->sve_access_checked);
52
-static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
96
- s->sve_access_checked = true;
53
- void *opaque, Error **errp)
97
+ s->sve_access_checked = -1;
54
-{
98
return false;
55
- ARMCPU *cpu = ARM_CPU(obj);
99
}
56
- Error *err = NULL;
100
57
- const uint64_t *bit = opaque;
101
@@ -XXX,XX +XXX,XX @@ bool sme_enabled_check(DisasContext *s)
58
- bool enabled;
102
* sme_excp_el by itself for cpregs access checks.
59
-
103
*/
60
- visit_type_bool(v, name, &enabled, errp);
104
if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
61
-
105
- s->fp_access_checked = true;
62
- if (!err) {
106
- return sme_access_check(s);
63
- if (enabled) {
107
+ bool ret = sme_access_check(s);
64
- cpu->env.cp15.sctlr_el[1] |= *bit;
108
+ s->fp_access_checked = (ret ? 1 : -1);
65
- } else {
109
+ return ret;
66
- cpu->env.cp15.sctlr_el[1] &= ~*bit;
110
}
67
- }
111
return fp_access_check_only(s);
68
- }
112
}
69
- error_propagate(errp, err);
113
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
70
-}
114
s->insn = insn;
71
-#endif
115
s->base.pc_next = pc + 4;
72
-
116
73
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
117
- s->fp_access_checked = false;
74
* otherwise, a CPU with as many features enabled as our emulation supports.
118
- s->sve_access_checked = false;
75
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
119
+ s->fp_access_checked = 0;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
120
+ s->sve_access_checked = 0;
77
*/
121
78
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
122
if (s->pstate_il) {
79
cpu->dcz_blocksize = 7; /* 512 bytes */
123
/*
80
-
81
- /*
82
- * Note that Linux will enable enable all of the keys at once.
83
- * But doing it this way will allow experimentation beyond that.
84
- */
85
- {
86
- static const uint64_t apia_bit = SCTLR_EnIA;
87
- static const uint64_t apib_bit = SCTLR_EnIB;
88
- static const uint64_t apda_bit = SCTLR_EnDA;
89
- static const uint64_t apdb_bit = SCTLR_EnDB;
90
-
91
- object_property_add(obj, "apia", "bool", cpu_max_get_packey,
92
- cpu_max_set_packey, NULL,
93
- (void *)&apia_bit, &error_fatal);
94
- object_property_add(obj, "apib", "bool", cpu_max_get_packey,
95
- cpu_max_set_packey, NULL,
96
- (void *)&apib_bit, &error_fatal);
97
- object_property_add(obj, "apda", "bool", cpu_max_get_packey,
98
- cpu_max_set_packey, NULL,
99
- (void *)&apda_bit, &error_fatal);
100
- object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
101
- cpu_max_set_packey, NULL,
102
- (void *)&apdb_bit, &error_fatal);
103
-
104
- /* Enable all PAC keys by default. */
105
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
106
- cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
107
- }
108
#endif
109
110
cpu->sve_max_vq = ARM_MAX_VQ;
111
--
124
--
112
2.20.1
125
2.43.0
113
114
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
In StreamingMode, fp_access_checked is handled already.
4
We cannot fall through to fp_access_check lest we fall
5
foul of the double-check assertion.
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 285b1d5fcef ("target/arm: Handle SME in sve_access_check")
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
10
Message-id: 20250307190415.982049-3-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
[PMM: move declaration of 'ret' to top of block]
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
14
---
7
linux-user/elfload.c | 9 +++++++++
15
target/arm/tcg/translate-a64.c | 22 +++++++++++-----------
8
1 file changed, 9 insertions(+)
16
1 file changed, 11 insertions(+), 11 deletions(-)
9
17
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
18
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
11
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
20
--- a/target/arm/tcg/translate-a64.c
13
+++ b/linux-user/elfload.c
21
+++ b/target/arm/tcg/translate-a64.c
14
@@ -XXX,XX +XXX,XX @@ enum {
22
@@ -XXX,XX +XXX,XX @@ static int fp_access_check_vector_hsd(DisasContext *s, bool is_q, MemOp esz)
15
ARM_HWCAP_A64_ASIMDDP = 1 << 20,
23
bool sve_access_check(DisasContext *s)
16
ARM_HWCAP_A64_SHA512 = 1 << 21,
24
{
17
ARM_HWCAP_A64_SVE = 1 << 22,
25
if (s->pstate_sm || !dc_isar_feature(aa64_sve, s)) {
18
+ ARM_HWCAP_A64_ASIMDFHM = 1 << 23,
26
+ bool ret;
19
+ ARM_HWCAP_A64_DIT = 1 << 24,
27
+
20
+ ARM_HWCAP_A64_USCAT = 1 << 25,
28
assert(dc_isar_feature(aa64_sme, s));
21
+ ARM_HWCAP_A64_ILRCPC = 1 << 26,
29
- if (!sme_sm_enabled_check(s)) {
22
+ ARM_HWCAP_A64_FLAGM = 1 << 27,
30
- goto fail_exit;
23
+ ARM_HWCAP_A64_SSBS = 1 << 28,
31
- }
24
+ ARM_HWCAP_A64_SB = 1 << 29,
32
- } else if (s->sve_excp_el) {
25
+ ARM_HWCAP_A64_PACA = 1 << 30,
33
+ ret = sme_sm_enabled_check(s);
26
+ ARM_HWCAP_A64_PACG = 1UL << 31,
34
+ s->sve_access_checked = (ret ? 1 : -1);
27
};
35
+ return ret;
28
36
+ }
29
#define ELF_HWCAP get_elf_hwcap()
37
+ if (s->sve_excp_el) {
38
+ /* Assert that we only raise one exception per instruction. */
39
+ assert(!s->sve_access_checked);
40
gen_exception_insn_el(s, 0, EXCP_UDEF,
41
syn_sve_access_trap(), s->sve_excp_el);
42
- goto fail_exit;
43
+ s->sve_access_checked = -1;
44
+ return false;
45
}
46
s->sve_access_checked = 1;
47
return fp_access_check(s);
48
-
49
- fail_exit:
50
- /* Assert that we only raise one exception per instruction. */
51
- assert(!s->sve_access_checked);
52
- s->sve_access_checked = -1;
53
- return false;
54
}
55
56
/*
30
--
57
--
31
2.20.1
58
2.43.0
32
33
diff view generated by jsdifflib
1
Rename various internal uses of 'iotkit' in hw/arm/iotkit.c to
1
We want to capture potential Rust backtraces on panics in our test
2
'armsse', for consistency. The remaining occurences are:
2
logs, which isn't Rust's default behaviour. Set RUST_BACKTRACE=1 in
3
* related to the devices TYPE_IOTKIT_SYSCTL, TYPE_IOTKIT_SYSINFO,
3
the add_test_setup environments, so that all our tests get run with
4
etc, which this refactor is not touching
4
this environment variable set.
5
* references that apply specifically to the IoTKit (like
5
6
the lack of a private CPU region)
6
This makes the setting of that variable in the gitlab CI template
7
* the vmstate, which keeps its old "iotkit" name for
7
redundant, so we can remove it.
8
migration compatibility reasons
9
8
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20190121185118.18550-7-peter.maydell@linaro.org
12
Message-id: 20250310102950.3752908-1-peter.maydell@linaro.org
14
---
13
---
15
hw/arm/iotkit.c | 68 ++++++++++++++++++++++++-------------------------
14
meson.build | 9 ++++++---
16
1 file changed, 34 insertions(+), 34 deletions(-)
15
.gitlab-ci.d/buildtest-template.yml | 1 -
16
2 files changed, 6 insertions(+), 4 deletions(-)
17
17
18
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
18
diff --git a/meson.build b/meson.build
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/iotkit.c
20
--- a/meson.build
21
+++ b/hw/arm/iotkit.c
21
+++ b/meson.build
22
@@ -XXX,XX +XXX,XX @@ static void nsccfg_handler(void *opaque, int n, int level)
22
@@ -XXX,XX +XXX,XX @@ project('qemu', ['c'], meson_version: '>=1.5.0',
23
s->nsccfg = level;
23
24
}
24
meson.add_devenv({ 'MESON_BUILD_ROOT' : meson.project_build_root() })
25
25
26
-static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
26
-add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true)
27
+static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
27
-add_test_setup('slow', exclude_suites: ['thorough'], env: ['G_TEST_SLOW=1', 'SPEED=slow'])
28
{
28
-add_test_setup('thorough', env: ['G_TEST_SLOW=1', 'SPEED=thorough'])
29
/* Each of the 4 AHB and 4 APB PPCs that might be present in a
29
+add_test_setup('quick', exclude_suites: ['slow', 'thorough'], is_default: true,
30
* system using the ARMSSE has a collection of control lines which
30
+ env: ['RUST_BACKTRACE=1'])
31
@@ -XXX,XX +XXX,XX @@ static void iotkit_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
31
+add_test_setup('slow', exclude_suites: ['thorough'],
32
* code using the ARMSSE can wire them up to the PPCs.
32
+ env: ['G_TEST_SLOW=1', 'SPEED=slow', 'RUST_BACKTRACE=1'])
33
*/
33
+add_test_setup('thorough',
34
SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
34
+ env: ['G_TEST_SLOW=1', 'SPEED=thorough', 'RUST_BACKTRACE=1'])
35
- DeviceState *iotkitdev = DEVICE(s);
35
36
+ DeviceState *armssedev = DEVICE(s);
36
meson.add_postconf_script(find_program('scripts/symlink-install-tree.py'))
37
DeviceState *dev_secctl = DEVICE(&s->secctl);
37
38
DeviceState *dev_splitter = DEVICE(splitter);
38
diff --git a/.gitlab-ci.d/buildtest-template.yml b/.gitlab-ci.d/buildtest-template.yml
39
char *name;
39
index XXXXXXX..XXXXXXX 100644
40
40
--- a/.gitlab-ci.d/buildtest-template.yml
41
name = g_strdup_printf("%s_nonsec", ppcname);
41
+++ b/.gitlab-ci.d/buildtest-template.yml
42
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
42
@@ -XXX,XX +XXX,XX @@
43
+ qdev_pass_gpios(dev_secctl, armssedev, name);
43
stage: test
44
g_free(name);
44
image: $CI_REGISTRY_IMAGE/qemu/$IMAGE:$QEMU_CI_CONTAINER_TAG
45
name = g_strdup_printf("%s_ap", ppcname);
45
script:
46
- qdev_pass_gpios(dev_secctl, iotkitdev, name);
46
- - export RUST_BACKTRACE=1
47
+ qdev_pass_gpios(dev_secctl, armssedev, name);
47
- source scripts/ci/gitlab-ci-section
48
g_free(name);
48
- section_start buildenv "Setting up to run tests"
49
name = g_strdup_printf("%s_irq_enable", ppcname);
49
- scripts/git-submodule.sh update roms/SLOF
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
--
50
--
255
2.20.1
51
2.43.0
256
52
257
53
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has four banks of SRAM, each with its own
2
Memory Protection Controller, where the IoTKit has only one.
3
Make the number of SRAM banks a field in ARMSSEInfo.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-10-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 9 +++--
10
hw/arm/armsse.c | 78 ++++++++++++++++++++++++++---------------
11
2 files changed, 56 insertions(+), 31 deletions(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
19
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
20
21
+#define MAX_SRAM_BANKS 4
22
+#if MAX_SRAM_BANKS > IOTS_NUM_MPC
23
+#error Too many SRAM banks
24
+#endif
25
+
26
typedef struct ARMSSE {
27
/*< private >*/
28
SysBusDevice parent_obj;
29
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
30
IoTKitSecCtl secctl;
31
TZPPC apb_ppc0;
32
TZPPC apb_ppc1;
33
- TZMPC mpc;
34
+ TZMPC mpc[IOTS_NUM_MPC];
35
CMSDKAPBTIMER timer0;
36
CMSDKAPBTIMER timer1;
37
CMSDKAPBTIMER s32ktimer;
38
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
39
MemoryRegion alias1;
40
MemoryRegion alias2;
41
MemoryRegion alias3;
42
- MemoryRegion sram0;
43
+ MemoryRegion sram[MAX_SRAM_BANKS];
44
45
qemu_irq *exp_irqs;
46
qemu_irq ppc0_irq;
47
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/armsse.c
50
+++ b/hw/arm/armsse.c
51
@@ -XXX,XX +XXX,XX @@
52
53
struct ARMSSEInfo {
54
const char *name;
55
+ int sram_banks;
56
};
57
58
static const ARMSSEInfo armsse_variants[] = {
59
{
60
.name = TYPE_IOTKIT,
61
+ .sram_banks = 1,
62
},
63
};
64
65
@@ -XXX,XX +XXX,XX @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
66
static void armsse_init(Object *obj)
67
{
68
ARMSSE *s = ARMSSE(obj);
69
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
70
+ const ARMSSEInfo *info = asc->info;
71
int i;
72
73
+ assert(info->sram_banks <= MAX_SRAM_BANKS);
74
+
75
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
76
77
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
78
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
79
TYPE_TZ_PPC);
80
sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
81
TYPE_TZ_PPC);
82
- sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
83
+ for (i = 0; i < info->sram_banks; i++) {
84
+ char *name = g_strdup_printf("mpc%d", i);
85
+ sysbus_init_child_obj(obj, name, &s->mpc[i],
86
+ sizeof(s->mpc[i]), TYPE_TZ_MPC);
87
+ g_free(name);
88
+ }
89
object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
90
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
91
&error_abort, NULL);
92
93
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
94
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
95
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
96
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
97
98
@@ -XXX,XX +XXX,XX @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
99
static void armsse_realize(DeviceState *dev, Error **errp)
100
{
101
ARMSSE *s = ARMSSE(dev);
102
+ ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
103
+ const ARMSSEInfo *info = asc->info;
104
int i;
105
MemoryRegion *mr;
106
Error *err = NULL;
107
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
108
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
109
qdev_get_gpio_in(dev_splitter, 0));
110
111
- /* This RAM lives behind the Memory Protection Controller */
112
- memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
113
- if (err) {
114
- error_propagate(errp, err);
115
- return;
116
+ /* Each SRAM bank lives behind its own Memory Protection Controller */
117
+ for (i = 0; i < info->sram_banks; i++) {
118
+ char *ramname = g_strdup_printf("armsse.sram%d", i);
119
+ SysBusDevice *sbd_mpc;
120
+
121
+ memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
122
+ g_free(ramname);
123
+ if (err) {
124
+ error_propagate(errp, err);
125
+ return;
126
+ }
127
+ object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
128
+ "downstream", &err);
129
+ if (err) {
130
+ error_propagate(errp, err);
131
+ return;
132
+ }
133
+ object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
134
+ if (err) {
135
+ error_propagate(errp, err);
136
+ return;
137
+ }
138
+ /* Map the upstream end of the MPC into the right place... */
139
+ sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
140
+ memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
141
+ sysbus_mmio_get_region(sbd_mpc, 1));
142
+ /* ...and its register interface */
143
+ memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
144
+ sysbus_mmio_get_region(sbd_mpc, 0));
145
}
146
- object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
147
- "downstream", &err);
148
- if (err) {
149
- error_propagate(errp, err);
150
- return;
151
- }
152
- object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
153
- if (err) {
154
- error_propagate(errp, err);
155
- return;
156
- }
157
- /* Map the upstream end of the MPC into the right place... */
158
- memory_region_add_subregion(&s->container, 0x20000000,
159
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
160
- 1));
161
- /* ...and its register interface */
162
- memory_region_add_subregion(&s->container, 0x50083000,
163
- sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
164
- 0));
165
166
/* We must OR together lines from the MPC splitters to go to the NVIC */
167
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
168
- IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
169
+ IOTS_NUM_EXP_MPC + info->sram_banks,
170
+ "num-lines", &err);
171
if (err) {
172
error_propagate(errp, err);
173
return;
174
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
175
}
176
177
/* Wire up the splitters for the MPC IRQs */
178
- for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
179
+ for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
180
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
181
DeviceState *dev_splitter = DEVICE(splitter);
182
183
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
184
"mpcexp_status", i));
185
} else {
186
/* Splitter input is from our own MPC */
187
- qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
188
+ qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
189
+ "irq", 0,
190
qdev_get_gpio_in(dev_splitter, 0));
191
qdev_connect_gpio_out(dev_splitter, 0,
192
qdev_get_gpio_in_named(dev_secctl,
193
--
194
2.20.1
195
196
diff view generated by jsdifflib
Deleted patch
1
Create a cluster object to hold each CPU in the SSE. They are
2
logically distinct and may be configured differently (for instance
3
one may not have an FPU where the other does).
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-14-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 2 ++
10
hw/arm/armsse.c | 31 ++++++++++++++++++++++++++++---
11
2 files changed, 30 insertions(+), 3 deletions(-)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/misc/iotkit-sysinfo.h"
19
#include "hw/or-irq.h"
20
#include "hw/core/split-irq.h"
21
+#include "hw/cpu/cluster.h"
22
23
#define TYPE_ARMSSE "arm-sse"
24
#define ARMSSE(obj) OBJECT_CHECK(ARMSSE, (obj), TYPE_ARMSSE)
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
27
/*< public >*/
28
ARMv7MState armv7m[SSE_MAX_CPUS];
29
+ CPUClusterState cluster[SSE_MAX_CPUS];
30
IoTKitSecCtl secctl;
31
TZPPC apb_ppc0;
32
TZPPC apb_ppc1;
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
38
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
39
40
for (i = 0; i < info->num_cpus; i++) {
41
- char *name = g_strdup_printf("armv7m%d", i);
42
- sysbus_init_child_obj(obj, name, &s->armv7m[i], sizeof(s->armv7m),
43
- TYPE_ARMV7M);
44
+ /*
45
+ * We put each CPU in its own cluster as they are logically
46
+ * distinct and may be configured differently.
47
+ */
48
+ char *name;
49
+
50
+ name = g_strdup_printf("cluster%d", i);
51
+ object_initialize_child(obj, name, &s->cluster[i],
52
+ sizeof(s->cluster[i]), TYPE_CPU_CLUSTER,
53
+ &error_abort, NULL);
54
+ qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
55
+ g_free(name);
56
+
57
+ name = g_strdup_printf("armv7m%d", i);
58
+ sysbus_init_child_obj(OBJECT(&s->cluster[i]), name,
59
+ &s->armv7m[i], sizeof(s->armv7m), TYPE_ARMV7M);
60
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
61
ARM_CPU_TYPE_NAME("cortex-m33"));
62
g_free(name);
63
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
64
error_propagate(errp, err);
65
return;
66
}
67
+ /*
68
+ * The cluster must be realized after the armv7m container, as
69
+ * the container's CPU object is only created on realize, and the
70
+ * CPU must exist and have been parented into the cluster before
71
+ * the cluster is realized.
72
+ */
73
+ object_property_set_bool(OBJECT(&s->cluster[i]),
74
+ true, "realized", &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
80
/* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
81
s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
Deleted patch
1
The SYS_VERSION and SYS_CONFIG register values differ between the
2
IoTKit and SSE-200. Make them configurable via QOM properties rather
3
than hard-coded, and set them appropriately in the ARMSSE code that
4
instantiates the IOTKIT_SYSINFO device.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-15-peter.maydell@linaro.org
9
---
10
include/hw/misc/iotkit-sysinfo.h | 6 ++++
11
hw/arm/armsse.c | 51 ++++++++++++++++++++++++++++++++
12
hw/misc/iotkit-sysinfo.c | 15 ++++++++--
13
3 files changed, 70 insertions(+), 2 deletions(-)
14
15
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/iotkit-sysinfo.h
18
+++ b/include/hw/misc/iotkit-sysinfo.h
19
@@ -XXX,XX +XXX,XX @@
20
* Arm IoTKit and documented in
21
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
22
* QEMU interface:
23
+ * + QOM property "SYS_VERSION": value to use for SYS_VERSION register
24
+ * + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
25
* + sysbus MMIO region 0: the system information register bank
26
*/
27
28
@@ -XXX,XX +XXX,XX @@ typedef struct IoTKitSysInfo {
29
30
/*< public >*/
31
MemoryRegion iomem;
32
+
33
+ /* Properties */
34
+ uint32_t sys_version;
35
+ uint32_t sys_config;
36
} IoTKitSysInfo;
37
38
#endif
39
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/armsse.c
42
+++ b/hw/arm/armsse.c
43
@@ -XXX,XX +XXX,XX @@
44
#include "hw/arm/armsse.h"
45
#include "hw/arm/arm.h"
46
47
+/* Format of the System Information block SYS_CONFIG register */
48
+typedef enum SysConfigFormat {
49
+ IoTKitFormat,
50
+ SSE200Format,
51
+} SysConfigFormat;
52
+
53
struct ARMSSEInfo {
54
const char *name;
55
int sram_banks;
56
int num_cpus;
57
+ uint32_t sys_version;
58
+ SysConfigFormat sys_config_format;
59
};
60
61
static const ARMSSEInfo armsse_variants[] = {
62
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
63
.name = TYPE_IOTKIT,
64
.sram_banks = 1,
65
.num_cpus = 1,
66
+ .sys_version = 0x41743,
67
+ .sys_config_format = IoTKitFormat,
68
},
69
};
70
71
+static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
72
+{
73
+ /* Return the SYS_CONFIG value for this SSE */
74
+ uint32_t sys_config;
75
+
76
+ switch (info->sys_config_format) {
77
+ case IoTKitFormat:
78
+ sys_config = 0;
79
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
80
+ sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
81
+ break;
82
+ case SSE200Format:
83
+ sys_config = 0;
84
+ sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
85
+ sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
86
+ sys_config = deposit32(sys_config, 24, 4, 2);
87
+ if (info->num_cpus > 1) {
88
+ sys_config = deposit32(sys_config, 10, 1, 1);
89
+ sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
90
+ sys_config = deposit32(sys_config, 28, 4, 2);
91
+ }
92
+ break;
93
+ default:
94
+ g_assert_not_reached();
95
+ }
96
+ return sys_config;
97
+}
98
+
99
/* Clock frequency in HZ of the 32KHz "slow clock" */
100
#define S32KCLK (32 * 1000)
101
102
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
103
qdev_get_gpio_in_named(dev_apb_ppc1,
104
"cfg_sec_resp", 0));
105
106
+ object_property_set_int(OBJECT(&s->sysinfo), info->sys_version,
107
+ "SYS_VERSION", &err);
108
+ if (err) {
109
+ error_propagate(errp, err);
110
+ return;
111
+ }
112
+ object_property_set_int(OBJECT(&s->sysinfo),
113
+ armsse_sys_config_value(s, info),
114
+ "SYS_CONFIG", &err);
115
+ if (err) {
116
+ error_propagate(errp, err);
117
+ return;
118
+ }
119
object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err);
120
if (err) {
121
error_propagate(errp, err);
122
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/misc/iotkit-sysinfo.c
125
+++ b/hw/misc/iotkit-sysinfo.c
126
@@ -XXX,XX +XXX,XX @@ static const int sysinfo_id[] = {
127
static uint64_t iotkit_sysinfo_read(void *opaque, hwaddr offset,
128
unsigned size)
129
{
130
+ IoTKitSysInfo *s = IOTKIT_SYSINFO(opaque);
131
uint64_t r;
132
133
switch (offset) {
134
case A_SYS_VERSION:
135
- r = 0x41743;
136
+ r = s->sys_version;
137
break;
138
139
case A_SYS_CONFIG:
140
- r = 0x31;
141
+ r = s->sys_config;
142
break;
143
case A_PID4 ... A_CID3:
144
r = sysinfo_id[(offset - A_PID4) / 4];
145
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps iotkit_sysinfo_ops = {
146
.valid.max_access_size = 4,
147
};
148
149
+static Property iotkit_sysinfo_props[] = {
150
+ DEFINE_PROP_UINT32("SYS_VERSION", IoTKitSysInfo, sys_version, 0),
151
+ DEFINE_PROP_UINT32("SYS_CONFIG", IoTKitSysInfo, sys_config, 0),
152
+ DEFINE_PROP_END_OF_LIST()
153
+};
154
+
155
static void iotkit_sysinfo_init(Object *obj)
156
{
157
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
158
@@ -XXX,XX +XXX,XX @@ static void iotkit_sysinfo_init(Object *obj)
159
160
static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data)
161
{
162
+ DeviceClass *dc = DEVICE_CLASS(klass);
163
+
164
/*
165
* This device has no guest-modifiable state and so it
166
* does not need a reset function or VMState.
167
*/
168
+
169
+ dc->props = iotkit_sysinfo_props;
170
}
171
172
static const TypeInfo iotkit_sysinfo_info = {
173
--
174
2.20.1
175
176
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has two Message Handling Units (MHUs), which sit behind
2
the APB PPC0. Wire up some unimplemented-device stubs for these,
3
since we don't yet implement a real model of this device.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190121185118.18550-16-peter.maydell@linaro.org
8
---
9
include/hw/arm/armsse.h | 3 +++
10
hw/arm/armsse.c | 41 +++++++++++++++++++++++++++++++++++++++++
11
2 files changed, 44 insertions(+)
12
13
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/armsse.h
16
+++ b/include/hw/arm/armsse.h
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/watchdog/cmsdk-apb-watchdog.h"
19
#include "hw/misc/iotkit-sysctl.h"
20
#include "hw/misc/iotkit-sysinfo.h"
21
+#include "hw/misc/unimp.h"
22
#include "hw/or-irq.h"
23
#include "hw/core/split-irq.h"
24
#include "hw/cpu/cluster.h"
25
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
26
IoTKitSysCtl sysctl;
27
IoTKitSysCtl sysinfo;
28
29
+ UnimplementedDeviceState mhu[2];
30
+
31
/*
32
* 'container' holds all devices seen by all CPUs.
33
* 'cpu_container[i]' is the view that CPU i has: this has the
34
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/armsse.c
37
+++ b/hw/arm/armsse.c
38
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
39
int num_cpus;
40
uint32_t sys_version;
41
SysConfigFormat sys_config_format;
42
+ bool has_mhus;
43
};
44
45
static const ARMSSEInfo armsse_variants[] = {
46
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
47
.num_cpus = 1,
48
.sys_version = 0x41743,
49
.sys_config_format = IoTKitFormat,
50
+ .has_mhus = false,
51
},
52
};
53
54
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
55
sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL);
56
sysbus_init_child_obj(obj, "armsse-sysinfo", &s->sysinfo,
57
sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO);
58
+ if (info->has_mhus) {
59
+ sysbus_init_child_obj(obj, "mhu0", &s->mhu[0], sizeof(s->mhu[0]),
60
+ TYPE_UNIMPLEMENTED_DEVICE);
61
+ sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
62
+ TYPE_UNIMPLEMENTED_DEVICE);
63
+ }
64
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
65
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
66
&error_abort, NULL);
67
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
68
* 0x40000000: timer0
69
* 0x40001000: timer1
70
* 0x40002000: dual timer
71
+ * 0x40003000: MHU0 (SSE-200 only)
72
+ * 0x40004000: MHU1 (SSE-200 only)
73
* We must configure and realize each downstream device and connect
74
* it to the appropriate PPC port; then we can realize the PPC and
75
* map its upstream ends to the right place in the container.
76
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
77
return;
78
}
79
80
+ if (info->has_mhus) {
81
+ for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
82
+ char *name = g_strdup_printf("MHU%d", i);
83
+ char *port = g_strdup_printf("port[%d]", i + 3);
84
+
85
+ qdev_prop_set_string(DEVICE(&s->mhu[i]), "name", name);
86
+ qdev_prop_set_uint64(DEVICE(&s->mhu[i]), "size", 0x1000);
87
+ object_property_set_bool(OBJECT(&s->mhu[i]), true,
88
+ "realized", &err);
89
+ if (err) {
90
+ error_propagate(errp, err);
91
+ return;
92
+ }
93
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mhu[i]), 0);
94
+ object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr),
95
+ port, &err);
96
+ if (err) {
97
+ error_propagate(errp, err);
98
+ return;
99
+ }
100
+ g_free(name);
101
+ g_free(port);
102
+ }
103
+ }
104
+
105
object_property_set_bool(OBJECT(&s->apb_ppc0), true, "realized", &err);
106
if (err) {
107
error_propagate(errp, err);
108
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
109
memory_region_add_subregion(&s->container, 0x40001000, mr);
110
mr = sysbus_mmio_get_region(sbd_apb_ppc0, 2);
111
memory_region_add_subregion(&s->container, 0x40002000, mr);
112
+ if (info->has_mhus) {
113
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
114
+ memory_region_add_subregion(&s->container, 0x40003000, mr);
115
+ mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
116
+ memory_region_add_subregion(&s->container, 0x40004000, mr);
117
+ }
118
for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
119
qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
120
qdev_get_gpio_in_named(dev_apb_ppc0,
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
Add unimplemented-device stubs for the various Power Policy Unit
2
devices that the SSE-200 has.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-17-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 11 ++++++++
9
hw/arm/armsse.c | 58 +++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 69 insertions(+)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
18
#define SSE_MAX_CPUS 2
19
20
+/* These define what each PPU in the ppu[] index is for */
21
+#define CPU0CORE_PPU 0
22
+#define CPU1CORE_PPU 1
23
+#define DBG_PPU 2
24
+#define RAM0_PPU 3
25
+#define RAM1_PPU 4
26
+#define RAM2_PPU 5
27
+#define RAM3_PPU 6
28
+#define NUM_PPUS 7
29
+
30
typedef struct ARMSSE {
31
/*< private >*/
32
SysBusDevice parent_obj;
33
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
34
IoTKitSysCtl sysinfo;
35
36
UnimplementedDeviceState mhu[2];
37
+ UnimplementedDeviceState ppu[NUM_PPUS];
38
39
/*
40
* 'container' holds all devices seen by all CPUs.
41
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/armsse.c
44
+++ b/hw/arm/armsse.c
45
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
46
uint32_t sys_version;
47
SysConfigFormat sys_config_format;
48
bool has_mhus;
49
+ bool has_ppus;
50
};
51
52
static const ARMSSEInfo armsse_variants[] = {
53
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
54
.sys_version = 0x41743,
55
.sys_config_format = IoTKitFormat,
56
.has_mhus = false,
57
+ .has_ppus = false,
58
},
59
};
60
61
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
62
sysbus_init_child_obj(obj, "mhu1", &s->mhu[1], sizeof(s->mhu[1]),
63
TYPE_UNIMPLEMENTED_DEVICE);
64
}
65
+ if (info->has_ppus) {
66
+ for (i = 0; i < info->num_cpus; i++) {
67
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
68
+ int ppuidx = CPU0CORE_PPU + i;
69
+
70
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
71
+ sizeof(s->ppu[ppuidx]),
72
+ TYPE_UNIMPLEMENTED_DEVICE);
73
+ g_free(name);
74
+ }
75
+ sysbus_init_child_obj(obj, "DBG_PPU", &s->ppu[DBG_PPU],
76
+ sizeof(s->ppu[DBG_PPU]),
77
+ TYPE_UNIMPLEMENTED_DEVICE);
78
+ for (i = 0; i < info->sram_banks; i++) {
79
+ char *name = g_strdup_printf("RAM%d_PPU", i);
80
+ int ppuidx = RAM0_PPU + i;
81
+
82
+ sysbus_init_child_obj(obj, name, &s->ppu[ppuidx],
83
+ sizeof(s->ppu[ppuidx]),
84
+ TYPE_UNIMPLEMENTED_DEVICE);
85
+ g_free(name);
86
+ }
87
+ }
88
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
89
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
90
&error_abort, NULL);
91
@@ -XXX,XX +XXX,XX @@ static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
92
}
93
}
94
95
+static void map_ppu(ARMSSE *s, int ppuidx, const char *name, hwaddr addr)
96
+{
97
+ /* Map a PPU unimplemented device stub */
98
+ DeviceState *dev = DEVICE(&s->ppu[ppuidx]);
99
+
100
+ qdev_prop_set_string(dev, "name", name);
101
+ qdev_prop_set_uint64(dev, "size", 0x1000);
102
+ qdev_init_nofail(dev);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ppu[ppuidx]), 0, addr);
104
+}
105
+
106
static void armsse_realize(DeviceState *dev, Error **errp)
107
{
108
ARMSSE *s = ARMSSE(dev);
109
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
110
}
111
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000);
112
113
+ if (info->has_ppus) {
114
+ /* CPUnCORE_PPU for each CPU */
115
+ for (i = 0; i < info->num_cpus; i++) {
116
+ char *name = g_strdup_printf("CPU%dCORE_PPU", i);
117
+
118
+ map_ppu(s, CPU0CORE_PPU + i, name, 0x50023000 + i * 0x2000);
119
+ /*
120
+ * We don't support CPU debug so don't create the
121
+ * CPU0DEBUG_PPU at 0x50024000 and 0x50026000.
122
+ */
123
+ g_free(name);
124
+ }
125
+ map_ppu(s, DBG_PPU, "DBG_PPU", 0x50029000);
126
+
127
+ for (i = 0; i < info->sram_banks; i++) {
128
+ char *name = g_strdup_printf("RAM%d_PPU", i);
129
+
130
+ map_ppu(s, RAM0_PPU + i, name, 0x5002a000 + i * 0x1000);
131
+ g_free(name);
132
+ }
133
+ }
134
+
135
/* This OR gate wires together outputs from the secure watchdogs to NMI */
136
object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err);
137
if (err) {
138
--
139
2.20.1
140
141
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 gives each CPU a register bank to use to control its
2
L1 instruction cache. Put in an unimplemented-device stub for this.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-18-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 1 +
9
hw/arm/armsse.c | 39 ++++++++++++++++++++++++++++++++++++++-
10
2 files changed, 39 insertions(+), 1 deletion(-)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
17
18
UnimplementedDeviceState mhu[2];
19
UnimplementedDeviceState ppu[NUM_PPUS];
20
+ UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
21
22
/*
23
* 'container' holds all devices seen by all CPUs.
24
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/armsse.c
27
+++ b/hw/arm/armsse.c
28
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
29
SysConfigFormat sys_config_format;
30
bool has_mhus;
31
bool has_ppus;
32
+ bool has_cachectrl;
33
};
34
35
static const ARMSSEInfo armsse_variants[] = {
36
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
37
.sys_config_format = IoTKitFormat,
38
.has_mhus = false,
39
.has_ppus = false,
40
+ .has_cachectrl = false,
41
},
42
};
43
44
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
45
g_free(name);
46
}
47
}
48
+ if (info->has_cachectrl) {
49
+ for (i = 0; i < info->num_cpus; i++) {
50
+ char *name = g_strdup_printf("cachectrl%d", i);
51
+
52
+ sysbus_init_child_obj(obj, name, &s->cachectrl[i],
53
+ sizeof(s->cachectrl[i]),
54
+ TYPE_UNIMPLEMENTED_DEVICE);
55
+ g_free(name);
56
+ }
57
+ }
58
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
59
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
60
&error_abort, NULL);
61
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
62
qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
63
armsse_get_common_irq_in(s, 10));
64
65
- /* 0x40010000 .. 0x4001ffff: private CPU region: unused in IoTKit */
66
+ /*
67
+ * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
68
+ * private per-CPU region (all these devices are SSE-200 only):
69
+ * 0x50010000: L1 icache control registers
70
+ * 0x50011000: CPUSECCTRL (CPU local security control registers)
71
+ * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
72
+ */
73
+ if (info->has_cachectrl) {
74
+ for (i = 0; i < info->num_cpus; i++) {
75
+ char *name = g_strdup_printf("cachectrl%d", i);
76
+ MemoryRegion *mr;
77
+
78
+ qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
79
+ g_free(name);
80
+ qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
81
+ object_property_set_bool(OBJECT(&s->cachectrl[i]), true,
82
+ "realized", &err);
83
+ if (err) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
89
+ memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
90
+ }
91
+ }
92
93
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
94
/* Devices behind APB PPC1:
95
--
96
2.20.1
97
98
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has a "CPU local security control" register bank; add an
2
unimplemented-device stub for it. (The register bank has only one
3
interesting register, which allows the guest to lock down changes
4
to various CPU registers so they cannot be modified further. We
5
don't support that in our Cortex-M33 model anyway.)
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190121185118.18550-19-peter.maydell@linaro.org
10
---
11
include/hw/arm/armsse.h | 1 +
12
hw/arm/armsse.c | 31 +++++++++++++++++++++++++++++++
13
2 files changed, 32 insertions(+)
14
15
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/armsse.h
18
+++ b/include/hw/arm/armsse.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
20
UnimplementedDeviceState mhu[2];
21
UnimplementedDeviceState ppu[NUM_PPUS];
22
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
23
+ UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
24
25
/*
26
* 'container' holds all devices seen by all CPUs.
27
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/armsse.c
30
+++ b/hw/arm/armsse.c
31
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
32
bool has_mhus;
33
bool has_ppus;
34
bool has_cachectrl;
35
+ bool has_cpusecctrl;
36
};
37
38
static const ARMSSEInfo armsse_variants[] = {
39
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
40
.has_mhus = false,
41
.has_ppus = false,
42
.has_cachectrl = false,
43
+ .has_cpusecctrl = false,
44
},
45
};
46
47
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
48
g_free(name);
49
}
50
}
51
+ if (info->has_cpusecctrl) {
52
+ for (i = 0; i < info->num_cpus; i++) {
53
+ char *name = g_strdup_printf("cpusecctrl%d", i);
54
+
55
+ sysbus_init_child_obj(obj, name, &s->cpusecctrl[i],
56
+ sizeof(s->cpusecctrl[i]),
57
+ TYPE_UNIMPLEMENTED_DEVICE);
58
+ g_free(name);
59
+ }
60
+ }
61
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
62
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
63
&error_abort, NULL);
64
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
65
memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
66
}
67
}
68
+ if (info->has_cpusecctrl) {
69
+ for (i = 0; i < info->num_cpus; i++) {
70
+ char *name = g_strdup_printf("CPUSECCTRL%d", i);
71
+ MemoryRegion *mr;
72
+
73
+ qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
74
+ g_free(name);
75
+ qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
76
+ object_property_set_bool(OBJECT(&s->cpusecctrl[i]), true,
77
+ "realized", &err);
78
+ if (err) {
79
+ error_propagate(errp, err);
80
+ return;
81
+ }
82
+
83
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
84
+ memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
85
+ }
86
+ }
87
88
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
89
/* Devices behind APB PPC1:
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
The SSE-200 has a CPU_IDENTITY register block, which is a set of
2
read-only registers. As well as the usual PID/CID registers, there
3
is a single CPUID register which indicates whether the CPU is CPU 0
4
or CPU 1. Implement a model of this register block.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190121185118.18550-20-peter.maydell@linaro.org
9
---
10
hw/misc/Makefile.objs | 1 +
11
include/hw/misc/armsse-cpuid.h | 41 ++++++++++
12
hw/misc/armsse-cpuid.c | 134 ++++++++++++++++++++++++++++++++
13
MAINTAINERS | 2 +
14
default-configs/arm-softmmu.mak | 1 +
15
hw/misc/trace-events | 4 +
16
6 files changed, 183 insertions(+)
17
create mode 100644 include/hw/misc/armsse-cpuid.h
18
create mode 100644 hw/misc/armsse-cpuid.c
19
20
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/Makefile.objs
23
+++ b/hw/misc/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_TZ_PPC) += tz-ppc.o
25
obj-$(CONFIG_IOTKIT_SECCTL) += iotkit-secctl.o
26
obj-$(CONFIG_IOTKIT_SYSCTL) += iotkit-sysctl.o
27
obj-$(CONFIG_IOTKIT_SYSINFO) += iotkit-sysinfo.o
28
+obj-$(CONFIG_ARMSSE_CPUID) += armsse-cpuid.o
29
30
obj-$(CONFIG_PVPANIC) += pvpanic.o
31
obj-$(CONFIG_AUX) += auxbus.o
32
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/armsse-cpuid.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * ARM SSE-200 CPU_IDENTITY register block
40
+ *
41
+ * Copyright (c) 2019 Linaro Limited
42
+ * Written by Peter Maydell
43
+ *
44
+ * This program is free software; you can redistribute it and/or modify
45
+ * it under the terms of the GNU General Public License version 2 or
46
+ * (at your option) any later version.
47
+ */
48
+
49
+/*
50
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
51
+ * Arm SSE-200 and documented in
52
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ *
54
+ * QEMU interface:
55
+ * + QOM property "CPUID": the value to use for the CPUID register
56
+ * + sysbus MMIO region 0: the system information register bank
57
+ */
58
+
59
+#ifndef HW_MISC_ARMSSE_CPUID_H
60
+#define HW_MISC_ARMSSE_CPUID_H
61
+
62
+#include "hw/sysbus.h"
63
+
64
+#define TYPE_ARMSSE_CPUID "armsse-cpuid"
65
+#define ARMSSE_CPUID(obj) OBJECT_CHECK(ARMSSECPUID, (obj), TYPE_ARMSSE_CPUID)
66
+
67
+typedef struct ARMSSECPUID {
68
+ /*< private >*/
69
+ SysBusDevice parent_obj;
70
+
71
+ /*< public >*/
72
+ MemoryRegion iomem;
73
+
74
+ /* Properties */
75
+ uint32_t cpuid;
76
+} ARMSSECPUID;
77
+
78
+#endif
79
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
80
new file mode 100644
81
index XXXXXXX..XXXXXXX
82
--- /dev/null
83
+++ b/hw/misc/armsse-cpuid.c
84
@@ -XXX,XX +XXX,XX @@
85
+/*
86
+ * ARM SSE-200 CPU_IDENTITY register block
87
+ *
88
+ * Copyright (c) 2019 Linaro Limited
89
+ * Written by Peter Maydell
90
+ *
91
+ * This program is free software; you can redistribute it and/or modify
92
+ * it under the terms of the GNU General Public License version 2 or
93
+ * (at your option) any later version.
94
+ */
95
+
96
+/*
97
+ * This is a model of the "CPU_IDENTITY" register block which is part of the
98
+ * Arm SSE-200 and documented in
99
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
100
+ *
101
+ * It consists of one read-only CPUID register (set by QOM property), plus the
102
+ * usual ID registers.
103
+ */
104
+
105
+#include "qemu/osdep.h"
106
+#include "qemu/log.h"
107
+#include "trace.h"
108
+#include "qapi/error.h"
109
+#include "sysemu/sysemu.h"
110
+#include "hw/sysbus.h"
111
+#include "hw/registerfields.h"
112
+#include "hw/misc/armsse-cpuid.h"
113
+
114
+REG32(CPUID, 0x0)
115
+REG32(PID4, 0xfd0)
116
+REG32(PID5, 0xfd4)
117
+REG32(PID6, 0xfd8)
118
+REG32(PID7, 0xfdc)
119
+REG32(PID0, 0xfe0)
120
+REG32(PID1, 0xfe4)
121
+REG32(PID2, 0xfe8)
122
+REG32(PID3, 0xfec)
123
+REG32(CID0, 0xff0)
124
+REG32(CID1, 0xff4)
125
+REG32(CID2, 0xff8)
126
+REG32(CID3, 0xffc)
127
+
128
+/* PID/CID values */
129
+static const int sysinfo_id[] = {
130
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
131
+ 0x58, 0xb8, 0x0b, 0x00, /* PID0..PID3 */
132
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
133
+};
134
+
135
+static uint64_t armsse_cpuid_read(void *opaque, hwaddr offset,
136
+ unsigned size)
137
+{
138
+ ARMSSECPUID *s = ARMSSE_CPUID(opaque);
139
+ uint64_t r;
140
+
141
+ switch (offset) {
142
+ case A_CPUID:
143
+ r = s->cpuid;
144
+ break;
145
+ case A_PID4 ... A_CID3:
146
+ r = sysinfo_id[(offset - A_PID4) / 4];
147
+ break;
148
+ default:
149
+ qemu_log_mask(LOG_GUEST_ERROR,
150
+ "SSE CPU_IDENTITY read: bad offset 0x%x\n", (int)offset);
151
+ r = 0;
152
+ break;
153
+ }
154
+ trace_armsse_cpuid_read(offset, r, size);
155
+ return r;
156
+}
157
+
158
+static void armsse_cpuid_write(void *opaque, hwaddr offset,
159
+ uint64_t value, unsigned size)
160
+{
161
+ trace_armsse_cpuid_write(offset, value, size);
162
+
163
+ qemu_log_mask(LOG_GUEST_ERROR,
164
+ "SSE CPU_IDENTITY: write to RO offset 0x%x\n", (int)offset);
165
+}
166
+
167
+static const MemoryRegionOps armsse_cpuid_ops = {
168
+ .read = armsse_cpuid_read,
169
+ .write = armsse_cpuid_write,
170
+ .endianness = DEVICE_LITTLE_ENDIAN,
171
+ /* byte/halfword accesses are just zero-padded on reads and writes */
172
+ .impl.min_access_size = 4,
173
+ .impl.max_access_size = 4,
174
+ .valid.min_access_size = 1,
175
+ .valid.max_access_size = 4,
176
+};
177
+
178
+static Property armsse_cpuid_props[] = {
179
+ DEFINE_PROP_UINT32("CPUID", ARMSSECPUID, cpuid, 0),
180
+ DEFINE_PROP_END_OF_LIST()
181
+};
182
+
183
+static void armsse_cpuid_init(Object *obj)
184
+{
185
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
186
+ ARMSSECPUID *s = ARMSSE_CPUID(obj);
187
+
188
+ memory_region_init_io(&s->iomem, obj, &armsse_cpuid_ops,
189
+ s, "armsse-cpuid", 0x1000);
190
+ sysbus_init_mmio(sbd, &s->iomem);
191
+}
192
+
193
+static void armsse_cpuid_class_init(ObjectClass *klass, void *data)
194
+{
195
+ DeviceClass *dc = DEVICE_CLASS(klass);
196
+
197
+ /*
198
+ * This device has no guest-modifiable state and so it
199
+ * does not need a reset function or VMState.
200
+ */
201
+
202
+ dc->props = armsse_cpuid_props;
203
+}
204
+
205
+static const TypeInfo armsse_cpuid_info = {
206
+ .name = TYPE_ARMSSE_CPUID,
207
+ .parent = TYPE_SYS_BUS_DEVICE,
208
+ .instance_size = sizeof(ARMSSECPUID),
209
+ .instance_init = armsse_cpuid_init,
210
+ .class_init = armsse_cpuid_class_init,
211
+};
212
+
213
+static void armsse_cpuid_register_types(void)
214
+{
215
+ type_register_static(&armsse_cpuid_info);
216
+}
217
+
218
+type_init(armsse_cpuid_register_types);
219
diff --git a/MAINTAINERS b/MAINTAINERS
220
index XXXXXXX..XXXXXXX 100644
221
--- a/MAINTAINERS
222
+++ b/MAINTAINERS
223
@@ -XXX,XX +XXX,XX @@ F: hw/misc/iotkit-sysctl.c
224
F: include/hw/misc/iotkit-sysctl.h
225
F: hw/misc/iotkit-sysinfo.c
226
F: include/hw/misc/iotkit-sysinfo.h
227
+F: hw/misc/armsse-cpuid.c
228
+F: include/hw/misc/armsse-cpuid.h
229
230
Musicpal
231
M: Jan Kiszka <jan.kiszka@web.de>
232
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
233
index XXXXXXX..XXXXXXX 100644
234
--- a/default-configs/arm-softmmu.mak
235
+++ b/default-configs/arm-softmmu.mak
236
@@ -XXX,XX +XXX,XX @@ CONFIG_ARMSSE=y
237
CONFIG_IOTKIT_SECCTL=y
238
CONFIG_IOTKIT_SYSCTL=y
239
CONFIG_IOTKIT_SYSINFO=y
240
+CONFIG_ARMSSE_CPUID=y
241
242
CONFIG_VERSATILE=y
243
CONFIG_VERSATILE_PCI=y
244
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
245
index XXXXXXX..XXXXXXX 100644
246
--- a/hw/misc/trace-events
247
+++ b/hw/misc/trace-events
248
@@ -XXX,XX +XXX,XX @@ iotkit_sysinfo_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysI
249
iotkit_sysctl_read(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
250
iotkit_sysctl_write(uint64_t offset, uint64_t data, unsigned size) "IoTKit SysCtl write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
251
iotkit_sysctl_reset(void) "IoTKit SysCtl: reset"
252
+
253
+# hw/misc/armsse-cpuid.c
254
+armsse_cpuid_read(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
255
+armsse_cpuid_write(uint64_t offset, uint64_t data, unsigned size) "SSE-200 CPU_IDENTITY write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
Deleted patch
1
Instantiate a copy of the CPU_IDENTITY register block for each CPU
2
in an SSE-200.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-21-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 3 +++
9
hw/arm/armsse.c | 28 ++++++++++++++++++++++++++++
10
2 files changed, 31 insertions(+)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/watchdog/cmsdk-apb-watchdog.h"
18
#include "hw/misc/iotkit-sysctl.h"
19
#include "hw/misc/iotkit-sysinfo.h"
20
+#include "hw/misc/armsse-cpuid.h"
21
#include "hw/misc/unimp.h"
22
#include "hw/or-irq.h"
23
#include "hw/core/split-irq.h"
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMSSE {
25
UnimplementedDeviceState cachectrl[SSE_MAX_CPUS];
26
UnimplementedDeviceState cpusecctrl[SSE_MAX_CPUS];
27
28
+ ARMSSECPUID cpuid[SSE_MAX_CPUS];
29
+
30
/*
31
* 'container' holds all devices seen by all CPUs.
32
* 'cpu_container[i]' is the view that CPU i has: this has the
33
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/armsse.c
36
+++ b/hw/arm/armsse.c
37
@@ -XXX,XX +XXX,XX @@ struct ARMSSEInfo {
38
bool has_ppus;
39
bool has_cachectrl;
40
bool has_cpusecctrl;
41
+ bool has_cpuid;
42
};
43
44
static const ARMSSEInfo armsse_variants[] = {
45
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
46
.has_ppus = false,
47
.has_cachectrl = false,
48
.has_cpusecctrl = false,
49
+ .has_cpuid = false,
50
},
51
};
52
53
@@ -XXX,XX +XXX,XX @@ static void armsse_init(Object *obj)
54
g_free(name);
55
}
56
}
57
+ if (info->has_cpuid) {
58
+ for (i = 0; i < info->num_cpus; i++) {
59
+ char *name = g_strdup_printf("cpuid%d", i);
60
+
61
+ sysbus_init_child_obj(obj, name, &s->cpuid[i],
62
+ sizeof(s->cpuid[i]),
63
+ TYPE_ARMSSE_CPUID);
64
+ g_free(name);
65
+ }
66
+ }
67
object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate,
68
sizeof(s->nmi_orgate), TYPE_OR_IRQ,
69
&error_abort, NULL);
70
@@ -XXX,XX +XXX,XX @@ static void armsse_realize(DeviceState *dev, Error **errp)
71
memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
72
}
73
}
74
+ if (info->has_cpuid) {
75
+ for (i = 0; i < info->num_cpus; i++) {
76
+ MemoryRegion *mr;
77
+
78
+ qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
79
+ object_property_set_bool(OBJECT(&s->cpuid[i]), true,
80
+ "realized", &err);
81
+ if (err) {
82
+ error_propagate(errp, err);
83
+ return;
84
+ }
85
+
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
87
+ memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
88
+ }
89
+ }
90
91
/* 0x40020000 .. 0x4002ffff : ARMSSE system control peripheral region */
92
/* Devices behind APB PPC1:
93
--
94
2.20.1
95
96
diff view generated by jsdifflib
Deleted patch
1
Add a model of the SSE-200, now we have put in all
2
the code that lets us make it different from the IoTKit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190121185118.18550-22-peter.maydell@linaro.org
7
---
8
include/hw/arm/armsse.h | 19 ++++++++++++++++---
9
hw/arm/armsse.c | 12 ++++++++++++
10
2 files changed, 28 insertions(+), 3 deletions(-)
11
12
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/arm/armsse.h
15
+++ b/include/hw/arm/armsse.h
16
@@ -XXX,XX +XXX,XX @@
17
/*
18
- * ARM SSE (Subsystems for Embedded): IoTKit
19
+ * ARM SSE (Subsystems for Embedded): IoTKit, SSE-200
20
*
21
* Copyright (c) 2018 Linaro Limited
22
* Written by Peter Maydell
23
@@ -XXX,XX +XXX,XX @@
24
/*
25
* This is a model of the Arm "Subsystems for Embedded" family of
26
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
27
- * SSE-200. Currently we model only the Arm IoT Kit which is documented in
28
+ * SSE-200. Currently we model:
29
+ * - the Arm IoT Kit which is documented in
30
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
31
- * It contains:
32
+ * - the SSE-200 which is documented in
33
+ * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
34
+ *
35
+ * The IoTKit contains:
36
* a Cortex-M33
37
* the IDAU
38
* some timers and watchdogs
39
@@ -XXX,XX +XXX,XX @@
40
* a security controller
41
* a bus fabric which arranges that some parts of the address
42
* space are secure and non-secure aliases of each other
43
+ * The SSE-200 additionally contains:
44
+ * a second Cortex-M33
45
+ * two Message Handling Units (MHUs)
46
+ * an optional CryptoCell (which we do not model)
47
+ * more SRAM banks with associated MPCs
48
+ * multiple Power Policy Units (PPUs)
49
+ * a control interface for an icache for each CPU
50
+ * per-CPU identity and control register blocks
51
*
52
* QEMU interface:
53
* + QOM property "memory" is a MemoryRegion containing the devices provided
54
@@ -XXX,XX +XXX,XX @@
55
* them via the ARMSSE base class, so they have no IOTKIT() etc macros.
56
*/
57
#define TYPE_IOTKIT "iotkit"
58
+#define TYPE_SSE200 "sse-200"
59
60
/* We have an IRQ splitter and an OR gate input for each external PPC
61
* and the 2 internal PPCs
62
diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/armsse.c
65
+++ b/hw/arm/armsse.c
66
@@ -XXX,XX +XXX,XX @@ static const ARMSSEInfo armsse_variants[] = {
67
.has_cpusecctrl = false,
68
.has_cpuid = false,
69
},
70
+ {
71
+ .name = TYPE_SSE200,
72
+ .sram_banks = 4,
73
+ .num_cpus = 2,
74
+ .sys_version = 0x22041743,
75
+ .sys_config_format = SSE200Format,
76
+ .has_mhus = true,
77
+ .has_ppus = true,
78
+ .has_cachectrl = true,
79
+ .has_cpusecctrl = true,
80
+ .has_cpuid = true,
81
+ },
82
};
83
84
static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
Deleted patch
1
In preparation for adding support for the AN521 MPS2 image, we need
2
to handle wiring up the MPS2 device interrupt lines to both CPUs in
3
the SSE-200, rather than just the one that the IoTKit has.
4
1
5
Abstract out a "connect to the IoTKit interrupt line" function
6
and make it connect to a splitter which feeds both sets of inputs
7
for the SSE-200 case.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190121185118.18550-23-peter.maydell@linaro.org
12
---
13
hw/arm/mps2-tz.c | 79 ++++++++++++++++++++++++++++++++++++------------
14
1 file changed, 59 insertions(+), 20 deletions(-)
15
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
19
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@
21
#include "net/net.h"
22
#include "hw/core/split-irq.h"
23
24
+#define MPS2TZ_NUMIRQ 92
25
+
26
typedef enum MPS2TZFPGAType {
27
FPGA_AN505,
28
+ FPGA_AN521,
29
} MPS2TZFPGAType;
30
31
typedef struct {
32
@@ -XXX,XX +XXX,XX @@ typedef struct {
33
SplitIRQ sec_resp_splitter;
34
qemu_or_irq uart_irq_orgate;
35
DeviceState *lan9118;
36
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
37
} MPS2TZMachineState;
38
39
#define TYPE_MPS2TZ_MACHINE "mps2tz"
40
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
41
memory_region_add_subregion(get_system_memory(), base, mr);
42
}
43
44
+static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
45
+{
46
+ /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
47
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
48
+
49
+ assert(irqno < MPS2TZ_NUMIRQ);
50
+
51
+ switch (mmc->fpga_type) {
52
+ case FPGA_AN505:
53
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
54
+ case FPGA_AN521:
55
+ return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
56
+ default:
57
+ g_assert_not_reached();
58
+ }
59
+}
60
+
61
/* Most of the devices in the AN505 FPGA image sit behind
62
* Peripheral Protection Controllers. These data structures
63
* define the layout of which devices sit behind which PPCs.
64
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
65
int txirqno = i * 2 + 1;
66
int combirqno = i + 10;
67
SysBusDevice *s;
68
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
70
71
sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
72
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
73
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
74
object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
75
s = SYS_BUS_DEVICE(uart);
76
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
77
- "EXP_IRQ", txirqno));
78
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
79
- "EXP_IRQ", rxirqno));
80
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
81
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
82
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
83
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
84
- sysbus_connect_irq(s, 4, qdev_get_gpio_in_named(iotkitdev,
85
- "EXP_IRQ", combirqno));
86
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
87
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
88
}
89
90
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
91
const char *name, hwaddr size)
92
{
93
SysBusDevice *s;
94
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
95
NICInfo *nd = &nd_table[0];
96
97
/* In hardware this is a LAN9220; the LAN9118 is software compatible
98
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
99
qdev_init_nofail(mms->lan9118);
100
101
s = SYS_BUS_DEVICE(mms->lan9118);
102
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 16));
103
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
104
return sysbus_mmio_get_region(s, 0);
105
}
106
107
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
108
109
s = SYS_BUS_DEVICE(dma);
110
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
111
- sysbus_connect_irq(s, 0, qdev_get_gpio_in_named(iotkitdev,
112
- "EXP_IRQ", 58 + i * 3));
113
- sysbus_connect_irq(s, 1, qdev_get_gpio_in_named(iotkitdev,
114
- "EXP_IRQ", 56 + i * 3));
115
- sysbus_connect_irq(s, 2, qdev_get_gpio_in_named(iotkitdev,
116
- "EXP_IRQ", 57 + i * 3));
117
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
118
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
119
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
120
121
g_free(mscname);
122
return sysbus_mmio_get_region(s, 0);
123
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
124
*/
125
PL022State *spi = opaque;
126
int i = spi - &mms->spi[0];
127
- DeviceState *iotkitdev = DEVICE(&mms->iotkit);
128
SysBusDevice *s;
129
130
sysbus_init_child_obj(OBJECT(mms), name, spi, sizeof(mms->spi[0]),
131
TYPE_PL022);
132
object_property_set_bool(OBJECT(spi), true, "realized", &error_fatal);
133
s = SYS_BUS_DEVICE(spi);
134
- sysbus_connect_irq(s, 0,
135
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 51 + i));
136
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
137
return sysbus_mmio_get_region(s, 0);
138
}
139
140
static void mps2tz_common_init(MachineState *machine)
141
{
142
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
143
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
144
MachineClass *mc = MACHINE_GET_CLASS(machine);
145
MemoryRegion *system_memory = get_system_memory();
146
DeviceState *iotkitdev;
147
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
148
iotkitdev = DEVICE(&mms->iotkit);
149
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
150
"memory", &error_abort);
151
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", 92);
152
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
153
qdev_prop_set_uint32(iotkitdev, "MAINCLK", SYSCLK_FRQ);
154
object_property_set_bool(OBJECT(&mms->iotkit), true, "realized",
155
&error_fatal);
156
157
+ /*
158
+ * The AN521 needs us to create splitters to feed the IRQ inputs
159
+ * for each CPU in the SSE-200 from each device in the board.
160
+ */
161
+ if (mmc->fpga_type == FPGA_AN521) {
162
+ for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
163
+ char *name = g_strdup_printf("mps2-irq-splitter%d", i);
164
+ SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
165
+
166
+ object_initialize_child(OBJECT(machine), name,
167
+ splitter, sizeof(*splitter),
168
+ TYPE_SPLIT_IRQ, &error_fatal, NULL);
169
+ g_free(name);
170
+
171
+ object_property_set_int(OBJECT(splitter), 2, "num-lines",
172
+ &error_fatal);
173
+ object_property_set_bool(OBJECT(splitter), true, "realized",
174
+ &error_fatal);
175
+ qdev_connect_gpio_out(DEVICE(splitter), 0,
176
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
177
+ "EXP_IRQ", i));
178
+ qdev_connect_gpio_out(DEVICE(splitter), 1,
179
+ qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
180
+ "EXP_CPU1_IRQ", i));
181
+ }
182
+ }
183
+
184
/* The sec_resp_cfg output from the IoTKit must be split into multiple
185
* lines, one for each of the PPCs we create here, plus one per MSC.
186
*/
187
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
188
object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true,
189
"realized", &error_fatal);
190
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
191
- qdev_get_gpio_in_named(iotkitdev, "EXP_IRQ", 15));
192
+ get_sse_irq_in(mms, 15));
193
194
/* Most of the devices in the FPGA are behind Peripheral Protection
195
* Controllers. The required order for initializing things is:
196
--
197
2.20.1
198
199
diff view generated by jsdifflib
Deleted patch
1
The "system instructions" and "system register move" subcategories
2
of "branches, exception generating and system instructions" for A64
3
only apply if bits [23:22] are zero; other values are currently
4
unallocated. Correctly UNDEF these unallocated encodings.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-2-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 6 +++++-
12
1 file changed, 5 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
19
break;
20
case 0x6a: /* Exception generation / System */
21
if (insn & (1 << 24)) {
22
- disas_system(s, insn);
23
+ if (extract32(insn, 22, 2) == 0) {
24
+ disas_system(s, insn);
25
+ } else {
26
+ unallocated_encoding(s);
27
+ }
28
} else {
29
disas_exc(s, insn);
30
}
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
Deleted patch
1
The PRFM prefetch insn in the load/store with imm9 encodings
2
requires idx field 0b00; we were underdecoding this by
3
only checking !is_unpriv (which is equivalent to idx != 2).
4
Correctly UNDEF the unallocated encodings where idx == 0b01
5
and 0b11 as well as 0b10.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-3-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
20
} else {
21
if (size == 3 && opc == 2) {
22
/* PRFM - prefetch */
23
- if (is_unpriv) {
24
+ if (idx != 0) {
25
unallocated_encoding(s);
26
return;
27
}
28
--
29
2.20.1
30
31
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD load/store multiple structures encodings,
2
the non-post-indexed case should have zeroes in [20:16]
3
(which is the Rm field for the post-indexed case).
4
Correctly UNDEF the currently unallocated encodings which
5
have non-zeroes in those bits.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-4-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 7 ++++++-
13
1 file changed, 6 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
20
{
21
int rt = extract32(insn, 0, 5);
22
int rn = extract32(insn, 5, 5);
23
+ int rm = extract32(insn, 16, 5);
24
int size = extract32(insn, 10, 2);
25
int opcode = extract32(insn, 12, 4);
26
bool is_store = !extract32(insn, 22, 1);
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
28
return;
29
}
30
31
+ if (!is_postidx && rm != 0) {
32
+ unallocated_encoding(s);
33
+ return;
34
+ }
35
+
36
/* From the shared decode logic */
37
switch (opcode) {
38
case 0x0:
39
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
40
}
41
42
if (is_postidx) {
43
- int rm = extract32(insn, 16, 5);
44
if (rm == 31) {
45
tcg_gen_mov_i64(tcg_rn, tcg_addr);
46
} else {
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD load/store single structure encodings, the
2
non-post-indexed case should have zeroes in [20:16] (which is the
3
Rm field for the post-indexed case). Bit 31 must also be zero
4
(a check we got right in ldst_multiple but not here). Correctly
5
UNDEF these unallocated encodings.
6
1
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20190125182626.9221-5-peter.maydell@linaro.org
11
---
12
target/arm/translate-a64.c | 11 ++++++++++-
13
1 file changed, 10 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
20
{
21
int rt = extract32(insn, 0, 5);
22
int rn = extract32(insn, 5, 5);
23
+ int rm = extract32(insn, 16, 5);
24
int size = extract32(insn, 10, 2);
25
int S = extract32(insn, 12, 1);
26
int opc = extract32(insn, 13, 3);
27
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
28
int ebytes, xs;
29
TCGv_i64 tcg_addr, tcg_rn, tcg_ebytes;
30
31
+ if (extract32(insn, 31, 1)) {
32
+ unallocated_encoding(s);
33
+ return;
34
+ }
35
+ if (!is_postidx && rm != 0) {
36
+ unallocated_encoding(s);
37
+ return;
38
+ }
39
+
40
switch (scale) {
41
case 3:
42
if (!is_load || S) {
43
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
44
}
45
46
if (is_postidx) {
47
- int rm = extract32(insn, 16, 5);
48
if (rm == 31) {
49
tcg_gen_mov_i64(tcg_rn, tcg_addr);
50
} else {
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
In the "add/subtract (extended register)" encoding group, the "opt"
2
field in bits [23:22] must be zero. Correctly UNDEF the unallocated
3
encodings where this field is not zero.
4
1
5
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Message-id: 20190125182626.9221-6-peter.maydell@linaro.org
9
---
10
target/arm/translate-a64.c | 3 ++-
11
1 file changed, 2 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
18
int imm3 = extract32(insn, 10, 3);
19
int option = extract32(insn, 13, 3);
20
int rm = extract32(insn, 16, 5);
21
+ int opt = extract32(insn, 22, 2);
22
bool setflags = extract32(insn, 29, 1);
23
bool sub_op = extract32(insn, 30, 1);
24
bool sf = extract32(insn, 31, 1);
25
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
26
TCGv_i64 tcg_rd;
27
TCGv_i64 tcg_result;
28
29
- if (imm3 > 4) {
30
+ if (imm3 > 4 || opt != 0) {
31
unallocated_encoding(s);
32
return;
33
}
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
In the encoding groups
2
* floating-point data-processing (1 source)
3
* floating-point data-processing (2 source)
4
* floating-point data-processing (3 source)
5
* floating-point immediate
6
* floating-point compare
7
* floating-ponit conditional compare
8
* floating-point conditional select
9
1
10
bit 31 is M and bit 29 is S (and bit 30 is 0, already checked at
11
this point in the decode). None of these groups allocate any
12
encoding for M=1 or S=1. We checked this in disas_fp_compare(),
13
disas_fp_ccomp() and disas_fp_csel(), but missed it in disas_fp_1src(),
14
disas_fp_2src(), disas_fp_3src() and disas_fp_imm().
15
16
We also missed that in the fp immediate encoding the imm5 field
17
must be all zeroes.
18
19
Correctly UNDEF the unallocated encodings here.
20
21
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
24
Message-id: 20190125182626.9221-7-peter.maydell@linaro.org
25
---
26
target/arm/translate-a64.c | 22 +++++++++++++++++++++-
27
1 file changed, 21 insertions(+), 1 deletion(-)
28
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-a64.c
32
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
34
*/
35
static void disas_fp_1src(DisasContext *s, uint32_t insn)
36
{
37
+ int mos = extract32(insn, 29, 3);
38
int type = extract32(insn, 22, 2);
39
int opcode = extract32(insn, 15, 6);
40
int rn = extract32(insn, 5, 5);
41
int rd = extract32(insn, 0, 5);
42
43
+ if (mos) {
44
+ unallocated_encoding(s);
45
+ return;
46
+ }
47
+
48
switch (opcode) {
49
case 0x4: case 0x5: case 0x7:
50
{
51
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_half(DisasContext *s, int opcode,
52
*/
53
static void disas_fp_2src(DisasContext *s, uint32_t insn)
54
{
55
+ int mos = extract32(insn, 29, 3);
56
int type = extract32(insn, 22, 2);
57
int rd = extract32(insn, 0, 5);
58
int rn = extract32(insn, 5, 5);
59
int rm = extract32(insn, 16, 5);
60
int opcode = extract32(insn, 12, 4);
61
62
- if (opcode > 8) {
63
+ if (opcode > 8 || mos) {
64
unallocated_encoding(s);
65
return;
66
}
67
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
68
*/
69
static void disas_fp_3src(DisasContext *s, uint32_t insn)
70
{
71
+ int mos = extract32(insn, 29, 3);
72
int type = extract32(insn, 22, 2);
73
int rd = extract32(insn, 0, 5);
74
int rn = extract32(insn, 5, 5);
75
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
76
bool o0 = extract32(insn, 15, 1);
77
bool o1 = extract32(insn, 21, 1);
78
79
+ if (mos) {
80
+ unallocated_encoding(s);
81
+ return;
82
+ }
83
+
84
switch (type) {
85
case 0:
86
if (!fp_access_check(s)) {
87
@@ -XXX,XX +XXX,XX @@ uint64_t vfp_expand_imm(int size, uint8_t imm8)
88
static void disas_fp_imm(DisasContext *s, uint32_t insn)
89
{
90
int rd = extract32(insn, 0, 5);
91
+ int imm5 = extract32(insn, 5, 5);
92
int imm8 = extract32(insn, 13, 8);
93
int type = extract32(insn, 22, 2);
94
+ int mos = extract32(insn, 29, 3);
95
uint64_t imm;
96
TCGv_i64 tcg_res;
97
TCGMemOp sz;
98
99
+ if (mos || imm5) {
100
+ unallocated_encoding(s);
101
+ return;
102
+ }
103
+
104
switch (type) {
105
case 0:
106
sz = MO_32;
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
Deleted patch
1
In the AdvSIMD scalar x indexed element and vector x indexed element
2
encoding group, the SDOT and UDOT instructions are vector only,
3
and their opcode is unallocated in the scalar group. Correctly
4
UNDEF this unallocated encoding.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190125182626.9221-8-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
19
break;
20
case 0x0e: /* SDOT */
21
case 0x1e: /* UDOT */
22
- if (size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
23
+ if (is_scalar || size != MO_32 || !dc_isar_feature(aa64_dp, s)) {
24
unallocated_encoding(s);
25
return;
26
}
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
The tcg_register_iommu_notifier() code has a GArray of
2
TCGIOMMUNotifier structs which it has registered by passing
3
memory_region_register_iommu_notifier() a pointer to the embedded
4
IOMMUNotifier field. Unfortunately, if we need to enlarge the
5
array via g_array_set_size() this can cause a realloc(), which
6
invalidates the pointer that memory_region_register_iommu_notifier()
7
put into the MemoryRegion's iommu_notify list. This can result
8
in segfaults.
9
1
10
Switch the GArray to holding pointers to the TCGIOMMUNotifier
11
structs, so that we can individually allocate and free them.
12
13
Cc: qemu-stable@nongnu.org
14
Fixes: 1f871c5e6b0f30644a60a ("exec.c: Handle IOMMUs in address_space_translate_for_iotlb()")
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190128174241.5860-1-peter.maydell@linaro.org
18
---
19
exec.c | 10 ++++++----
20
1 file changed, 6 insertions(+), 4 deletions(-)
21
22
diff --git a/exec.c b/exec.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/exec.c
25
+++ b/exec.c
26
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
27
int i;
28
29
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
30
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
31
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
32
if (notifier->mr == mr && notifier->iommu_idx == iommu_idx) {
33
break;
34
}
35
@@ -XXX,XX +XXX,XX @@ static void tcg_register_iommu_notifier(CPUState *cpu,
36
if (i == cpu->iommu_notifiers->len) {
37
/* Not found, add a new entry at the end of the array */
38
cpu->iommu_notifiers = g_array_set_size(cpu->iommu_notifiers, i + 1);
39
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
40
+ notifier = g_new0(TCGIOMMUNotifier, 1);
41
+ g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i) = notifier;
42
43
notifier->mr = mr;
44
notifier->iommu_idx = iommu_idx;
45
@@ -XXX,XX +XXX,XX @@ static void tcg_iommu_free_notifier_list(CPUState *cpu)
46
TCGIOMMUNotifier *notifier;
47
48
for (i = 0; i < cpu->iommu_notifiers->len; i++) {
49
- notifier = &g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier, i);
50
+ notifier = g_array_index(cpu->iommu_notifiers, TCGIOMMUNotifier *, i);
51
memory_region_unregister_iommu_notifier(notifier->mr, &notifier->n);
52
+ g_free(notifier);
53
}
54
g_array_free(cpu->iommu_notifiers, true);
55
}
56
@@ -XXX,XX +XXX,XX @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
57
vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
58
}
59
60
- cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier));
61
+ cpu->iommu_notifiers = g_array_new(false, true, sizeof(TCGIOMMUNotifier *));
62
#endif
63
}
64
65
--
66
2.20.1
67
68
diff view generated by jsdifflib
Deleted patch
1
The FCMLA (by element) instruction exists in the
2
"vector x indexed element" encoding group, but not in
3
the "scalar x indexed element" group. Correctly UNDEF
4
the unallocated encodings.
5
1
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Message-id: 20190129140411.682-2-peter.maydell@linaro.org
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
19
case 0x13: /* FCMLA #90 */
20
case 0x15: /* FCMLA #180 */
21
case 0x17: /* FCMLA #270 */
22
- if (!dc_isar_feature(aa64_fcma, s)) {
23
+ if (is_scalar || !dc_isar_feature(aa64_fcma, s)) {
24
unallocated_encoding(s);
25
return;
26
}
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
In disas_simd_indexed(), for the case of "complex fp", each indexable
2
element is a complex pair, so the total size is twice that indicated
3
in the 'size' field in the encoding. We were trying to do this
4
"double the size" operation with a left shift by 1, but this is
5
incorrect because the 'size' field is a MO_8/MO_16/MO_32/MO_64
6
value, and doubling the size should be done by a simple increment.
7
1
8
This meant we were mishandling FCMLA (by element) of values where
9
the real and imaginary parts are 32-bit floats, and would incorrectly
10
UNDEF this encoding. (No other insns take this code path, and for
11
16-bit floats it happens that 1 << 1 and 1 + 1 are both the same).
12
13
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
16
Message-id: 20190129140411.682-3-peter.maydell@linaro.org
17
---
18
target/arm/translate-a64.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
26
27
case 2: /* complex fp */
28
/* Each indexable element is a complex pair. */
29
- size <<= 1;
30
+ size += 1;
31
switch (size) {
32
case MO_32:
33
if (h && !is_q) {
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
These bits become writable with the ARMv8.3-PAuth extension.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190129143511.12311-1-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 6 ++++++
11
1 file changed, 6 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
18
if (cpu_isar_feature(aa64_lor, cpu)) {
19
valid_mask |= SCR_TLOR;
20
}
21
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
22
+ valid_mask |= SCR_API | SCR_APK;
23
+ }
24
25
/* Clear all-context RES0 bits. */
26
value &= valid_mask;
27
@@ -XXX,XX +XXX,XX @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
28
if (cpu_isar_feature(aa64_lor, cpu)) {
29
valid_mask |= HCR_TLOR;
30
}
31
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
32
+ valid_mask |= HCR_API | HCR_APK;
33
+ }
34
35
/* Clear RES0 bits. */
36
value &= valid_mask;
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Julia Suvorova <jusual@mail.ru>
2
1
3
Until now, the set_pc logic was unclear, which raised questions about
4
whether it should be used directly, applying a value to PC or adding
5
additional checks, for example, set the Thumb bit in Arm cpu. Let's set
6
the set_pc logic for “Configure the PC, as was done in the ELF file”
7
and implement synchronize_with_tb hook for preserving PC to cpu_tb_exec.
8
9
Signed-off-by: Julia Suvorova <jusual@mail.ru>
10
Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 20190129121817.7109-1-jusual@mail.ru
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/qom/cpu.h | 16 ++++++++++++++--
16
hw/arm/boot.c | 4 ----
17
target/arm/arm-powerctl.c | 3 ---
18
target/arm/cpu.c | 26 +++++++++++++++++++++++++-
19
target/arm/cpu64.c | 15 ---------------
20
5 files changed, 39 insertions(+), 25 deletions(-)
21
22
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/qom/cpu.h
25
+++ b/include/qom/cpu.h
26
@@ -XXX,XX +XXX,XX @@ struct TranslationBlock;
27
* @get_arch_id: Callback for getting architecture-dependent CPU ID.
28
* @get_paging_enabled: Callback for inquiring whether paging is enabled.
29
* @get_memory_mapping: Callback for obtaining the memory mappings.
30
- * @set_pc: Callback for setting the Program Counter register.
31
+ * @set_pc: Callback for setting the Program Counter register. This
32
+ * should have the semantics used by the target architecture when
33
+ * setting the PC from a source such as an ELF file entry point;
34
+ * for example on Arm it will also set the Thumb mode bit based
35
+ * on the least significant bit of the new PC value.
36
+ * If the target behaviour here is anything other than "set
37
+ * the PC register to the value passed in" then the target must
38
+ * also implement the synchronize_from_tb hook.
39
* @synchronize_from_tb: Callback for synchronizing state from a TCG
40
- * #TranslationBlock.
41
+ * #TranslationBlock. This is called when we abandon execution
42
+ * of a TB before starting it, and must set all parts of the CPU
43
+ * state which the previous TB in the chain may not have updated.
44
+ * This always includes at least the program counter; some targets
45
+ * will need to do more. If this hook is not implemented then the
46
+ * default is to call @set_pc(tb->pc).
47
* @handle_mmu_fault: Callback for handling an MMU fault.
48
* @get_phys_page_debug: Callback for obtaining a physical address.
49
* @get_phys_page_attrs_debug: Callback for obtaining a physical address and the
50
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/boot.c
53
+++ b/hw/arm/boot.c
54
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
55
g_assert_not_reached();
56
}
57
58
- if (!env->aarch64) {
59
- env->thumb = info->entry & 1;
60
- entry &= 0xfffffffe;
61
- }
62
cpu_set_pc(cs, entry);
63
} else {
64
/* If we are booting Linux then we need to check whether we are
65
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/arm-powerctl.c
68
+++ b/target/arm/arm-powerctl.c
69
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
70
71
if (info->target_aa64) {
72
target_cpu->env.xregs[0] = info->context_id;
73
- target_cpu->env.thumb = false;
74
} else {
75
target_cpu->env.regs[0] = info->context_id;
76
- target_cpu->env.thumb = info->entry & 1;
77
- info->entry &= 0xfffffffe;
78
}
79
80
/* Start the new CPU at the requested address */
81
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/cpu.c
84
+++ b/target/arm/cpu.c
85
@@ -XXX,XX +XXX,XX @@
86
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
87
{
88
ARMCPU *cpu = ARM_CPU(cs);
89
+ CPUARMState *env = &cpu->env;
90
91
- cpu->env.regs[15] = value;
92
+ if (is_a64(env)) {
93
+ env->pc = value;
94
+ env->thumb = 0;
95
+ } else {
96
+ env->regs[15] = value & ~1;
97
+ env->thumb = value & 1;
98
+ }
99
+}
100
+
101
+static void arm_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
102
+{
103
+ ARMCPU *cpu = ARM_CPU(cs);
104
+ CPUARMState *env = &cpu->env;
105
+
106
+ /*
107
+ * It's OK to look at env for the current mode here, because it's
108
+ * never possible for an AArch64 TB to chain to an AArch32 TB.
109
+ */
110
+ if (is_a64(env)) {
111
+ env->pc = tb->pc;
112
+ } else {
113
+ env->regs[15] = tb->pc;
114
+ }
115
}
116
117
static bool arm_cpu_has_work(CPUState *cs)
118
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
119
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
120
cc->dump_state = arm_cpu_dump_state;
121
cc->set_pc = arm_cpu_set_pc;
122
+ cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
123
cc->gdb_read_register = arm_cpu_gdb_read_register;
124
cc->gdb_write_register = arm_cpu_gdb_write_register;
125
#ifdef CONFIG_USER_ONLY
126
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/target/arm/cpu64.c
129
+++ b/target/arm/cpu64.c
130
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_finalizefn(Object *obj)
131
{
132
}
133
134
-static void aarch64_cpu_set_pc(CPUState *cs, vaddr value)
135
-{
136
- ARMCPU *cpu = ARM_CPU(cs);
137
- /* It's OK to look at env for the current mode here, because it's
138
- * never possible for an AArch64 TB to chain to an AArch32 TB.
139
- * (Otherwise we would need to use synchronize_from_tb instead.)
140
- */
141
- if (is_a64(&cpu->env)) {
142
- cpu->env.pc = value;
143
- } else {
144
- cpu->env.regs[15] = value;
145
- }
146
-}
147
-
148
static gchar *aarch64_gdb_arch_name(CPUState *cs)
149
{
150
return g_strdup("aarch64");
151
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
152
CPUClass *cc = CPU_CLASS(oc);
153
154
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
155
- cc->set_pc = aarch64_cpu_set_pc;
156
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
157
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
158
cc->gdb_num_core_regs = 34;
159
--
160
2.20.1
161
162
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
The nRF51 contains three regions of non-volatile memory (NVM):
4
- CODE (R/W): contains code
5
- FICR (R): Factory information like code size, chip id etc.
6
- UICR (R/W): Changeable configuration data. Lock bits, Code
7
protection configuration, Bootloader address, Nordic SoftRadio
8
configuration, Firmware configuration.
9
10
Read and write access to the memories is managed by the
11
Non-volatile memory controller.
12
13
Memory schema:
14
[ CPU ] -+- [ NVM, either FICR, UICR or CODE ]
15
| |
16
\- [ NVMC ]
17
18
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
20
Tested-by: Joel Stanley <joel@jms.id.au>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20190201023357.22596-2-stefanha@redhat.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
hw/nvram/Makefile.objs | 1 +
26
include/hw/nvram/nrf51_nvm.h | 64 ++++++
27
hw/nvram/nrf51_nvm.c | 388 +++++++++++++++++++++++++++++++++++
28
3 files changed, 453 insertions(+)
29
create mode 100644 include/hw/nvram/nrf51_nvm.h
30
create mode 100644 hw/nvram/nrf51_nvm.c
31
32
diff --git a/hw/nvram/Makefile.objs b/hw/nvram/Makefile.objs
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/nvram/Makefile.objs
35
+++ b/hw/nvram/Makefile.objs
36
@@ -XXX,XX +XXX,XX @@ common-obj-y += fw_cfg.o
37
common-obj-y += chrp_nvram.o
38
common-obj-$(CONFIG_MAC_NVRAM) += mac_nvram.o
39
obj-$(CONFIG_PSERIES) += spapr_nvram.o
40
+obj-$(CONFIG_NRF51_SOC) += nrf51_nvm.o
41
diff --git a/include/hw/nvram/nrf51_nvm.h b/include/hw/nvram/nrf51_nvm.h
42
new file mode 100644
43
index XXXXXXX..XXXXXXX
44
--- /dev/null
45
+++ b/include/hw/nvram/nrf51_nvm.h
46
@@ -XXX,XX +XXX,XX @@
47
+/*
48
+ * Nordic Semiconductor nRF51 non-volatile memory
49
+ *
50
+ * It provides an interface to erase regions in flash memory.
51
+ * Furthermore it provides the user and factory information registers.
52
+ *
53
+ * QEMU interface:
54
+ * + sysbus MMIO regions 0: NVMC peripheral registers
55
+ * + sysbus MMIO regions 1: FICR peripheral registers
56
+ * + sysbus MMIO regions 2: UICR peripheral registers
57
+ * + flash-size property: flash size in bytes.
58
+ *
59
+ * Accuracy of the peripheral model:
60
+ * + Code regions (MPU configuration) are disregarded.
61
+ *
62
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
63
+ *
64
+ * This code is licensed under the GPL version 2 or later. See
65
+ * the COPYING file in the top-level directory.
66
+ *
67
+ */
68
+#ifndef NRF51_NVM_H
69
+#define NRF51_NVM_H
70
+
71
+#include "hw/sysbus.h"
72
+#define TYPE_NRF51_NVM "nrf51_soc.nvm"
73
+#define NRF51_NVM(obj) OBJECT_CHECK(NRF51NVMState, (obj), TYPE_NRF51_NVM)
74
+
75
+#define NRF51_UICR_FIXTURE_SIZE 64
76
+
77
+#define NRF51_NVMC_SIZE 0x1000
78
+
79
+#define NRF51_NVMC_READY 0x400
80
+#define NRF51_NVMC_READY_READY 0x01
81
+#define NRF51_NVMC_CONFIG 0x504
82
+#define NRF51_NVMC_CONFIG_MASK 0x03
83
+#define NRF51_NVMC_CONFIG_WEN 0x01
84
+#define NRF51_NVMC_CONFIG_EEN 0x02
85
+#define NRF51_NVMC_ERASEPCR1 0x508
86
+#define NRF51_NVMC_ERASEPCR0 0x510
87
+#define NRF51_NVMC_ERASEALL 0x50C
88
+#define NRF51_NVMC_ERASEUICR 0x514
89
+#define NRF51_NVMC_ERASE 0x01
90
+
91
+#define NRF51_UICR_SIZE 0x100
92
+
93
+typedef struct NRF51NVMState {
94
+ SysBusDevice parent_obj;
95
+
96
+ MemoryRegion mmio;
97
+ MemoryRegion ficr;
98
+ MemoryRegion uicr;
99
+ MemoryRegion flash;
100
+
101
+ uint32_t uicr_content[NRF51_UICR_FIXTURE_SIZE];
102
+ uint32_t flash_size;
103
+ uint8_t *storage;
104
+
105
+ uint32_t config;
106
+
107
+} NRF51NVMState;
108
+
109
+
110
+#endif
111
diff --git a/hw/nvram/nrf51_nvm.c b/hw/nvram/nrf51_nvm.c
112
new file mode 100644
113
index XXXXXXX..XXXXXXX
114
--- /dev/null
115
+++ b/hw/nvram/nrf51_nvm.c
116
@@ -XXX,XX +XXX,XX @@
117
+/*
118
+ * Nordic Semiconductor nRF51 non-volatile memory
119
+ *
120
+ * It provides an interface to erase regions in flash memory.
121
+ * Furthermore it provides the user and factory information registers.
122
+ *
123
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
124
+ *
125
+ * See nRF51 reference manual and product sheet sections:
126
+ * + Non-Volatile Memory Controller (NVMC)
127
+ * + Factory Information Configuration Registers (FICR)
128
+ * + User Information Configuration Registers (UICR)
129
+ *
130
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
131
+ *
132
+ * This code is licensed under the GPL version 2 or later. See
133
+ * the COPYING file in the top-level directory.
134
+ */
135
+
136
+#include "qemu/osdep.h"
137
+#include "qapi/error.h"
138
+#include "qemu/log.h"
139
+#include "exec/address-spaces.h"
140
+#include "hw/arm/nrf51.h"
141
+#include "hw/nvram/nrf51_nvm.h"
142
+
143
+/*
144
+ * FICR Registers Assignments
145
+ * CODEPAGESIZE 0x010
146
+ * CODESIZE 0x014
147
+ * CLENR0 0x028
148
+ * PPFC 0x02C
149
+ * NUMRAMBLOCK 0x034
150
+ * SIZERAMBLOCKS 0x038
151
+ * SIZERAMBLOCK[0] 0x038
152
+ * SIZERAMBLOCK[1] 0x03C
153
+ * SIZERAMBLOCK[2] 0x040
154
+ * SIZERAMBLOCK[3] 0x044
155
+ * CONFIGID 0x05C
156
+ * DEVICEID[0] 0x060
157
+ * DEVICEID[1] 0x064
158
+ * ER[0] 0x080
159
+ * ER[1] 0x084
160
+ * ER[2] 0x088
161
+ * ER[3] 0x08C
162
+ * IR[0] 0x090
163
+ * IR[1] 0x094
164
+ * IR[2] 0x098
165
+ * IR[3] 0x09C
166
+ * DEVICEADDRTYPE 0x0A0
167
+ * DEVICEADDR[0] 0x0A4
168
+ * DEVICEADDR[1] 0x0A8
169
+ * OVERRIDEEN 0x0AC
170
+ * NRF_1MBIT[0] 0x0B0
171
+ * NRF_1MBIT[1] 0x0B4
172
+ * NRF_1MBIT[2] 0x0B8
173
+ * NRF_1MBIT[3] 0x0BC
174
+ * NRF_1MBIT[4] 0x0C0
175
+ * BLE_1MBIT[0] 0x0EC
176
+ * BLE_1MBIT[1] 0x0F0
177
+ * BLE_1MBIT[2] 0x0F4
178
+ * BLE_1MBIT[3] 0x0F8
179
+ * BLE_1MBIT[4] 0x0FC
180
+ */
181
+static const uint32_t ficr_content[64] = {
182
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000400,
183
+ 0x00000100, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, 0x00002000,
184
+ 0x00002000, 0x00002000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
185
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
186
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003,
187
+ 0x12345678, 0x9ABCDEF1, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
188
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
189
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
190
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
191
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
192
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
193
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
194
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
195
+};
196
+
197
+static uint64_t ficr_read(void *opaque, hwaddr offset, unsigned int size)
198
+{
199
+ assert(offset < sizeof(ficr_content));
200
+ return ficr_content[offset / 4];
201
+}
202
+
203
+static void ficr_write(void *opaque, hwaddr offset, uint64_t value,
204
+ unsigned int size)
205
+{
206
+ /* Intentionally do nothing */
207
+}
208
+
209
+static const MemoryRegionOps ficr_ops = {
210
+ .read = ficr_read,
211
+ .write = ficr_write,
212
+ .impl.min_access_size = 4,
213
+ .impl.max_access_size = 4,
214
+ .endianness = DEVICE_LITTLE_ENDIAN
215
+};
216
+
217
+/*
218
+ * UICR Registers Assignments
219
+ * CLENR0 0x000
220
+ * RBPCONF 0x004
221
+ * XTALFREQ 0x008
222
+ * FWID 0x010
223
+ * BOOTLOADERADDR 0x014
224
+ * NRFFW[0] 0x014
225
+ * NRFFW[1] 0x018
226
+ * NRFFW[2] 0x01C
227
+ * NRFFW[3] 0x020
228
+ * NRFFW[4] 0x024
229
+ * NRFFW[5] 0x028
230
+ * NRFFW[6] 0x02C
231
+ * NRFFW[7] 0x030
232
+ * NRFFW[8] 0x034
233
+ * NRFFW[9] 0x038
234
+ * NRFFW[10] 0x03C
235
+ * NRFFW[11] 0x040
236
+ * NRFFW[12] 0x044
237
+ * NRFFW[13] 0x048
238
+ * NRFFW[14] 0x04C
239
+ * NRFHW[0] 0x050
240
+ * NRFHW[1] 0x054
241
+ * NRFHW[2] 0x058
242
+ * NRFHW[3] 0x05C
243
+ * NRFHW[4] 0x060
244
+ * NRFHW[5] 0x064
245
+ * NRFHW[6] 0x068
246
+ * NRFHW[7] 0x06C
247
+ * NRFHW[8] 0x070
248
+ * NRFHW[9] 0x074
249
+ * NRFHW[10] 0x078
250
+ * NRFHW[11] 0x07C
251
+ * CUSTOMER[0] 0x080
252
+ * CUSTOMER[1] 0x084
253
+ * CUSTOMER[2] 0x088
254
+ * CUSTOMER[3] 0x08C
255
+ * CUSTOMER[4] 0x090
256
+ * CUSTOMER[5] 0x094
257
+ * CUSTOMER[6] 0x098
258
+ * CUSTOMER[7] 0x09C
259
+ * CUSTOMER[8] 0x0A0
260
+ * CUSTOMER[9] 0x0A4
261
+ * CUSTOMER[10] 0x0A8
262
+ * CUSTOMER[11] 0x0AC
263
+ * CUSTOMER[12] 0x0B0
264
+ * CUSTOMER[13] 0x0B4
265
+ * CUSTOMER[14] 0x0B8
266
+ * CUSTOMER[15] 0x0BC
267
+ * CUSTOMER[16] 0x0C0
268
+ * CUSTOMER[17] 0x0C4
269
+ * CUSTOMER[18] 0x0C8
270
+ * CUSTOMER[19] 0x0CC
271
+ * CUSTOMER[20] 0x0D0
272
+ * CUSTOMER[21] 0x0D4
273
+ * CUSTOMER[22] 0x0D8
274
+ * CUSTOMER[23] 0x0DC
275
+ * CUSTOMER[24] 0x0E0
276
+ * CUSTOMER[25] 0x0E4
277
+ * CUSTOMER[26] 0x0E8
278
+ * CUSTOMER[27] 0x0EC
279
+ * CUSTOMER[28] 0x0F0
280
+ * CUSTOMER[29] 0x0F4
281
+ * CUSTOMER[30] 0x0F8
282
+ * CUSTOMER[31] 0x0FC
283
+ */
284
+
285
+static uint64_t uicr_read(void *opaque, hwaddr offset, unsigned int size)
286
+{
287
+ NRF51NVMState *s = NRF51_NVM(opaque);
288
+
289
+ assert(offset < sizeof(s->uicr_content));
290
+ return s->uicr_content[offset / 4];
291
+}
292
+
293
+static void uicr_write(void *opaque, hwaddr offset, uint64_t value,
294
+ unsigned int size)
295
+{
296
+ NRF51NVMState *s = NRF51_NVM(opaque);
297
+
298
+ assert(offset < sizeof(s->uicr_content));
299
+ s->uicr_content[offset / 4] = value;
300
+}
301
+
302
+static const MemoryRegionOps uicr_ops = {
303
+ .read = uicr_read,
304
+ .write = uicr_write,
305
+ .impl.min_access_size = 4,
306
+ .impl.max_access_size = 4,
307
+ .endianness = DEVICE_LITTLE_ENDIAN
308
+};
309
+
310
+
311
+static uint64_t io_read(void *opaque, hwaddr offset, unsigned int size)
312
+{
313
+ NRF51NVMState *s = NRF51_NVM(opaque);
314
+ uint64_t r = 0;
315
+
316
+ switch (offset) {
317
+ case NRF51_NVMC_READY:
318
+ r = NRF51_NVMC_READY_READY;
319
+ break;
320
+ case NRF51_NVMC_CONFIG:
321
+ r = s->config;
322
+ break;
323
+ default:
324
+ qemu_log_mask(LOG_GUEST_ERROR,
325
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n", __func__, offset);
326
+ break;
327
+ }
328
+
329
+ return r;
330
+}
331
+
332
+static void io_write(void *opaque, hwaddr offset, uint64_t value,
333
+ unsigned int size)
334
+{
335
+ NRF51NVMState *s = NRF51_NVM(opaque);
336
+
337
+ switch (offset) {
338
+ case NRF51_NVMC_CONFIG:
339
+ s->config = value & NRF51_NVMC_CONFIG_MASK;
340
+ break;
341
+ case NRF51_NVMC_ERASEPCR0:
342
+ case NRF51_NVMC_ERASEPCR1:
343
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
344
+ /* Mask in-page sub address */
345
+ value &= ~(NRF51_PAGE_SIZE - 1);
346
+ if (value <= (s->flash_size - NRF51_PAGE_SIZE)) {
347
+ memset(s->storage + value, 0xFF, NRF51_PAGE_SIZE);
348
+ memory_region_flush_rom_device(&s->flash, value,
349
+ NRF51_PAGE_SIZE);
350
+ }
351
+ } else {
352
+ qemu_log_mask(LOG_GUEST_ERROR,
353
+ "%s: Flash erase at 0x%" HWADDR_PRIx" while flash not erasable.\n",
354
+ __func__, offset);
355
+ }
356
+ break;
357
+ case NRF51_NVMC_ERASEALL:
358
+ if (value == NRF51_NVMC_ERASE) {
359
+ if (s->config & NRF51_NVMC_CONFIG_EEN) {
360
+ memset(s->storage, 0xFF, s->flash_size);
361
+ memory_region_flush_rom_device(&s->flash, 0, s->flash_size);
362
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
363
+ } else {
364
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash not erasable.\n",
365
+ __func__);
366
+ }
367
+ }
368
+ break;
369
+ case NRF51_NVMC_ERASEUICR:
370
+ if (value == NRF51_NVMC_ERASE) {
371
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
372
+ }
373
+ break;
374
+
375
+ default:
376
+ qemu_log_mask(LOG_GUEST_ERROR,
377
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n", __func__, offset);
378
+ }
379
+}
380
+
381
+static const MemoryRegionOps io_ops = {
382
+ .read = io_read,
383
+ .write = io_write,
384
+ .impl.min_access_size = 4,
385
+ .impl.max_access_size = 4,
386
+ .endianness = DEVICE_LITTLE_ENDIAN,
387
+};
388
+
389
+
390
+static void flash_write(void *opaque, hwaddr offset, uint64_t value,
391
+ unsigned int size)
392
+{
393
+ NRF51NVMState *s = NRF51_NVM(opaque);
394
+
395
+ if (s->config & NRF51_NVMC_CONFIG_WEN) {
396
+ uint32_t oldval;
397
+
398
+ assert(offset + size <= s->flash_size);
399
+
400
+ /* NOR Flash only allows bits to be flipped from 1's to 0's on write */
401
+ oldval = ldl_le_p(s->storage + offset);
402
+ oldval &= value;
403
+ stl_le_p(s->storage + offset, oldval);
404
+
405
+ memory_region_flush_rom_device(&s->flash, offset, size);
406
+ } else {
407
+ qemu_log_mask(LOG_GUEST_ERROR,
408
+ "%s: Flash write 0x%" HWADDR_PRIx" while flash not writable.\n",
409
+ __func__, offset);
410
+ }
411
+}
412
+
413
+
414
+
415
+static const MemoryRegionOps flash_ops = {
416
+ .write = flash_write,
417
+ .valid.min_access_size = 4,
418
+ .valid.max_access_size = 4,
419
+ .endianness = DEVICE_LITTLE_ENDIAN,
420
+};
421
+
422
+static void nrf51_nvm_init(Object *obj)
423
+{
424
+ NRF51NVMState *s = NRF51_NVM(obj);
425
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
426
+
427
+ memory_region_init_io(&s->mmio, obj, &io_ops, s, "nrf51_soc.nvmc",
428
+ NRF51_NVMC_SIZE);
429
+ sysbus_init_mmio(sbd, &s->mmio);
430
+
431
+ memory_region_init_io(&s->ficr, obj, &ficr_ops, s, "nrf51_soc.ficr",
432
+ sizeof(ficr_content));
433
+ sysbus_init_mmio(sbd, &s->ficr);
434
+
435
+ memory_region_init_io(&s->uicr, obj, &uicr_ops, s, "nrf51_soc.uicr",
436
+ sizeof(s->uicr_content));
437
+ sysbus_init_mmio(sbd, &s->uicr);
438
+}
439
+
440
+static void nrf51_nvm_realize(DeviceState *dev, Error **errp)
441
+{
442
+ NRF51NVMState *s = NRF51_NVM(dev);
443
+ Error *err = NULL;
444
+
445
+ memory_region_init_rom_device(&s->flash, OBJECT(dev), &flash_ops, s,
446
+ "nrf51_soc.flash", s->flash_size, &err);
447
+ if (err) {
448
+ error_propagate(errp, err);
449
+ return;
450
+ }
451
+
452
+ s->storage = memory_region_get_ram_ptr(&s->flash);
453
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->flash);
454
+}
455
+
456
+static void nrf51_nvm_reset(DeviceState *dev)
457
+{
458
+ NRF51NVMState *s = NRF51_NVM(dev);
459
+
460
+ s->config = 0x00;
461
+ memset(s->uicr_content, 0xFF, sizeof(s->uicr_content));
462
+}
463
+
464
+static Property nrf51_nvm_properties[] = {
465
+ DEFINE_PROP_UINT32("flash-size", NRF51NVMState, flash_size, 0x40000),
466
+ DEFINE_PROP_END_OF_LIST(),
467
+};
468
+
469
+static const VMStateDescription vmstate_nvm = {
470
+ .name = "nrf51_soc.nvm",
471
+ .version_id = 1,
472
+ .minimum_version_id = 1,
473
+ .fields = (VMStateField[]) {
474
+ VMSTATE_UINT32_ARRAY(uicr_content, NRF51NVMState,
475
+ NRF51_UICR_FIXTURE_SIZE),
476
+ VMSTATE_UINT32(config, NRF51NVMState),
477
+ VMSTATE_END_OF_LIST()
478
+ }
479
+};
480
+
481
+static void nrf51_nvm_class_init(ObjectClass *klass, void *data)
482
+{
483
+ DeviceClass *dc = DEVICE_CLASS(klass);
484
+
485
+ dc->props = nrf51_nvm_properties;
486
+ dc->vmsd = &vmstate_nvm;
487
+ dc->realize = nrf51_nvm_realize;
488
+ dc->reset = nrf51_nvm_reset;
489
+}
490
+
491
+static const TypeInfo nrf51_nvm_info = {
492
+ .name = TYPE_NRF51_NVM,
493
+ .parent = TYPE_SYS_BUS_DEVICE,
494
+ .instance_size = sizeof(NRF51NVMState),
495
+ .instance_init = nrf51_nvm_init,
496
+ .class_init = nrf51_nvm_class_init
497
+};
498
+
499
+static void nrf51_nvm_register_types(void)
500
+{
501
+ type_register_static(&nrf51_nvm_info);
502
+}
503
+
504
+type_init(nrf51_nvm_register_types)
505
--
506
2.20.1
507
508
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
Instantiates UICR, FICR, FLASH and NVMC in nRF51 SOC.
4
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190201023357.22596-3-stefanha@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/nrf51_soc.h | 2 ++
13
hw/arm/nrf51_soc.c | 41 +++++++++++++++++++++++++++-----------
14
2 files changed, 31 insertions(+), 12 deletions(-)
15
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/nrf51_soc.h
19
+++ b/include/hw/arm/nrf51_soc.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/char/nrf51_uart.h"
22
#include "hw/misc/nrf51_rng.h"
23
#include "hw/gpio/nrf51_gpio.h"
24
+#include "hw/nvram/nrf51_nvm.h"
25
#include "hw/timer/nrf51_timer.h"
26
27
#define TYPE_NRF51_SOC "nrf51-soc"
28
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
29
30
NRF51UARTState uart;
31
NRF51RNGState rng;
32
+ NRF51NVMState nvm;
33
NRF51GPIOState gpio;
34
NRF51TimerState timer[NRF51_NUM_TIMERS];
35
36
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/nrf51_soc.c
39
+++ b/hw/arm/nrf51_soc.c
40
@@ -XXX,XX +XXX,XX @@
41
* are supported in the future, add a sub-class of NRF51SoC for
42
* the specific variants
43
*/
44
-#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
45
-#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
46
+#define NRF51822_FLASH_PAGES 256
47
+#define NRF51822_SRAM_PAGES 16
48
+#define NRF51822_FLASH_SIZE (NRF51822_FLASH_PAGES * NRF51_PAGE_SIZE)
49
+#define NRF51822_SRAM_SIZE (NRF51822_SRAM_PAGES * NRF51_PAGE_SIZE)
50
51
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
52
53
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
54
55
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
56
57
- memory_region_init_rom(&s->flash, OBJECT(s), "nrf51.flash", s->flash_size,
58
- &err);
59
- if (err) {
60
- error_propagate(errp, err);
61
- return;
62
- }
63
- memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
64
-
65
memory_region_init_ram(&s->sram, OBJECT(s), "nrf51.sram", s->sram_size,
66
&err);
67
if (err) {
68
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
69
qdev_get_gpio_in(DEVICE(&s->cpu),
70
BASE_TO_IRQ(NRF51_RNG_BASE)));
71
72
+ /* UICR, FICR, NVMC, FLASH */
73
+ object_property_set_uint(OBJECT(&s->nvm), s->flash_size, "flash-size",
74
+ &err);
75
+ if (err) {
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
+
80
+ object_property_set_bool(OBJECT(&s->nvm), true, "realized", &err);
81
+ if (err) {
82
+ error_propagate(errp, err);
83
+ return;
84
+ }
85
+
86
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 0);
87
+ memory_region_add_subregion_overlap(&s->container, NRF51_NVMC_BASE, mr, 0);
88
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 1);
89
+ memory_region_add_subregion_overlap(&s->container, NRF51_FICR_BASE, mr, 0);
90
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 2);
91
+ memory_region_add_subregion_overlap(&s->container, NRF51_UICR_BASE, mr, 0);
92
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->nvm), 3);
93
+ memory_region_add_subregion_overlap(&s->container, NRF51_FLASH_BASE, mr, 0);
94
+
95
/* GPIO */
96
object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
97
if (err) {
98
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
99
100
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
101
NRF51_IOMEM_SIZE);
102
- create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
103
- NRF51_FICR_SIZE);
104
create_unimplemented_device("nrf51_soc.private",
105
NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
108
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
109
TYPE_NRF51_RNG);
110
111
+ sysbus_init_child_obj(obj, "nvm", &s->nvm, sizeof(s->nvm), TYPE_NRF51_NVM);
112
+
113
sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
114
TYPE_NRF51_GPIO);
115
116
--
117
2.20.1
118
119
diff view generated by jsdifflib
Deleted patch
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
1
3
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
4
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Acked-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190201023357.22596-4-stefanha@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
tests/microbit-test.c | 108 ++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
12
13
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/tests/microbit-test.c
16
+++ b/tests/microbit-test.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/arm/nrf51.h"
19
#include "hw/char/nrf51_uart.h"
20
#include "hw/gpio/nrf51_gpio.h"
21
+#include "hw/nvram/nrf51_nvm.h"
22
#include "hw/timer/nrf51_timer.h"
23
#include "hw/i2c/microbit_i2c.h"
24
25
@@ -XXX,XX +XXX,XX @@ static void test_microbit_i2c(void)
26
qtest_quit(qts);
27
}
28
29
+#define FLASH_SIZE (256 * NRF51_PAGE_SIZE)
30
+
31
+static void fill_and_erase(QTestState *qts, hwaddr base, hwaddr size,
32
+ uint32_t address_reg)
33
+{
34
+ hwaddr i;
35
+
36
+ /* Erase Page */
37
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
38
+ qtest_writel(qts, NRF51_NVMC_BASE + address_reg, base);
39
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
40
+
41
+ /* Check memory */
42
+ for (i = 0; i < size / 4; i++) {
43
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, 0xFFFFFFFF);
44
+ }
45
+
46
+ /* Fill memory */
47
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
48
+ for (i = 0; i < size / 4; i++) {
49
+ qtest_writel(qts, base + i * 4, i);
50
+ g_assert_cmpuint(qtest_readl(qts, base + i * 4), ==, i);
51
+ }
52
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
53
+}
54
+
55
+static void test_nrf51_nvmc(void)
56
+{
57
+ uint32_t value;
58
+ hwaddr i;
59
+ QTestState *qts = qtest_init("-M microbit");
60
+
61
+ /* Test always ready */
62
+ value = qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_READY);
63
+ g_assert_cmpuint(value & 0x01, ==, 0x01);
64
+
65
+ /* Test write-read config register */
66
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x03);
67
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
68
+ ==, 0x03);
69
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
70
+ g_assert_cmpuint(qtest_readl(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG),
71
+ ==, 0x00);
72
+
73
+ /* Test PCR0 */
74
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
75
+ NRF51_NVMC_ERASEPCR0);
76
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
77
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR0);
78
+
79
+ /* Test PCR1 */
80
+ fill_and_erase(qts, NRF51_FLASH_BASE, NRF51_PAGE_SIZE,
81
+ NRF51_NVMC_ERASEPCR1);
82
+ fill_and_erase(qts, NRF51_FLASH_BASE + NRF51_PAGE_SIZE,
83
+ NRF51_PAGE_SIZE, NRF51_NVMC_ERASEPCR1);
84
+
85
+ /* Erase all */
86
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
87
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
88
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
89
+
90
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
91
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
92
+ qtest_writel(qts, NRF51_FLASH_BASE + i * 4, i);
93
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4), ==, i);
94
+ }
95
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
96
+
97
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
98
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEALL, 0x01);
99
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
100
+
101
+ for (i = 0; i < FLASH_SIZE / 4; i++) {
102
+ g_assert_cmpuint(qtest_readl(qts, NRF51_FLASH_BASE + i * 4),
103
+ ==, 0xFFFFFFFF);
104
+ }
105
+
106
+ /* Erase UICR */
107
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
108
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
109
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
110
+
111
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
112
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
113
+ ==, 0xFFFFFFFF);
114
+ }
115
+
116
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x01);
117
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
118
+ qtest_writel(qts, NRF51_UICR_BASE + i * 4, i);
119
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4), ==, i);
120
+ }
121
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
122
+
123
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x02);
124
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_ERASEUICR, 0x01);
125
+ qtest_writel(qts, NRF51_NVMC_BASE + NRF51_NVMC_CONFIG, 0x00);
126
+
127
+ for (i = 0; i < NRF51_UICR_SIZE / 4; i++) {
128
+ g_assert_cmpuint(qtest_readl(qts, NRF51_UICR_BASE + i * 4),
129
+ ==, 0xFFFFFFFF);
130
+ }
131
+
132
+ qtest_quit(qts);
133
+}
134
+
135
static void test_nrf51_gpio(void)
136
{
137
size_t i;
138
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
139
140
qtest_add_func("/microbit/nrf51/uart", test_nrf51_uart);
141
qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
142
+ qtest_add_func("/microbit/nrf51/nvmc", test_nrf51_nvmc);
143
qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
144
qtest_add_func("/microbit/microbit/i2c", test_microbit_i2c);
145
146
--
147
2.20.1
148
149
diff view generated by jsdifflib