1
ARM queue: mostly patches from me, but also the Smartfusion2 board.
1
Hi; here's the first target-arm pullreq for the 7.0 cycle.
2
2
3
thanks
3
thanks
4
-- PMM
4
-- PMM
5
5
6
The following changes since commit 9ee660e7c138595224b65ddc1c5712549f0a278c:
6
The following changes since commit 76b56fdfc9fa43ec6e5986aee33f108c6c6a511e:
7
7
8
Merge remote-tracking branch 'remotes/yongbok/tags/mips-20170921' into staging (2017-09-21 14:40:32 +0100)
8
Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2021-12-14 12:46:18 -0800)
9
9
10
are available in the git repository at:
10
are available in the Git repository at:
11
11
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170921
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211215
13
13
14
for you to fetch changes up to 6d262dcb7d108eda93813574c2061398084dc795:
14
for you to fetch changes up to aed176558806674d030a8305d989d4e6a5073359:
15
15
16
msf2: Add Emcraft's Smartfusion2 SOM kit (2017-09-21 16:36:56 +0100)
16
tests/acpi: add expected blob for VIOT test on virt machine (2021-12-15 10:35:26 +0000)
17
17
18
----------------------------------------------------------------
18
----------------------------------------------------------------
19
target-arm queue:
19
target-arm queue:
20
* more preparatory work for v8M support
20
* ITS: error reporting cleanup
21
* convert some omap devices away from old_mmio
21
* aspeed: improve documentation
22
* remove out of date ARM ARM section references in comments
22
* Fix STM32F2XX USART data register readout
23
* add the Smartfusion2 board
23
* allow emulated GICv3 to be disabled in non-TCG builds
24
* fix exception priority for singlestep, misaligned PC, bp, etc
25
* Correct calculation of tlb range invalidate length
26
* npcm7xx_emc: fix missing queue_flush
27
* virt: Add VIOT ACPI table for virtio-iommu
28
* target/i386: Use assert() to sanity-check b1 in SSE decode
29
* Don't include qemu-common unnecessarily
24
30
25
----------------------------------------------------------------
31
----------------------------------------------------------------
26
Peter Maydell (26):
32
Alex Bennée (1):
27
target/arm: Implement MSR/MRS access to NS banked registers
33
hw/intc: clean-up error reporting for failed ITS cmd
28
nvic: Add banked exception states
29
nvic: Add cached vectpending_is_s_banked state
30
nvic: Add cached vectpending_prio state
31
nvic: Implement AIRCR changes for v8M
32
nvic: Make ICSR.RETTOBASE handle banked exceptions
33
nvic: Implement NVIC_ITNS<n> registers
34
nvic: Handle banked exceptions in nvic_recompute_state()
35
nvic: Make set_pending and clear_pending take a secure parameter
36
nvic: Make SHPR registers banked
37
nvic: Compare group priority for escalation to HF
38
nvic: In escalation to HardFault, support HF not being priority -1
39
nvic: Implement v8M changes to fixed priority exceptions
40
nvic: Disable the non-secure HardFault if AIRCR.BFHFNMINS is clear
41
nvic: Handle v8M changes in nvic_exec_prio()
42
target/arm: Handle banking in negative-execution-priority check in cpu_mmu_index()
43
nvic: Make ICSR banked for v8M
44
nvic: Make SHCSR banked for v8M
45
nvic: Support banked exceptions in acknowledge and complete
46
target/arm: Remove out of date ARM ARM section references in A64 decoder
47
hw/arm/palm.c: Don't use old_mmio for static_ops
48
hw/gpio/omap_gpio.c: Don't use old_mmio
49
hw/timer/omap_synctimer.c: Don't use old_mmio
50
hw/timer/omap_gptimer: Don't use old_mmio
51
hw/i2c/omap_i2c.c: Don't use old_mmio
52
hw/arm/omap2.c: Don't use old_mmio
53
34
54
Subbaraya Sundeep (5):
35
Jean-Philippe Brucker (8):
55
msf2: Add Smartfusion2 System timer
36
hw/arm/virt-acpi-build: Add VIOT table for virtio-iommu
56
msf2: Microsemi Smartfusion2 System Register block
37
hw/arm/virt: Remove device tree restriction for virtio-iommu
57
msf2: Add Smartfusion2 SPI controller
38
hw/arm/virt: Reject instantiation of multiple IOMMUs
58
msf2: Add Smartfusion2 SoC
39
hw/arm/virt: Use object_property_set instead of qdev_prop_set
59
msf2: Add Emcraft's Smartfusion2 SOM kit
40
tests/acpi: allow updates of VIOT expected data files
41
tests/acpi: add test case for VIOT
42
tests/acpi: add expected blobs for VIOT test on q35 machine
43
tests/acpi: add expected blob for VIOT test on virt machine
60
44
61
hw/arm/Makefile.objs | 1 +
45
Joel Stanley (4):
62
hw/misc/Makefile.objs | 1 +
46
docs: aspeed: Add new boards
63
hw/ssi/Makefile.objs | 1 +
47
docs: aspeed: Update OpenBMC image URL
64
hw/timer/Makefile.objs | 1 +
48
docs: aspeed: Give an example of booting a kernel
65
include/hw/arm/msf2-soc.h | 67 +++
49
docs: aspeed: ADC is now modelled
66
include/hw/intc/armv7m_nvic.h | 33 +-
67
include/hw/misc/msf2-sysreg.h | 77 ++++
68
include/hw/ssi/mss-spi.h | 58 +++
69
include/hw/timer/mss-timer.h | 64 +++
70
target/arm/cpu.h | 62 ++-
71
hw/arm/msf2-soc.c | 238 +++++++++++
72
hw/arm/msf2-som.c | 105 +++++
73
hw/arm/omap2.c | 49 ++-
74
hw/arm/palm.c | 30 +-
75
hw/gpio/omap_gpio.c | 26 +-
76
hw/i2c/omap_i2c.c | 44 +-
77
hw/intc/armv7m_nvic.c | 913 ++++++++++++++++++++++++++++++++++------
78
hw/misc/msf2-sysreg.c | 160 +++++++
79
hw/ssi/mss-spi.c | 404 ++++++++++++++++++
80
hw/timer/mss-timer.c | 289 +++++++++++++
81
hw/timer/omap_gptimer.c | 49 ++-
82
hw/timer/omap_synctimer.c | 35 +-
83
target/arm/cpu.c | 7 +
84
target/arm/helper.c | 142 ++++++-
85
target/arm/translate-a64.c | 227 +++++-----
86
default-configs/arm-softmmu.mak | 1 +
87
hw/intc/trace-events | 13 +-
88
hw/misc/trace-events | 5 +
89
28 files changed, 2735 insertions(+), 367 deletions(-)
90
create mode 100644 include/hw/arm/msf2-soc.h
91
create mode 100644 include/hw/misc/msf2-sysreg.h
92
create mode 100644 include/hw/ssi/mss-spi.h
93
create mode 100644 include/hw/timer/mss-timer.h
94
create mode 100644 hw/arm/msf2-soc.c
95
create mode 100644 hw/arm/msf2-som.c
96
create mode 100644 hw/misc/msf2-sysreg.c
97
create mode 100644 hw/ssi/mss-spi.c
98
create mode 100644 hw/timer/mss-timer.c
99
50
51
Olivier Hériveaux (1):
52
Fix STM32F2XX USART data register readout
53
54
Patrick Venture (1):
55
hw/net: npcm7xx_emc fix missing queue_flush
56
57
Peter Maydell (6):
58
target/i386: Use assert() to sanity-check b1 in SSE decode
59
include/hw/i386: Don't include qemu-common.h in .h files
60
target/hexagon/cpu.h: don't include qemu-common.h
61
target/rx/cpu.h: Don't include qemu-common.h
62
hw/arm: Don't include qemu-common.h unnecessarily
63
target/arm: Correct calculation of tlb range invalidate length
64
65
Philippe Mathieu-Daudé (2):
66
hw/intc/arm_gicv3: Extract gicv3_set_gicv3state from arm_gicv3_cpuif.c
67
hw/intc/arm_gicv3: Introduce CONFIG_ARM_GIC_TCG Kconfig selector
68
69
Richard Henderson (10):
70
target/arm: Hoist pc_next to a local variable in aarch64_tr_translate_insn
71
target/arm: Hoist pc_next to a local variable in arm_tr_translate_insn
72
target/arm: Hoist pc_next to a local variable in thumb_tr_translate_insn
73
target/arm: Split arm_pre_translate_insn
74
target/arm: Advance pc for arch single-step exception
75
target/arm: Split compute_fsr_fsc out of arm_deliver_fault
76
target/arm: Take an exception if PC is misaligned
77
target/arm: Assert thumb pc is aligned
78
target/arm: Suppress bp for exceptions with more priority
79
tests/tcg: Add arm and aarch64 pc alignment tests
80
81
docs/system/arm/aspeed.rst | 26 ++++++++++++----
82
include/hw/i386/microvm.h | 1 -
83
include/hw/i386/x86.h | 1 -
84
target/arm/helper.h | 1 +
85
target/arm/syndrome.h | 5 +++
86
target/hexagon/cpu.h | 1 -
87
target/rx/cpu.h | 1 -
88
hw/arm/boot.c | 1 -
89
hw/arm/digic_boards.c | 1 -
90
hw/arm/highbank.c | 1 -
91
hw/arm/npcm7xx_boards.c | 1 -
92
hw/arm/sbsa-ref.c | 1 -
93
hw/arm/stm32f405_soc.c | 1 -
94
hw/arm/vexpress.c | 1 -
95
hw/arm/virt-acpi-build.c | 7 +++++
96
hw/arm/virt.c | 21 ++++++-------
97
hw/char/stm32f2xx_usart.c | 3 +-
98
hw/intc/arm_gicv3.c | 2 +-
99
hw/intc/arm_gicv3_cpuif.c | 10 +-----
100
hw/intc/arm_gicv3_cpuif_common.c | 22 +++++++++++++
101
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++--------
102
hw/net/npcm7xx_emc.c | 18 +++++------
103
hw/virtio/virtio-iommu-pci.c | 12 ++------
104
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++------------
105
linux-user/hexagon/cpu_loop.c | 1 +
106
target/arm/debug_helper.c | 23 ++++++++++++++
107
target/arm/gdbstub.c | 9 ++++--
108
target/arm/helper.c | 6 ++--
109
target/arm/machine.c | 10 ++++++
110
target/arm/tlb_helper.c | 63 ++++++++++++++++++++++++++++----------
111
target/arm/translate-a64.c | 23 ++++++++++++--
112
target/arm/translate.c | 58 ++++++++++++++++++++++++++---------
113
target/i386/tcg/translate.c | 12 ++------
114
tests/qtest/bios-tables-test.c | 38 +++++++++++++++++++++++
115
tests/tcg/aarch64/pcalign-a64.c | 37 ++++++++++++++++++++++
116
tests/tcg/arm/pcalign-a32.c | 46 ++++++++++++++++++++++++++++
117
hw/arm/Kconfig | 1 +
118
hw/intc/Kconfig | 5 +++
119
hw/intc/meson.build | 11 ++++---
120
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
121
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
122
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
123
tests/tcg/aarch64/Makefile.target | 4 +--
124
tests/tcg/arm/Makefile.target | 4 +++
125
44 files changed, 429 insertions(+), 145 deletions(-)
126
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
127
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
128
create mode 100644 tests/tcg/arm/pcalign-a32.c
129
create mode 100644 tests/data/acpi/q35/DSDT.viot
130
create mode 100644 tests/data/acpi/q35/VIOT.viot
131
create mode 100644 tests/data/acpi/virt/VIOT
132
diff view generated by jsdifflib
1
Instead of looking up the pending priority
1
From: Alex Bennée <alex.bennee@linaro.org>
2
in nvic_pending_prio(), cache it in a new state struct
3
field. The calculation of the pending priority given
4
the interrupt number is more complicated in v8M with
5
the security extension, so the caching will be worthwhile.
6
2
7
This changes nvic_pending_prio() from returning a full
3
While trying to debug a GIC ITS failure I saw some guest errors that
8
(group + subpriority) priority value to returning a group
4
had poor formatting as well as leaving me confused as to what failed.
9
priority. This doesn't require changes to its callsites
5
As most of the checks aren't possible without a valid dte split that
10
because we use it only in comparisons of the form
6
check apart and then check the other conditions in steps. This avoids
11
execution_prio > nvic_pending_prio()
7
us relying on undefined data.
12
and execution priority is always a group priority, so
13
a test (exec prio > full prio) is true if and only if
14
(execprio > group_prio).
15
8
16
(Architecturally the expected comparison is with the
9
I still get a failure with the current kvm-unit-tests but at least I
17
group priority for this sort of "would we preempt" test;
10
know (partially) why now:
18
we were only doing a test with a full priority as an
19
optimisation to avoid the mask, which is possible
20
precisely because the two comparisons always give the
21
same answer.)
22
11
12
Exception return from AArch64 EL1 to AArch64 EL1 PC 0x40080588
13
PASS: gicv3: its-trigger: inv/invall: dev2/eventid=20 now triggers an LPI
14
ITS: MAPD devid=2 size = 0x8 itt=0x40430000 valid=0
15
INT dev_id=2 event_id=20
16
process_its_cmd: invalid command attributes: invalid dte: 0 for 2 (MEM_TX: 0)
17
PASS: gicv3: its-trigger: mapd valid=false: no LPI after device unmap
18
SUMMARY: 6 tests, 1 unexpected failures
19
20
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Message-id: 20211112170454.3158925-1-alex.bennee@linaro.org
23
Cc: Shashi Mallela <shashi.mallela@linaro.org>
24
Cc: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 1505240046-11454-5-git-send-email-peter.maydell@linaro.org
26
---
26
---
27
include/hw/intc/armv7m_nvic.h | 2 ++
27
hw/intc/arm_gicv3_its.c | 39 +++++++++++++++++++++++++++------------
28
hw/intc/armv7m_nvic.c | 23 +++++++++++++----------
28
1 file changed, 27 insertions(+), 12 deletions(-)
29
hw/intc/trace-events | 2 +-
30
3 files changed, 16 insertions(+), 11 deletions(-)
31
29
32
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
30
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
33
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
34
--- a/include/hw/intc/armv7m_nvic.h
32
--- a/hw/intc/arm_gicv3_its.c
35
+++ b/include/hw/intc/armv7m_nvic.h
33
+++ b/hw/intc/arm_gicv3_its.c
36
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
34
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
37
* - vectpending
35
if (res != MEMTX_OK) {
38
* - vectpending_is_secure
36
return result;
39
* - exception_prio
37
}
40
+ * - vectpending_prio
38
+ } else {
41
*/
39
+ qemu_log_mask(LOG_GUEST_ERROR,
42
unsigned int vectpending; /* highest prio pending enabled exception */
40
+ "%s: invalid command attributes: "
43
/* true if vectpending is a banked secure exception, ie it is in
41
+ "invalid dte: %"PRIx64" for %d (MEM_TX: %d)\n",
44
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
42
+ __func__, dte, devid, res);
45
*/
43
+ return result;
46
bool vectpending_is_s_banked;
47
int exception_prio; /* group prio of the highest prio active exception */
48
+ int vectpending_prio; /* group prio of the exeception in vectpending */
49
50
MemoryRegion sysregmem;
51
MemoryRegion sysreg_ns_mem;
52
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/armv7m_nvic.c
55
+++ b/hw/intc/armv7m_nvic.c
56
@@ -XXX,XX +XXX,XX @@ static const uint8_t nvic_id[] = {
57
58
static int nvic_pending_prio(NVICState *s)
59
{
60
- /* return the priority of the current pending interrupt,
61
+ /* return the group priority of the current pending interrupt,
62
* or NVIC_NOEXC_PRIO if no interrupt is pending
63
*/
64
- return s->vectpending ? s->vectors[s->vectpending].prio : NVIC_NOEXC_PRIO;
65
+ return s->vectpending_prio;
66
}
67
68
/* Return the value of the ISCR RETTOBASE bit:
69
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state(NVICState *s)
70
active_prio &= nvic_gprio_mask(s);
71
}
44
}
72
45
73
+ if (pend_prio > 0) {
46
- if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
74
+ pend_prio &= nvic_gprio_mask(s);
47
- !cte_valid || (eventid > max_eventid)) {
75
+ }
76
+
48
+
77
s->vectpending = pend_irq;
49
+ /*
78
+ s->vectpending_prio = pend_prio;
50
+ * In this implementation, in case of guest errors we ignore the
79
s->exception_prio = active_prio;
51
+ * command and move onto the next command in the queue.
80
52
+ */
81
- trace_nvic_recompute_state(s->vectpending, s->exception_prio);
53
+ if (devid > s->dt.maxids.max_devids) {
82
+ trace_nvic_recompute_state(s->vectpending,
54
qemu_log_mask(LOG_GUEST_ERROR,
83
+ s->vectpending_prio,
55
- "%s: invalid command attributes "
84
+ s->exception_prio);
56
- "devid %d or eventid %d or invalid dte %d or"
85
}
57
- "invalid cte %d or invalid ite %d\n",
86
58
- __func__, devid, eventid, dte_valid, cte_valid,
87
/* Return the current execution priority of the CPU
59
- ite_valid);
88
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque)
60
- /*
89
CPUARMState *env = &s->cpu->env;
61
- * in this implementation, in case of error
90
const int pending = s->vectpending;
62
- * we ignore this command and move onto the next
91
const int running = nvic_exec_prio(s);
63
- * command in the queue
92
- int pendgroupprio;
64
- */
93
VecInfo *vec;
65
+ "%s: invalid command attributes: devid %d>%d",
94
66
+ __func__, devid, s->dt.maxids.max_devids);
95
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
67
+
96
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque)
68
+ } else if (!dte_valid || !ite_valid || !cte_valid) {
97
assert(vec->enabled);
69
+ qemu_log_mask(LOG_GUEST_ERROR,
98
assert(vec->pending);
70
+ "%s: invalid command attributes: "
99
71
+ "dte: %s, ite: %s, cte: %s\n",
100
- pendgroupprio = vec->prio;
72
+ __func__,
101
- if (pendgroupprio > 0) {
73
+ dte_valid ? "valid" : "invalid",
102
- pendgroupprio &= nvic_gprio_mask(s);
74
+ ite_valid ? "valid" : "invalid",
103
- }
75
+ cte_valid ? "valid" : "invalid");
104
- assert(pendgroupprio < running);
76
+ } else if (eventid > max_eventid) {
105
+ assert(s->vectpending_prio < running);
77
+ qemu_log_mask(LOG_GUEST_ERROR,
106
78
+ "%s: invalid command attributes: eventid %d > %d\n",
107
- trace_nvic_acknowledge_irq(pending, vec->prio);
79
+ __func__, eventid, max_eventid);
108
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
80
} else {
109
81
/*
110
vec->active = 1;
82
* Current implementation only supports rdbase == procnum
111
vec->pending = 0;
112
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
113
s->exception_prio = NVIC_NOEXC_PRIO;
114
s->vectpending = 0;
115
s->vectpending_is_s_banked = false;
116
+ s->vectpending_prio = NVIC_NOEXC_PRIO;
117
}
118
119
static void nvic_systick_trigger(void *opaque, int n, int level)
120
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/intc/trace-events
123
+++ b/hw/intc/trace-events
124
@@ -XXX,XX +XXX,XX @@ gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x
125
gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d"
126
127
# hw/intc/armv7m_nvic.c
128
-nvic_recompute_state(int vectpending, int exception_prio) "NVIC state recomputed: vectpending %d exception_prio %d"
129
+nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
130
nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d"
131
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
132
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
133
--
83
--
134
2.7.4
84
2.25.1
135
85
136
86
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Add X11, FP5280G2, G220A, Rainier and Fuji. Mention that Swift will be
4
removed in v7.0.
5
6
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20211117065752.330632-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 7 ++++++-
12
1 file changed, 6 insertions(+), 1 deletion(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ AST2400 SoC based machines :
19
20
- ``palmetto-bmc`` OpenPOWER Palmetto POWER8 BMC
21
- ``quanta-q71l-bmc`` OpenBMC Quanta BMC
22
+- ``supermicrox11-bmc`` Supermicro X11 BMC
23
24
AST2500 SoC based machines :
25
26
@@ -XXX,XX +XXX,XX @@ AST2500 SoC based machines :
27
- ``romulus-bmc`` OpenPOWER Romulus POWER9 BMC
28
- ``witherspoon-bmc`` OpenPOWER Witherspoon POWER9 BMC
29
- ``sonorapass-bmc`` OCP SonoraPass BMC
30
-- ``swift-bmc`` OpenPOWER Swift BMC POWER9
31
+- ``swift-bmc`` OpenPOWER Swift BMC POWER9 (to be removed in v7.0)
32
+- ``fp5280g2-bmc`` Inspur FP5280G2 BMC
33
+- ``g220a-bmc`` Bytedance G220A BMC
34
35
AST2600 SoC based machines :
36
37
- ``ast2600-evb`` Aspeed AST2600 Evaluation board (Cortex-A7)
38
- ``tacoma-bmc`` OpenPOWER Witherspoon POWER9 AST2600 BMC
39
+- ``rainier-bmc`` IBM Rainier POWER10 BMC
40
+- ``fuji-bmc`` Facebook Fuji BMC
41
42
Supported devices
43
-----------------
44
--
45
2.25.1
46
47
diff view generated by jsdifflib
1
Don't use old_mmio in the memory region ops struct.
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
This is the latest URL for the OpenBMC CI. The old URL still works, but
4
redirects.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-3-joel@jms.id.au
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1505580378-9044-7-git-send-email-peter.maydell@linaro.org
6
---
10
---
7
hw/arm/omap2.c | 49 +++++++++++++++++++++++++++++++++++++------------
11
docs/system/arm/aspeed.rst | 2 +-
8
1 file changed, 37 insertions(+), 12 deletions(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
9
13
10
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
11
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/arm/omap2.c
16
--- a/docs/system/arm/aspeed.rst
13
+++ b/hw/arm/omap2.c
17
+++ b/docs/system/arm/aspeed.rst
14
@@ -XXX,XX +XXX,XX @@ static void omap_sysctl_write(void *opaque, hwaddr addr,
18
@@ -XXX,XX +XXX,XX @@ The Aspeed machines can be started using the ``-kernel`` option to
15
}
19
load a Linux kernel or from a firmware. Images can be downloaded from
16
}
20
the OpenBMC jenkins :
17
21
18
+static uint64_t omap_sysctl_readfn(void *opaque, hwaddr addr,
22
- https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/distro=ubuntu,label=docker-builder
19
+ unsigned size)
23
+ https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
20
+{
24
21
+ switch (size) {
25
or directly from the OpenBMC GitHub release repository :
22
+ case 1:
23
+ return omap_sysctl_read8(opaque, addr);
24
+ case 2:
25
+ return omap_badwidth_read32(opaque, addr); /* TODO */
26
+ case 4:
27
+ return omap_sysctl_read(opaque, addr);
28
+ default:
29
+ g_assert_not_reached();
30
+ }
31
+}
32
+
33
+static void omap_sysctl_writefn(void *opaque, hwaddr addr,
34
+ uint64_t value, unsigned size)
35
+{
36
+ switch (size) {
37
+ case 1:
38
+ omap_sysctl_write8(opaque, addr, value);
39
+ break;
40
+ case 2:
41
+ omap_badwidth_write32(opaque, addr, value); /* TODO */
42
+ break;
43
+ case 4:
44
+ omap_sysctl_write(opaque, addr, value);
45
+ break;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
49
+}
50
+
51
static const MemoryRegionOps omap_sysctl_ops = {
52
- .old_mmio = {
53
- .read = {
54
- omap_sysctl_read8,
55
- omap_badwidth_read32,    /* TODO */
56
- omap_sysctl_read,
57
- },
58
- .write = {
59
- omap_sysctl_write8,
60
- omap_badwidth_write32,    /* TODO */
61
- omap_sysctl_write,
62
- },
63
- },
64
+ .read = omap_sysctl_readfn,
65
+ .write = omap_sysctl_writefn,
66
+ .valid.min_access_size = 1,
67
+ .valid.max_access_size = 4,
68
.endianness = DEVICE_NATIVE_ENDIAN,
69
};
70
26
71
--
27
--
72
2.7.4
28
2.25.1
73
29
74
30
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
A common use case for the ASPEED machine is to boot a Linux kernel.
4
Provide a full example command line.
5
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20211117065752.330632-4-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/aspeed.rst | 15 ++++++++++++---
12
1 file changed, 12 insertions(+), 3 deletions(-)
13
14
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
15
index XXXXXXX..XXXXXXX 100644
16
--- a/docs/system/arm/aspeed.rst
17
+++ b/docs/system/arm/aspeed.rst
18
@@ -XXX,XX +XXX,XX @@ Missing devices
19
Boot options
20
------------
21
22
-The Aspeed machines can be started using the ``-kernel`` option to
23
-load a Linux kernel or from a firmware. Images can be downloaded from
24
-the OpenBMC jenkins :
25
+The Aspeed machines can be started using the ``-kernel`` and ``-dtb`` options
26
+to load a Linux kernel or from a firmware. Images can be downloaded from the
27
+OpenBMC jenkins :
28
29
https://jenkins.openbmc.org/job/ci-openbmc/lastSuccessfulBuild/
30
31
@@ -XXX,XX +XXX,XX @@ or directly from the OpenBMC GitHub release repository :
32
33
https://github.com/openbmc/openbmc/releases
34
35
+To boot a kernel directly from a Linux build tree:
36
+
37
+.. code-block:: bash
38
+
39
+ $ qemu-system-arm -M ast2600-evb -nographic \
40
+ -kernel arch/arm/boot/zImage \
41
+ -dtb arch/arm/boot/dts/aspeed-ast2600-evb.dtb \
42
+ -initrd rootfs.cpio
43
+
44
The image should be attached as an MTD drive. Run :
45
46
.. code-block:: bash
47
--
48
2.25.1
49
50
diff view generated by jsdifflib
1
In armv7m_nvic_set_pending() we have to compare the
1
From: Joel Stanley <joel@jms.id.au>
2
priority of an exception against the execution priority
3
to decide whether it needs to be escalated to HardFault.
4
In the specification this is a comparison against the
5
exception's group priority; for v7M we implemented it
6
as a comparison against the raw exception priority
7
because the two comparisons will always give the
8
same answer. For v8M the existence of AIRCR.PRIS and
9
the possibility of different PRIGROUP values for secure
10
and nonsecure exceptions means we need to explicitly
11
calculate the vector's group priority for this check.
12
2
3
Move it to the supported list.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Message-id: 20211117065752.330632-5-joel@jms.id.au
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 1505240046-11454-12-git-send-email-peter.maydell@linaro.org
16
---
8
---
17
hw/intc/armv7m_nvic.c | 2 +-
9
docs/system/arm/aspeed.rst | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
19
11
20
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
12
diff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/armv7m_nvic.c
14
--- a/docs/system/arm/aspeed.rst
23
+++ b/hw/intc/armv7m_nvic.c
15
+++ b/docs/system/arm/aspeed.rst
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
16
@@ -XXX,XX +XXX,XX @@ Supported devices
25
int running = nvic_exec_prio(s);
17
* Front LEDs (PCA9552 on I2C bus)
26
bool escalate = false;
18
* LPC Peripheral Controller (a subset of subdevices are supported)
27
19
* Hash/Crypto Engine (HACE) - Hash support only. TODO: HMAC and RSA
28
- if (vec->prio >= running) {
20
+ * ADC
29
+ if (exc_group_prio(s, vec->prio, secure) >= running) {
21
30
trace_nvic_escalate_prio(irq, vec->prio, running);
22
31
escalate = true;
23
Missing devices
32
} else if (!vec->enabled) {
24
---------------
25
26
* Coprocessor support
27
- * ADC (out of tree implementation)
28
* PWM and Fan Controller
29
* Slave GPIO Controller
30
* Super I/O Controller
33
--
31
--
34
2.7.4
32
2.25.1
35
33
36
34
diff view generated by jsdifflib
1
The ICSR NVIC register is banked for v8M. This doesn't
1
From: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
2
require any new state, but it does mean that some bits
3
are controlled by BFHNFNMINS and some bits must work
4
with the correct banked exception. There is also a new
5
in v8M PENDNMICLR bit.
6
2
3
Fix issue where the data register may be overwritten by next character
4
reception before being read and returned.
5
6
Signed-off-by: Olivier Hériveaux <olivier.heriveaux@ledger.fr>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20211128120723.4053-1-olivier.heriveaux@ledger.fr
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1505240046-11454-18-git-send-email-peter.maydell@linaro.org
10
---
11
---
11
hw/intc/armv7m_nvic.c | 45 ++++++++++++++++++++++++++++++++-------------
12
hw/char/stm32f2xx_usart.c | 3 ++-
12
1 file changed, 32 insertions(+), 13 deletions(-)
13
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
15
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
17
--- a/hw/char/stm32f2xx_usart.c
17
+++ b/hw/intc/armv7m_nvic.c
18
+++ b/hw/char/stm32f2xx_usart.c
18
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
19
@@ -XXX,XX +XXX,XX @@ static uint64_t stm32f2xx_usart_read(void *opaque, hwaddr addr,
19
}
20
return retvalue;
20
case 0xd00: /* CPUID Base. */
21
case USART_DR:
21
return cpu->midr;
22
DB_PRINT("Value: 0x%" PRIx32 ", %c\n", s->usart_dr, (char) s->usart_dr);
22
- case 0xd04: /* Interrupt Control State. */
23
+ retvalue = s->usart_dr & 0x3FF;
23
+ case 0xd04: /* Interrupt Control State (ICSR) */
24
s->usart_sr &= ~USART_SR_RXNE;
24
/* VECTACTIVE */
25
qemu_chr_fe_accept_input(&s->chr);
25
val = cpu->env.v7m.exception;
26
qemu_set_irq(s->irq, 0);
26
/* VECTPENDING */
27
- return s->usart_dr & 0x3FF;
27
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
28
+ return retvalue;
28
if (nvic_rettobase(s)) {
29
case USART_BRR:
29
val |= (1 << 11);
30
return s->usart_brr;
30
}
31
case USART_CR1:
31
- /* PENDSTSET */
32
- if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {
33
- val |= (1 << 26);
34
- }
35
- /* PENDSVSET */
36
- if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {
37
- val |= (1 << 28);
38
+ if (attrs.secure) {
39
+ /* PENDSTSET */
40
+ if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) {
41
+ val |= (1 << 26);
42
+ }
43
+ /* PENDSVSET */
44
+ if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) {
45
+ val |= (1 << 28);
46
+ }
47
+ } else {
48
+ /* PENDSTSET */
49
+ if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) {
50
+ val |= (1 << 26);
51
+ }
52
+ /* PENDSVSET */
53
+ if (s->vectors[ARMV7M_EXCP_PENDSV].pending) {
54
+ val |= (1 << 28);
55
+ }
56
}
57
/* NMIPENDSET */
58
- if (s->vectors[ARMV7M_EXCP_NMI].pending) {
59
+ if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
60
+ s->vectors[ARMV7M_EXCP_NMI].pending) {
61
val |= (1 << 31);
62
}
63
- /* ISRPREEMPT not implemented */
64
+ /* ISRPREEMPT: RES0 when halting debug not implemented */
65
+ /* STTNS: RES0 for the Main Extension */
66
return val;
67
case 0xd08: /* Vector Table Offset. */
68
return cpu->env.v7m.vecbase[attrs.secure];
69
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
70
nvic_irq_update(s);
71
break;
72
}
73
- case 0xd04: /* Interrupt Control State. */
74
- if (value & (1 << 31)) {
75
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
76
+ case 0xd04: /* Interrupt Control State (ICSR) */
77
+ if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
78
+ if (value & (1 << 31)) {
79
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
80
+ } else if (value & (1 << 30) &&
81
+ arm_feature(&cpu->env, ARM_FEATURE_V8)) {
82
+ /* PENDNMICLR didn't exist in v7M */
83
+ armv7m_nvic_clear_pending(s, ARMV7M_EXCP_NMI, false);
84
+ }
85
}
86
if (value & (1 << 28)) {
87
armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
88
--
32
--
89
2.7.4
33
2.25.1
90
34
91
35
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Emulated Emcraft's Smartfusion2 System On Module starter
3
gicv3_set_gicv3state() is used by arm_gicv3_common.c in
4
kit.
4
arm_gicv3_common_realize(). Since we want to restrict
5
arm_gicv3_cpuif.c to TCG, extract gicv3_set_gicv3state()
6
to a new file. Add this file to the meson 'specific'
7
source set, since it needs access to "cpu.h".
5
8
6
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20170920201737.25723-6-f4bug@amsat.org
11
Message-id: 20211115223619.2599282-2-philmd@redhat.com
9
[PMD: drop cpu_model to directly use cpu type]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
hw/arm/Makefile.objs | 2 +-
14
hw/intc/arm_gicv3_cpuif.c | 10 +---------
13
hw/arm/msf2-som.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++
15
hw/intc/arm_gicv3_cpuif_common.c | 22 ++++++++++++++++++++++
14
2 files changed, 106 insertions(+), 1 deletion(-)
16
hw/intc/meson.build | 1 +
15
create mode 100644 hw/arm/msf2-som.c
17
3 files changed, 24 insertions(+), 9 deletions(-)
18
create mode 100644 hw/intc/arm_gicv3_cpuif_common.c
16
19
17
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
20
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/Makefile.objs
22
--- a/hw/intc/arm_gicv3_cpuif.c
20
+++ b/hw/arm/Makefile.objs
23
+++ b/hw/intc/arm_gicv3_cpuif.c
21
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
24
@@ -XXX,XX +XXX,XX @@
22
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
25
/*
23
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
26
- * ARM Generic Interrupt Controller v3
24
obj-$(CONFIG_MPS2) += mps2.o
27
+ * ARM Generic Interrupt Controller v3 (emulation)
25
-obj-$(CONFIG_MSF2) += msf2-soc.o
28
*
26
+obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
29
* Copyright (c) 2016 Linaro Limited
27
diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c
30
* Written by Peter Maydell
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/irq.h"
33
#include "cpu.h"
34
35
-void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
36
-{
37
- ARMCPU *arm_cpu = ARM_CPU(cpu);
38
- CPUARMState *env = &arm_cpu->env;
39
-
40
- env->gicv3state = (void *)s;
41
-};
42
-
43
static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
44
{
45
return env->gicv3state;
46
diff --git a/hw/intc/arm_gicv3_cpuif_common.c b/hw/intc/arm_gicv3_cpuif_common.c
28
new file mode 100644
47
new file mode 100644
29
index XXXXXXX..XXXXXXX
48
index XXXXXXX..XXXXXXX
30
--- /dev/null
49
--- /dev/null
31
+++ b/hw/arm/msf2-som.c
50
+++ b/hw/intc/arm_gicv3_cpuif_common.c
32
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
52
+/* SPDX-License-Identifier: GPL-2.0-or-later */
33
+/*
53
+/*
34
+ * SmartFusion2 SOM starter kit(from Emcraft) emulation.
54
+ * ARM Generic Interrupt Controller v3
35
+ *
55
+ *
36
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
56
+ * Copyright (c) 2016 Linaro Limited
57
+ * Written by Peter Maydell
37
+ *
58
+ *
38
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
59
+ * This code is licensed under the GPL, version 2 or (at your option)
39
+ * of this software and associated documentation files (the "Software"), to deal
60
+ * any later version.
40
+ * in the Software without restriction, including without limitation the rights
41
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ * copies of the Software, and to permit persons to whom the Software is
43
+ * furnished to do so, subject to the following conditions:
44
+ *
45
+ * The above copyright notice and this permission notice shall be included in
46
+ * all copies or substantial portions of the Software.
47
+ *
48
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
51
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
54
+ * THE SOFTWARE.
55
+ */
61
+ */
56
+
62
+
57
+#include "qemu/osdep.h"
63
+#include "qemu/osdep.h"
58
+#include "qapi/error.h"
64
+#include "gicv3_internal.h"
59
+#include "qemu/error-report.h"
60
+#include "hw/boards.h"
61
+#include "hw/arm/arm.h"
62
+#include "exec/address-spaces.h"
63
+#include "qemu/cutils.h"
64
+#include "hw/arm/msf2-soc.h"
65
+#include "cpu.h"
65
+#include "cpu.h"
66
+
66
+
67
+#define DDR_BASE_ADDRESS 0xA0000000
67
+void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
68
+#define DDR_SIZE (64 * M_BYTE)
68
+{
69
+ ARMCPU *arm_cpu = ARM_CPU(cpu);
70
+ CPUARMState *env = &arm_cpu->env;
69
+
71
+
70
+#define M2S010_ENVM_SIZE (256 * K_BYTE)
72
+ env->gicv3state = (void *)s;
71
+#define M2S010_ESRAM_SIZE (64 * K_BYTE)
73
+};
72
+
74
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
73
+static void emcraft_sf2_s2s010_init(MachineState *machine)
75
index XXXXXXX..XXXXXXX 100644
74
+{
76
--- a/hw/intc/meson.build
75
+ DeviceState *dev;
77
+++ b/hw/intc/meson.build
76
+ DeviceState *spi_flash;
78
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
77
+ MSF2State *soc;
79
78
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
80
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
79
+ DriveInfo *dinfo = drive_get_next(IF_MTD);
81
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
80
+ qemu_irq cs_line;
82
+specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
81
+ SSIBus *spi_bus;
83
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
82
+ MemoryRegion *sysmem = get_system_memory();
84
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
83
+ MemoryRegion *ddr = g_new(MemoryRegion, 1);
85
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
84
+
85
+ if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
86
+ error_report("This board can only be used with CPU %s",
87
+ mc->default_cpu_type);
88
+ }
89
+
90
+ memory_region_init_ram(ddr, NULL, "ddr-ram", DDR_SIZE,
91
+ &error_fatal);
92
+ memory_region_add_subregion(sysmem, DDR_BASE_ADDRESS, ddr);
93
+
94
+ dev = qdev_create(NULL, TYPE_MSF2_SOC);
95
+ qdev_prop_set_string(dev, "part-name", "M2S010");
96
+ qdev_prop_set_string(dev, "cpu-type", mc->default_cpu_type);
97
+
98
+ qdev_prop_set_uint64(dev, "eNVM-size", M2S010_ENVM_SIZE);
99
+ qdev_prop_set_uint64(dev, "eSRAM-size", M2S010_ESRAM_SIZE);
100
+
101
+ /*
102
+ * CPU clock and peripheral clocks(APB0, APB1)are configurable
103
+ * in Libero. CPU clock is divided by APB0 and APB1 divisors for
104
+ * peripherals. Emcraft's SoM kit comes with these settings by default.
105
+ */
106
+ qdev_prop_set_uint32(dev, "m3clk", 142 * 1000000);
107
+ qdev_prop_set_uint32(dev, "apb0div", 2);
108
+ qdev_prop_set_uint32(dev, "apb1div", 2);
109
+
110
+ object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
111
+
112
+ soc = MSF2_SOC(dev);
113
+
114
+ /* Attach SPI flash to SPI0 controller */
115
+ spi_bus = (SSIBus *)qdev_get_child_bus(dev, "spi0");
116
+ spi_flash = ssi_create_slave_no_init(spi_bus, "s25sl12801");
117
+ qdev_prop_set_uint8(spi_flash, "spansion-cr2nv", 1);
118
+ if (dinfo) {
119
+ qdev_prop_set_drive(spi_flash, "drive", blk_by_legacy_dinfo(dinfo),
120
+ &error_fatal);
121
+ }
122
+ qdev_init_nofail(spi_flash);
123
+ cs_line = qdev_get_gpio_in_named(spi_flash, SSI_GPIO_CS, 0);
124
+ sysbus_connect_irq(SYS_BUS_DEVICE(&soc->spi[0]), 1, cs_line);
125
+
126
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
127
+ soc->envm_size);
128
+}
129
+
130
+static void emcraft_sf2_machine_init(MachineClass *mc)
131
+{
132
+ mc->desc = "SmartFusion2 SOM kit from Emcraft (M2S010)";
133
+ mc->init = emcraft_sf2_s2s010_init;
134
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m3");
135
+}
136
+
137
+DEFINE_MACHINE("emcraft-sf2", emcraft_sf2_machine_init)
138
--
86
--
139
2.7.4
87
2.25.1
140
88
141
89
diff view generated by jsdifflib
1
For v8M, the NVIC has a new set of registers per interrupt,
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
NVIC_ITNS<n>. These determine whether the interrupt targets Secure
3
or Non-secure state. Implement the register read/write code for
4
these, and make them cause NVIC_IABR, NVIC_ICER, NVIC_ISER,
5
NVIC_ICPR, NVIC_IPR and NVIC_ISPR to RAZ/WI for non-secure
6
accesses to fields corresponding to interrupts which are
7
configured to target secure state.
8
2
3
The TYPE_ARM_GICV3 device is an emulated one. When using
4
KVM, it is recommended to use the TYPE_KVM_ARM_GICV3 device
5
(which uses in-kernel support).
6
7
When using --with-devices-FOO, it is possible to build a
8
binary with a specific set of devices. When this binary is
9
restricted to KVM accelerator, the TYPE_ARM_GICV3 device is
10
irrelevant, and it is desirable to remove it from the binary.
11
12
Therefore introduce the CONFIG_ARM_GIC_TCG Kconfig selector
13
which select the files required to have the TYPE_ARM_GICV3
14
device, but also allowing to de-select this device.
15
16
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Message-id: 20211115223619.2599282-3-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 1505240046-11454-8-git-send-email-peter.maydell@linaro.org
12
---
20
---
13
include/hw/intc/armv7m_nvic.h | 3 ++
21
hw/intc/arm_gicv3.c | 2 +-
14
hw/intc/armv7m_nvic.c | 74 +++++++++++++++++++++++++++++++++++++++----
22
hw/intc/Kconfig | 5 +++++
15
2 files changed, 70 insertions(+), 7 deletions(-)
23
hw/intc/meson.build | 10 ++++++----
24
3 files changed, 12 insertions(+), 5 deletions(-)
16
25
17
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
26
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/intc/armv7m_nvic.h
28
--- a/hw/intc/arm_gicv3.c
20
+++ b/include/hw/intc/armv7m_nvic.h
29
+++ b/hw/intc/arm_gicv3.c
21
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
30
@@ -XXX,XX +XXX,XX @@
22
/* The PRIGROUP field in AIRCR is banked */
31
/*
23
uint32_t prigroup[M_REG_NUM_BANKS];
32
- * ARM Generic Interrupt Controller v3
24
33
+ * ARM Generic Interrupt Controller v3 (emulation)
25
+ /* v8M NVIC_ITNS state (stored as a bool per bit) */
34
*
26
+ bool itns[NVIC_MAX_VECTORS];
35
* Copyright (c) 2015 Huawei.
36
* Copyright (c) 2016 Linaro Limited
37
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/intc/Kconfig
40
+++ b/hw/intc/Kconfig
41
@@ -XXX,XX +XXX,XX @@ config APIC
42
select MSI_NONBROKEN
43
select I8259
44
45
+config ARM_GIC_TCG
46
+ bool
47
+ default y
48
+ depends on ARM_GIC && TCG
27
+
49
+
28
/* The following fields are all cached state that can be recalculated
50
config ARM_GIC_KVM
29
* from the vectors[] and sec_vectors[] arrays and the prigroup field:
51
bool
30
* - vectpending
52
default y
31
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
53
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
32
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/armv7m_nvic.c
55
--- a/hw/intc/meson.build
34
+++ b/hw/intc/armv7m_nvic.c
56
+++ b/hw/intc/meson.build
35
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
57
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
36
switch (offset) {
58
'arm_gic.c',
37
case 4: /* Interrupt Control Type. */
59
'arm_gic_common.c',
38
return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1;
60
'arm_gicv2m.c',
39
+ case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
61
- 'arm_gicv3.c',
40
+ {
62
'arm_gicv3_common.c',
41
+ int startvec = 32 * (offset - 0x380) + NVIC_FIRST_IRQ;
63
- 'arm_gicv3_dist.c',
42
+ int i;
64
'arm_gicv3_its_common.c',
43
+
65
- 'arm_gicv3_redist.c',
44
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
66
+))
45
+ goto bad_offset;
67
+softmmu_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files(
46
+ }
68
+ 'arm_gicv3.c',
47
+ if (!attrs.secure) {
69
+ 'arm_gicv3_dist.c',
48
+ return 0;
70
'arm_gicv3_its.c',
49
+ }
71
+ 'arm_gicv3_redist.c',
50
+ val = 0;
72
))
51
+ for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
73
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
52
+ if (s->itns[startvec + i]) {
74
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
53
+ val |= (1 << i);
75
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP_PMU', if_true: files('xlnx-pmu-iomod-in
54
+ }
76
specific_ss.add(when: 'CONFIG_ALLWINNER_A10_PIC', if_true: files('allwinner-a10-pic.c'))
55
+ }
77
specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic.c', 'apic_common.c'))
56
+ return val;
78
specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_common.c'))
57
+ }
79
-specific_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif.c'))
58
case 0xd00: /* CPUID Base. */
80
+specific_ss.add(when: 'CONFIG_ARM_GIC_TCG', if_true: files('arm_gicv3_cpuif.c'))
59
return cpu->midr;
81
specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'))
60
case 0xd04: /* Interrupt Control State. */
82
specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: files('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c'))
61
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
83
specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
62
ARMCPU *cpu = s->cpu;
63
64
switch (offset) {
65
+ case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */
66
+ {
67
+ int startvec = 32 * (offset - 0x380) + NVIC_FIRST_IRQ;
68
+ int i;
69
+
70
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
71
+ goto bad_offset;
72
+ }
73
+ if (!attrs.secure) {
74
+ break;
75
+ }
76
+ for (i = 0; i < 32 && startvec + i < s->num_irq; i++) {
77
+ s->itns[startvec + i] = (value >> i) & 1;
78
+ }
79
+ nvic_irq_update(s);
80
+ break;
81
+ }
82
case 0xd04: /* Interrupt Control State. */
83
if (value & (1 << 31)) {
84
armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI);
85
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
86
startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */
87
88
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
89
- if (s->vectors[startvec + i].enabled) {
90
+ if (s->vectors[startvec + i].enabled &&
91
+ (attrs.secure || s->itns[startvec + i])) {
92
val |= (1 << i);
93
}
94
}
95
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
96
val = 0;
97
startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */
98
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
99
- if (s->vectors[startvec + i].pending) {
100
+ if (s->vectors[startvec + i].pending &&
101
+ (attrs.secure || s->itns[startvec + i])) {
102
val |= (1 << i);
103
}
104
}
105
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
106
startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */
107
108
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
109
- if (s->vectors[startvec + i].active) {
110
+ if (s->vectors[startvec + i].active &&
111
+ (attrs.secure || s->itns[startvec + i])) {
112
val |= (1 << i);
113
}
114
}
115
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
116
startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */
117
118
for (i = 0; i < size && startvec + i < s->num_irq; i++) {
119
- val |= s->vectors[startvec + i].prio << (8 * i);
120
+ if (attrs.secure || s->itns[startvec + i]) {
121
+ val |= s->vectors[startvec + i].prio << (8 * i);
122
+ }
123
}
124
break;
125
case 0xd18 ... 0xd23: /* System Handler Priority. */
126
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
127
startvec = 8 * (offset - 0x180) + NVIC_FIRST_IRQ;
128
129
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
130
- if (value & (1 << i)) {
131
+ if (value & (1 << i) &&
132
+ (attrs.secure || s->itns[startvec + i])) {
133
s->vectors[startvec + i].enabled = setval;
134
}
135
}
136
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
137
startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
138
139
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
140
- if (value & (1 << i)) {
141
+ if (value & (1 << i) &&
142
+ (attrs.secure || s->itns[startvec + i])) {
143
s->vectors[startvec + i].pending = setval;
144
}
145
}
146
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
147
startvec = 8 * (offset - 0x400) + NVIC_FIRST_IRQ; /* vector # */
148
149
for (i = 0; i < size && startvec + i < s->num_irq; i++) {
150
- set_prio(s, startvec + i, (value >> (i * 8)) & 0xff);
151
+ if (attrs.secure || s->itns[startvec + i]) {
152
+ set_prio(s, startvec + i, (value >> (i * 8)) & 0xff);
153
+ }
154
}
155
nvic_irq_update(s);
156
return MEMTX_OK;
157
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic_security = {
158
VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1,
159
vmstate_VecInfo, VecInfo),
160
VMSTATE_UINT32(prigroup[M_REG_S], NVICState),
161
+ VMSTATE_BOOL_ARRAY(itns, NVICState, NVIC_MAX_VECTORS),
162
VMSTATE_END_OF_LIST()
163
}
164
};
165
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
166
s->vectpending = 0;
167
s->vectpending_is_s_banked = false;
168
s->vectpending_prio = NVIC_NOEXC_PRIO;
169
+
170
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
171
+ memset(s->itns, 0, sizeof(s->itns));
172
+ } else {
173
+ /* This state is constant and not guest accessible in a non-security
174
+ * NVIC; we set the bits to true to avoid having to do a feature
175
+ * bit check in the NVIC enable/pend/etc register accessors.
176
+ */
177
+ int i;
178
+
179
+ for (i = NVIC_FIRST_IRQ; i < ARRAY_SIZE(s->itns); i++) {
180
+ s->itns[i] = true;
181
+ }
182
+ }
183
}
184
185
static void nvic_systick_trigger(void *opaque, int n, int level)
186
--
84
--
187
2.7.4
85
2.25.1
188
86
189
87
diff view generated by jsdifflib
1
In the A64 decoder, we have a lot of references to section numbers
1
From: Richard Henderson <richard.henderson@linaro.org>
2
from version A.a of the v8A ARM ARM (DDI0487). This version of the
3
document is now long obsolete (we are currently on revision B.a),
4
and various intervening versions renumbered all the sections.
5
2
6
The most recent B.a version of the document doesn't assign
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
section numbers at all to the individual instruction classes
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
in the way that the various A.x versions did. The simplest thing
9
to do is just to delete all the out of date C.x.x references.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20170915150849.23557-1-peter.maydell@linaro.org
14
---
6
---
15
target/arm/translate-a64.c | 227 +++++++++++++++++++++++----------------------
7
target/arm/translate-a64.c | 7 ++++---
16
1 file changed, 114 insertions(+), 113 deletions(-)
8
1 file changed, 4 insertions(+), 3 deletions(-)
17
9
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
12
--- a/target/arm/translate-a64.c
21
+++ b/target/arm/translate-a64.c
13
+++ b/target/arm/translate-a64.c
22
@@ -XXX,XX +XXX,XX @@ static inline AArch64DecodeFn *lookup_disas_fn(const AArch64DecodeTable *table,
14
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
23
}
15
{
24
16
DisasContext *s = container_of(dcbase, DisasContext, base);
25
/*
17
CPUARMState *env = cpu->env_ptr;
26
- * the instruction disassembly implemented here matches
18
+ uint64_t pc = s->base.pc_next;
27
- * the instruction encoding classifications in chapter 3 (C3)
19
uint32_t insn;
28
- * of the ARM Architecture Reference Manual (DDI0487A_a)
20
29
+ * The instruction disassembly implemented here matches
21
if (s->ss_active && !s->pstate_ss) {
30
+ * the instruction encoding classifications in chapter C4
22
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
31
+ * of the ARM Architecture Reference Manual (DDI0487B_a);
23
return;
32
+ * classification names and decode diagrams here should generally
33
+ * match up with those in the manual.
34
*/
35
36
-/* C3.2.7 Unconditional branch (immediate)
37
+/* Unconditional branch (immediate)
38
* 31 30 26 25 0
39
* +----+-----------+-------------------------------------+
40
* | op | 0 0 1 0 1 | imm26 |
41
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_imm(DisasContext *s, uint32_t insn)
42
uint64_t addr = s->pc + sextract32(insn, 0, 26) * 4 - 4;
43
44
if (insn & (1U << 31)) {
45
- /* C5.6.26 BL Branch with link */
46
+ /* BL Branch with link */
47
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
48
}
24
}
49
25
50
- /* C5.6.20 B Branch / C5.6.26 BL Branch with link */
26
- s->pc_curr = s->base.pc_next;
51
+ /* B Branch / BL Branch with link */
27
- insn = arm_ldl_code(env, &s->base, s->base.pc_next, s->sctlr_b);
52
gen_goto_tb(s, 0, addr);
28
+ s->pc_curr = pc;
53
}
29
+ insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
54
30
s->insn = insn;
55
-/* C3.2.1 Compare & branch (immediate)
31
- s->base.pc_next += 4;
56
+/* Compare and branch (immediate)
32
+ s->base.pc_next = pc + 4;
57
* 31 30 25 24 23 5 4 0
33
58
* +----+-------------+----+---------------------+--------+
34
s->fp_access_checked = false;
59
* | sf | 0 1 1 0 1 0 | op | imm19 | Rt |
35
s->sve_access_checked = false;
60
@@ -XXX,XX +XXX,XX @@ static void disas_comp_b_imm(DisasContext *s, uint32_t insn)
61
gen_goto_tb(s, 1, addr);
62
}
63
64
-/* C3.2.5 Test & branch (immediate)
65
+/* Test and branch (immediate)
66
* 31 30 25 24 23 19 18 5 4 0
67
* +----+-------------+----+-------+-------------+------+
68
* | b5 | 0 1 1 0 1 1 | op | b40 | imm14 | Rt |
69
@@ -XXX,XX +XXX,XX @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
70
gen_goto_tb(s, 1, addr);
71
}
72
73
-/* C3.2.2 / C5.6.19 Conditional branch (immediate)
74
+/* Conditional branch (immediate)
75
* 31 25 24 23 5 4 3 0
76
* +---------------+----+---------------------+----+------+
77
* | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
78
@@ -XXX,XX +XXX,XX @@ static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
79
}
80
}
81
82
-/* C5.6.68 HINT */
83
+/* HINT instruction group, including various allocated HINTs */
84
static void handle_hint(DisasContext *s, uint32_t insn,
85
unsigned int op1, unsigned int op2, unsigned int crm)
86
{
87
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
88
}
89
}
90
91
-/* C5.6.130 MSR (immediate) - move immediate to processor state field */
92
+/* MSR (immediate) - move immediate to processor state field */
93
static void handle_msr_i(DisasContext *s, uint32_t insn,
94
unsigned int op1, unsigned int op2, unsigned int crm)
95
{
96
@@ -XXX,XX +XXX,XX @@ static void gen_set_nzcv(TCGv_i64 tcg_rt)
97
tcg_temp_free_i32(nzcv);
98
}
99
100
-/* C5.6.129 MRS - move from system register
101
- * C5.6.131 MSR (register) - move to system register
102
- * C5.6.204 SYS
103
- * C5.6.205 SYSL
104
+/* MRS - move from system register
105
+ * MSR (register) - move to system register
106
+ * SYS
107
+ * SYSL
108
* These are all essentially the same insn in 'read' and 'write'
109
* versions, with varying op0 fields.
110
*/
111
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
112
}
113
}
114
115
-/* C3.2.4 System
116
+/* System
117
* 31 22 21 20 19 18 16 15 12 11 8 7 5 4 0
118
* +---------------------+---+-----+-----+-------+-------+-----+------+
119
* | 1 1 0 1 0 1 0 1 0 0 | L | op0 | op1 | CRn | CRm | op2 | Rt |
120
@@ -XXX,XX +XXX,XX @@ static void disas_system(DisasContext *s, uint32_t insn)
121
return;
122
}
123
switch (crn) {
124
- case 2: /* C5.6.68 HINT */
125
+ case 2: /* HINT (including allocated hints like NOP, YIELD, etc) */
126
handle_hint(s, insn, op1, op2, crm);
127
break;
128
case 3: /* CLREX, DSB, DMB, ISB */
129
handle_sync(s, insn, op1, op2, crm);
130
break;
131
- case 4: /* C5.6.130 MSR (immediate) */
132
+ case 4: /* MSR (immediate) */
133
handle_msr_i(s, insn, op1, op2, crm);
134
break;
135
default:
136
@@ -XXX,XX +XXX,XX @@ static void disas_system(DisasContext *s, uint32_t insn)
137
handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
138
}
139
140
-/* C3.2.3 Exception generation
141
+/* Exception generation
142
*
143
* 31 24 23 21 20 5 4 2 1 0
144
* +-----------------+-----+------------------------+-----+----+
145
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
146
}
147
}
148
149
-/* C3.2.7 Unconditional branch (register)
150
+/* Unconditional branch (register)
151
* 31 25 24 21 20 16 15 10 9 5 4 0
152
* +---------------+-------+-------+-------+------+-------+
153
* | 1 1 0 1 0 1 1 | opc | op2 | op3 | Rn | op4 |
154
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
155
s->base.is_jmp = DISAS_JUMP;
156
}
157
158
-/* C3.2 Branches, exception generating and system instructions */
159
+/* Branches, exception generating and system instructions */
160
static void disas_b_exc_sys(DisasContext *s, uint32_t insn)
161
{
162
switch (extract32(insn, 25, 7)) {
163
@@ -XXX,XX +XXX,XX @@ static bool disas_ldst_compute_iss_sf(int size, bool is_signed, int opc)
164
return regsize == 64;
165
}
166
167
-/* C3.3.6 Load/store exclusive
168
+/* Load/store exclusive
169
*
170
* 31 30 29 24 23 22 21 20 16 15 14 10 9 5 4 0
171
* +-----+-------------+----+---+----+------+----+-------+------+------+
172
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
173
}
174
175
/*
176
- * C3.3.5 Load register (literal)
177
+ * Load register (literal)
178
*
179
* 31 30 29 27 26 25 24 23 5 4 0
180
* +-----+-------+---+-----+-------------------+-------+
181
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
182
}
183
184
/*
185
- * C5.6.80 LDNP (Load Pair - non-temporal hint)
186
- * C5.6.81 LDP (Load Pair - non vector)
187
- * C5.6.82 LDPSW (Load Pair Signed Word - non vector)
188
- * C5.6.176 STNP (Store Pair - non-temporal hint)
189
- * C5.6.177 STP (Store Pair - non vector)
190
- * C6.3.165 LDNP (Load Pair of SIMD&FP - non-temporal hint)
191
- * C6.3.165 LDP (Load Pair of SIMD&FP)
192
- * C6.3.284 STNP (Store Pair of SIMD&FP - non-temporal hint)
193
- * C6.3.284 STP (Store Pair of SIMD&FP)
194
+ * LDNP (Load Pair - non-temporal hint)
195
+ * LDP (Load Pair - non vector)
196
+ * LDPSW (Load Pair Signed Word - non vector)
197
+ * STNP (Store Pair - non-temporal hint)
198
+ * STP (Store Pair - non vector)
199
+ * LDNP (Load Pair of SIMD&FP - non-temporal hint)
200
+ * LDP (Load Pair of SIMD&FP)
201
+ * STNP (Store Pair of SIMD&FP - non-temporal hint)
202
+ * STP (Store Pair of SIMD&FP)
203
*
204
* 31 30 29 27 26 25 24 23 22 21 15 14 10 9 5 4 0
205
* +-----+-------+---+---+-------+---+-----------------------------+
206
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
207
}
208
209
/*
210
- * C3.3.8 Load/store (immediate post-indexed)
211
- * C3.3.9 Load/store (immediate pre-indexed)
212
- * C3.3.12 Load/store (unscaled immediate)
213
+ * Load/store (immediate post-indexed)
214
+ * Load/store (immediate pre-indexed)
215
+ * Load/store (unscaled immediate)
216
*
217
* 31 30 29 27 26 25 24 23 22 21 20 12 11 10 9 5 4 0
218
* +----+-------+---+-----+-----+---+--------+-----+------+------+
219
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
220
}
221
222
/*
223
- * C3.3.10 Load/store (register offset)
224
+ * Load/store (register offset)
225
*
226
* 31 30 29 27 26 25 24 23 22 21 20 16 15 13 12 11 10 9 5 4 0
227
* +----+-------+---+-----+-----+---+------+-----+--+-----+----+----+
228
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
229
}
230
231
/*
232
- * C3.3.13 Load/store (unsigned immediate)
233
+ * Load/store (unsigned immediate)
234
*
235
* 31 30 29 27 26 25 24 23 22 21 10 9 5
236
* +----+-------+---+-----+-----+------------+-------+------+
237
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
238
}
239
}
240
241
-/* C3.3.1 AdvSIMD load/store multiple structures
242
+/* AdvSIMD load/store multiple structures
243
*
244
* 31 30 29 23 22 21 16 15 12 11 10 9 5 4 0
245
* +---+---+---------------+---+-------------+--------+------+------+------+
246
* | 0 | Q | 0 0 1 1 0 0 0 | L | 0 0 0 0 0 0 | opcode | size | Rn | Rt |
247
* +---+---+---------------+---+-------------+--------+------+------+------+
248
*
249
- * C3.3.2 AdvSIMD load/store multiple structures (post-indexed)
250
+ * AdvSIMD load/store multiple structures (post-indexed)
251
*
252
* 31 30 29 23 22 21 20 16 15 12 11 10 9 5 4 0
253
* +---+---+---------------+---+---+---------+--------+------+------+------+
254
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
255
tcg_temp_free_i64(tcg_addr);
256
}
257
258
-/* C3.3.3 AdvSIMD load/store single structure
259
+/* AdvSIMD load/store single structure
260
*
261
* 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
262
* +---+---+---------------+-----+-----------+-----+---+------+------+------+
263
* | 0 | Q | 0 0 1 1 0 1 0 | L R | 0 0 0 0 0 | opc | S | size | Rn | Rt |
264
* +---+---+---------------+-----+-----------+-----+---+------+------+------+
265
*
266
- * C3.3.4 AdvSIMD load/store single structure (post-indexed)
267
+ * AdvSIMD load/store single structure (post-indexed)
268
*
269
* 31 30 29 23 22 21 20 16 15 13 12 11 10 9 5 4 0
270
* +---+---+---------------+-----+-----------+-----+---+------+------+------+
271
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
272
tcg_temp_free_i64(tcg_addr);
273
}
274
275
-/* C3.3 Loads and stores */
276
+/* Loads and stores */
277
static void disas_ldst(DisasContext *s, uint32_t insn)
278
{
279
switch (extract32(insn, 24, 6)) {
280
@@ -XXX,XX +XXX,XX @@ static void disas_ldst(DisasContext *s, uint32_t insn)
281
}
282
}
283
284
-/* C3.4.6 PC-rel. addressing
285
+/* PC-rel. addressing
286
* 31 30 29 28 24 23 5 4 0
287
* +----+-------+-----------+-------------------+------+
288
* | op | immlo | 1 0 0 0 0 | immhi | Rd |
289
@@ -XXX,XX +XXX,XX @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn)
290
}
291
292
/*
293
- * C3.4.1 Add/subtract (immediate)
294
+ * Add/subtract (immediate)
295
*
296
* 31 30 29 28 24 23 22 21 10 9 5 4 0
297
* +--+--+--+-----------+-----+-------------+-----+-----+
298
@@ -XXX,XX +XXX,XX @@ static bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
299
return true;
300
}
301
302
-/* C3.4.4 Logical (immediate)
303
+/* Logical (immediate)
304
* 31 30 29 28 23 22 21 16 15 10 9 5 4 0
305
* +----+-----+-------------+---+------+------+------+------+
306
* | sf | opc | 1 0 0 1 0 0 | N | immr | imms | Rn | Rd |
307
@@ -XXX,XX +XXX,XX @@ static void disas_logic_imm(DisasContext *s, uint32_t insn)
308
}
309
310
/*
311
- * C3.4.5 Move wide (immediate)
312
+ * Move wide (immediate)
313
*
314
* 31 30 29 28 23 22 21 20 5 4 0
315
* +--+-----+-------------+-----+----------------+------+
316
@@ -XXX,XX +XXX,XX @@ static void disas_movw_imm(DisasContext *s, uint32_t insn)
317
}
318
}
319
320
-/* C3.4.2 Bitfield
321
+/* Bitfield
322
* 31 30 29 28 23 22 21 16 15 10 9 5 4 0
323
* +----+-----+-------------+---+------+------+------+------+
324
* | sf | opc | 1 0 0 1 1 0 | N | immr | imms | Rn | Rd |
325
@@ -XXX,XX +XXX,XX @@ static void disas_bitfield(DisasContext *s, uint32_t insn)
326
}
327
}
328
329
-/* C3.4.3 Extract
330
+/* Extract
331
* 31 30 29 28 23 22 21 20 16 15 10 9 5 4 0
332
* +----+------+-------------+---+----+------+--------+------+------+
333
* | sf | op21 | 1 0 0 1 1 1 | N | o0 | Rm | imms | Rn | Rd |
334
@@ -XXX,XX +XXX,XX @@ static void disas_extract(DisasContext *s, uint32_t insn)
335
}
336
}
337
338
-/* C3.4 Data processing - immediate */
339
+/* Data processing - immediate */
340
static void disas_data_proc_imm(DisasContext *s, uint32_t insn)
341
{
342
switch (extract32(insn, 23, 6)) {
343
@@ -XXX,XX +XXX,XX @@ static void shift_reg_imm(TCGv_i64 dst, TCGv_i64 src, int sf,
344
}
345
}
346
347
-/* C3.5.10 Logical (shifted register)
348
+/* Logical (shifted register)
349
* 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0
350
* +----+-----+-----------+-------+---+------+--------+------+------+
351
* | sf | opc | 0 1 0 1 0 | shift | N | Rm | imm6 | Rn | Rd |
352
@@ -XXX,XX +XXX,XX @@ static void disas_logic_reg(DisasContext *s, uint32_t insn)
353
}
354
355
/*
356
- * C3.5.1 Add/subtract (extended register)
357
+ * Add/subtract (extended register)
358
*
359
* 31|30|29|28 24|23 22|21|20 16|15 13|12 10|9 5|4 0|
360
* +--+--+--+-----------+-----+--+-------+------+------+----+----+
361
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_ext_reg(DisasContext *s, uint32_t insn)
362
}
363
364
/*
365
- * C3.5.2 Add/subtract (shifted register)
366
+ * Add/subtract (shifted register)
367
*
368
* 31 30 29 28 24 23 22 21 20 16 15 10 9 5 4 0
369
* +--+--+--+-----------+-----+--+-------+---------+------+------+
370
@@ -XXX,XX +XXX,XX @@ static void disas_add_sub_reg(DisasContext *s, uint32_t insn)
371
tcg_temp_free_i64(tcg_result);
372
}
373
374
-/* C3.5.9 Data-processing (3 source)
375
-
376
- 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0
377
- +--+------+-----------+------+------+----+------+------+------+
378
- |sf| op54 | 1 1 0 1 1 | op31 | Rm | o0 | Ra | Rn | Rd |
379
- +--+------+-----------+------+------+----+------+------+------+
380
-
381
+/* Data-processing (3 source)
382
+ *
383
+ * 31 30 29 28 24 23 21 20 16 15 14 10 9 5 4 0
384
+ * +--+------+-----------+------+------+----+------+------+------+
385
+ * |sf| op54 | 1 1 0 1 1 | op31 | Rm | o0 | Ra | Rn | Rd |
386
+ * +--+------+-----------+------+------+----+------+------+------+
387
*/
388
static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
389
{
390
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
391
tcg_temp_free_i64(tcg_tmp);
392
}
393
394
-/* C3.5.3 - Add/subtract (with carry)
395
+/* Add/subtract (with carry)
396
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
397
* +--+--+--+------------------------+------+---------+------+-----+
398
* |sf|op| S| 1 1 0 1 0 0 0 0 | rm | opcode2 | Rn | Rd |
399
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
400
}
401
}
402
403
-/* C3.5.4 - C3.5.5 Conditional compare (immediate / register)
404
+/* Conditional compare (immediate / register)
405
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0
406
* +--+--+--+------------------------+--------+------+----+--+------+--+-----+
407
* |sf|op| S| 1 1 0 1 0 0 1 0 |imm5/rm | cond |i/r |o2| Rn |o3|nzcv |
408
@@ -XXX,XX +XXX,XX @@ static void disas_cc(DisasContext *s, uint32_t insn)
409
tcg_temp_free_i32(tcg_t2);
410
}
411
412
-/* C3.5.6 Conditional select
413
+/* Conditional select
414
* 31 30 29 28 21 20 16 15 12 11 10 9 5 4 0
415
* +----+----+---+-----------------+------+------+-----+------+------+
416
* | sf | op | S | 1 1 0 1 0 1 0 0 | Rm | cond | op2 | Rn | Rd |
417
@@ -XXX,XX +XXX,XX @@ static void handle_rbit(DisasContext *s, unsigned int sf,
418
}
419
}
420
421
-/* C5.6.149 REV with sf==1, opcode==3 ("REV64") */
422
+/* REV with sf==1, opcode==3 ("REV64") */
423
static void handle_rev64(DisasContext *s, unsigned int sf,
424
unsigned int rn, unsigned int rd)
425
{
426
@@ -XXX,XX +XXX,XX @@ static void handle_rev64(DisasContext *s, unsigned int sf,
427
tcg_gen_bswap64_i64(cpu_reg(s, rd), cpu_reg(s, rn));
428
}
429
430
-/* C5.6.149 REV with sf==0, opcode==2
431
- * C5.6.151 REV32 (sf==1, opcode==2)
432
+/* REV with sf==0, opcode==2
433
+ * REV32 (sf==1, opcode==2)
434
*/
435
static void handle_rev32(DisasContext *s, unsigned int sf,
436
unsigned int rn, unsigned int rd)
437
@@ -XXX,XX +XXX,XX @@ static void handle_rev32(DisasContext *s, unsigned int sf,
438
}
439
}
440
441
-/* C5.6.150 REV16 (opcode==1) */
442
+/* REV16 (opcode==1) */
443
static void handle_rev16(DisasContext *s, unsigned int sf,
444
unsigned int rn, unsigned int rd)
445
{
446
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
447
tcg_temp_free_i64(tcg_tmp);
448
}
449
450
-/* C3.5.7 Data-processing (1 source)
451
+/* Data-processing (1 source)
452
* 31 30 29 28 21 20 16 15 10 9 5 4 0
453
* +----+---+---+-----------------+---------+--------+------+------+
454
* | sf | 1 | S | 1 1 0 1 0 1 1 0 | opcode2 | opcode | Rn | Rd |
455
@@ -XXX,XX +XXX,XX @@ static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
456
}
457
}
458
459
-/* C5.6.115 LSLV, C5.6.118 LSRV, C5.6.17 ASRV, C5.6.154 RORV */
460
+/* LSLV, LSRV, ASRV, RORV */
461
static void handle_shift_reg(DisasContext *s,
462
enum a64_shift_type shift_type, unsigned int sf,
463
unsigned int rm, unsigned int rn, unsigned int rd)
464
@@ -XXX,XX +XXX,XX @@ static void handle_crc32(DisasContext *s,
465
tcg_temp_free_i32(tcg_bytes);
466
}
467
468
-/* C3.5.8 Data-processing (2 source)
469
+/* Data-processing (2 source)
470
* 31 30 29 28 21 20 16 15 10 9 5 4 0
471
* +----+---+---+-----------------+------+--------+------+------+
472
* | sf | 0 | S | 1 1 0 1 0 1 1 0 | Rm | opcode | Rn | Rd |
473
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
474
}
475
}
476
477
-/* C3.5 Data processing - register */
478
+/* Data processing - register */
479
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
480
{
481
switch (extract32(insn, 24, 5)) {
482
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
483
tcg_temp_free_i64(tcg_flags);
484
}
485
486
-/* C3.6.22 Floating point compare
487
+/* Floating point compare
488
* 31 30 29 28 24 23 22 21 20 16 15 14 13 10 9 5 4 0
489
* +---+---+---+-----------+------+---+------+-----+---------+------+-------+
490
* | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | op | 1 0 0 0 | Rn | op2 |
491
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
492
handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
493
}
494
495
-/* C3.6.23 Floating point conditional compare
496
+/* Floating point conditional compare
497
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0
498
* +---+---+---+-----------+------+---+------+------+-----+------+----+------+
499
* | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 0 1 | Rn | op | nzcv |
500
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
501
}
502
}
503
504
-/* C3.6.24 Floating point conditional select
505
+/* Floating point conditional select
506
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
507
* +---+---+---+-----------+------+---+------+------+-----+------+------+
508
* | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | cond | 1 1 | Rn | Rd |
509
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
510
tcg_temp_free_i64(t_true);
511
}
512
513
-/* C3.6.25 Floating-point data-processing (1 source) - single precision */
514
+/* Floating-point data-processing (1 source) - single precision */
515
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
516
{
517
TCGv_ptr fpst;
518
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
519
tcg_temp_free_i32(tcg_res);
520
}
521
522
-/* C3.6.25 Floating-point data-processing (1 source) - double precision */
523
+/* Floating-point data-processing (1 source) - double precision */
524
static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
525
{
526
TCGv_ptr fpst;
527
@@ -XXX,XX +XXX,XX @@ static void handle_fp_fcvt(DisasContext *s, int opcode,
528
}
529
}
530
531
-/* C3.6.25 Floating point data-processing (1 source)
532
+/* Floating point data-processing (1 source)
533
* 31 30 29 28 24 23 22 21 20 15 14 10 9 5 4 0
534
* +---+---+---+-----------+------+---+--------+-----------+------+------+
535
* | M | 0 | S | 1 1 1 1 0 | type | 1 | opcode | 1 0 0 0 0 | Rn | Rd |
536
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
537
}
538
}
539
540
-/* C3.6.26 Floating-point data-processing (2 source) - single precision */
541
+/* Floating-point data-processing (2 source) - single precision */
542
static void handle_fp_2src_single(DisasContext *s, int opcode,
543
int rd, int rn, int rm)
544
{
545
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_single(DisasContext *s, int opcode,
546
tcg_temp_free_i32(tcg_res);
547
}
548
549
-/* C3.6.26 Floating-point data-processing (2 source) - double precision */
550
+/* Floating-point data-processing (2 source) - double precision */
551
static void handle_fp_2src_double(DisasContext *s, int opcode,
552
int rd, int rn, int rm)
553
{
554
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
555
tcg_temp_free_i64(tcg_res);
556
}
557
558
-/* C3.6.26 Floating point data-processing (2 source)
559
+/* Floating point data-processing (2 source)
560
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
561
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
562
* | M | 0 | S | 1 1 1 1 0 | type | 1 | Rm | opcode | 1 0 | Rn | Rd |
563
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
564
}
565
}
566
567
-/* C3.6.27 Floating-point data-processing (3 source) - single precision */
568
+/* Floating-point data-processing (3 source) - single precision */
569
static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
570
int rd, int rn, int rm, int ra)
571
{
572
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
573
tcg_temp_free_i32(tcg_res);
574
}
575
576
-/* C3.6.27 Floating-point data-processing (3 source) - double precision */
577
+/* Floating-point data-processing (3 source) - double precision */
578
static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
579
int rd, int rn, int rm, int ra)
580
{
581
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
582
tcg_temp_free_i64(tcg_res);
583
}
584
585
-/* C3.6.27 Floating point data-processing (3 source)
586
+/* Floating point data-processing (3 source)
587
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
588
* +---+---+---+-----------+------+----+------+----+------+------+------+
589
* | M | 0 | S | 1 1 1 1 1 | type | o1 | Rm | o0 | Ra | Rn | Rd |
590
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
591
}
592
}
593
594
-/* C3.6.28 Floating point immediate
595
+/* Floating point immediate
596
* 31 30 29 28 24 23 22 21 20 13 12 10 9 5 4 0
597
* +---+---+---+-----------+------+---+------------+-------+------+------+
598
* | M | 0 | S | 1 1 1 1 0 | type | 1 | imm8 | 1 0 0 | imm5 | Rd |
599
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
600
tcg_temp_free_i32(tcg_shift);
601
}
602
603
-/* C3.6.29 Floating point <-> fixed point conversions
604
+/* Floating point <-> fixed point conversions
605
* 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0
606
* +----+---+---+-----------+------+---+-------+--------+-------+------+------+
607
* | sf | 0 | S | 1 1 1 1 0 | type | 0 | rmode | opcode | scale | Rn | Rd |
608
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
609
}
610
}
611
612
-/* C3.6.30 Floating point <-> integer conversions
613
+/* Floating point <-> integer conversions
614
* 31 30 29 28 24 23 22 21 20 19 18 16 15 10 9 5 4 0
615
* +----+---+---+-----------+------+---+-------+-----+-------------+----+----+
616
* | sf | 0 | S | 1 1 1 1 0 | type | 1 | rmode | opc | 0 0 0 0 0 0 | Rn | Rd |
617
@@ -XXX,XX +XXX,XX @@ static void do_ext64(DisasContext *s, TCGv_i64 tcg_left, TCGv_i64 tcg_right,
618
tcg_temp_free_i64(tcg_tmp);
619
}
620
621
-/* C3.6.1 EXT
622
+/* EXT
623
* 31 30 29 24 23 22 21 20 16 15 14 11 10 9 5 4 0
624
* +---+---+-------------+-----+---+------+---+------+---+------+------+
625
* | 0 | Q | 1 0 1 1 1 0 | op2 | 0 | Rm | 0 | imm4 | 0 | Rn | Rd |
626
@@ -XXX,XX +XXX,XX @@ static void disas_simd_ext(DisasContext *s, uint32_t insn)
627
tcg_temp_free_i64(tcg_resh);
628
}
629
630
-/* C3.6.2 TBL/TBX
631
+/* TBL/TBX
632
* 31 30 29 24 23 22 21 20 16 15 14 13 12 11 10 9 5 4 0
633
* +---+---+-------------+-----+---+------+---+-----+----+-----+------+------+
634
* | 0 | Q | 0 0 1 1 1 0 | op2 | 0 | Rm | 0 | len | op | 0 0 | Rn | Rd |
635
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
636
tcg_temp_free_i64(tcg_resh);
637
}
638
639
-/* C3.6.3 ZIP/UZP/TRN
640
+/* ZIP/UZP/TRN
641
* 31 30 29 24 23 22 21 20 16 15 14 12 11 10 9 5 4 0
642
* +---+---+-------------+------+---+------+---+------------------+------+
643
* | 0 | Q | 0 0 1 1 1 0 | size | 0 | Rm | 0 | opc | 1 0 | Rn | Rd |
644
@@ -XXX,XX +XXX,XX @@ static void do_minmaxop(DisasContext *s, TCGv_i32 tcg_elt1, TCGv_i32 tcg_elt2,
645
}
646
}
647
648
-/* C3.6.4 AdvSIMD across lanes
649
+/* AdvSIMD across lanes
650
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
651
* +---+---+---+-----------+------+-----------+--------+-----+------+------+
652
* | 0 | Q | U | 0 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 | Rn | Rd |
653
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
654
tcg_temp_free_i64(tcg_res);
655
}
656
657
-/* C6.3.31 DUP (Element, Vector)
658
+/* DUP (Element, Vector)
659
*
660
* 31 30 29 21 20 16 15 10 9 5 4 0
661
* +---+---+-------------------+--------+-------------+------+------+
662
@@ -XXX,XX +XXX,XX @@ static void handle_simd_dupe(DisasContext *s, int is_q, int rd, int rn,
663
tcg_temp_free_i64(tmp);
664
}
665
666
-/* C6.3.31 DUP (element, scalar)
667
+/* DUP (element, scalar)
668
* 31 21 20 16 15 10 9 5 4 0
669
* +-----------------------+--------+-------------+------+------+
670
* | 0 1 0 1 1 1 1 0 0 0 0 | imm5 | 0 0 0 0 0 1 | Rn | Rd |
671
@@ -XXX,XX +XXX,XX @@ static void handle_simd_dupes(DisasContext *s, int rd, int rn,
672
tcg_temp_free_i64(tmp);
673
}
674
675
-/* C6.3.32 DUP (General)
676
+/* DUP (General)
677
*
678
* 31 30 29 21 20 16 15 10 9 5 4 0
679
* +---+---+-------------------+--------+-------------+------+------+
680
@@ -XXX,XX +XXX,XX @@ static void handle_simd_dupg(DisasContext *s, int is_q, int rd, int rn,
681
}
682
}
683
684
-/* C6.3.150 INS (Element)
685
+/* INS (Element)
686
*
687
* 31 21 20 16 15 14 11 10 9 5 4 0
688
* +-----------------------+--------+------------+---+------+------+
689
@@ -XXX,XX +XXX,XX @@ static void handle_simd_inse(DisasContext *s, int rd, int rn,
690
}
691
692
693
-/* C6.3.151 INS (General)
694
+/* INS (General)
695
*
696
* 31 21 20 16 15 10 9 5 4 0
697
* +-----------------------+--------+-------------+------+------+
698
@@ -XXX,XX +XXX,XX @@ static void handle_simd_insg(DisasContext *s, int rd, int rn, int imm5)
699
}
700
701
/*
702
- * C6.3.321 UMOV (General)
703
- * C6.3.237 SMOV (General)
704
+ * UMOV (General)
705
+ * SMOV (General)
706
*
707
* 31 30 29 21 20 16 15 12 10 9 5 4 0
708
* +---+---+-------------------+--------+-------------+------+------+
709
@@ -XXX,XX +XXX,XX @@ static void handle_simd_umov_smov(DisasContext *s, int is_q, int is_signed,
710
}
711
}
712
713
-/* C3.6.5 AdvSIMD copy
714
+/* AdvSIMD copy
715
* 31 30 29 28 21 20 16 15 14 11 10 9 5 4 0
716
* +---+---+----+-----------------+------+---+------+---+------+------+
717
* | 0 | Q | op | 0 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 | Rn | Rd |
718
@@ -XXX,XX +XXX,XX @@ static void disas_simd_copy(DisasContext *s, uint32_t insn)
719
}
720
}
721
722
-/* C3.6.6 AdvSIMD modified immediate
723
+/* AdvSIMD modified immediate
724
* 31 30 29 28 19 18 16 15 12 11 10 9 5 4 0
725
* +---+---+----+---------------------+-----+-------+----+---+-------+------+
726
* | 0 | Q | op | 0 1 1 1 1 0 0 0 0 0 | abc | cmode | o2 | 1 | defgh | Rd |
727
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
728
tcg_temp_free_i64(tcg_imm);
729
}
730
731
-/* C3.6.7 AdvSIMD scalar copy
732
+/* AdvSIMD scalar copy
733
* 31 30 29 28 21 20 16 15 14 11 10 9 5 4 0
734
* +-----+----+-----------------+------+---+------+---+------+------+
735
* | 0 1 | op | 1 1 1 1 0 0 0 0 | imm5 | 0 | imm4 | 1 | Rn | Rd |
736
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_copy(DisasContext *s, uint32_t insn)
737
handle_simd_dupes(s, rd, rn, imm5);
738
}
739
740
-/* C3.6.8 AdvSIMD scalar pairwise
741
+/* AdvSIMD scalar pairwise
742
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
743
* +-----+---+-----------+------+-----------+--------+-----+------+------+
744
* | 0 1 | U | 1 1 1 1 0 | size | 1 1 0 0 0 | opcode | 1 0 | Rn | Rd |
745
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
746
tcg_temp_free_i32(tcg_rmode);
747
}
748
749
-/* C3.6.9 AdvSIMD scalar shift by immediate
750
+/* AdvSIMD scalar shift by immediate
751
* 31 30 29 28 23 22 19 18 16 15 11 10 9 5 4 0
752
* +-----+---+-------------+------+------+--------+---+------+------+
753
* | 0 1 | U | 1 1 1 1 1 0 | immh | immb | opcode | 1 | Rn | Rd |
754
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_shift_imm(DisasContext *s, uint32_t insn)
755
}
756
}
757
758
-/* C3.6.10 AdvSIMD scalar three different
759
+/* AdvSIMD scalar three different
760
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
761
* +-----+---+-----------+------+---+------+--------+-----+------+------+
762
* | 0 1 | U | 1 1 1 1 0 | size | 1 | Rm | opcode | 0 0 | Rn | Rd |
763
@@ -XXX,XX +XXX,XX @@ static void handle_3same_float(DisasContext *s, int size, int elements,
764
}
765
}
766
767
-/* C3.6.11 AdvSIMD scalar three same
768
+/* AdvSIMD scalar three same
769
* 31 30 29 28 24 23 22 21 20 16 15 11 10 9 5 4 0
770
* +-----+---+-----------+------+---+------+--------+---+------+------+
771
* | 0 1 | U | 1 1 1 1 0 | size | 1 | Rm | opcode | 1 | Rn | Rd |
772
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_satacc(DisasContext *s, bool is_scalar, bool is_u,
773
}
774
}
775
776
-/* C3.6.12 AdvSIMD scalar two reg misc
777
+/* AdvSIMD scalar two reg misc
778
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
779
* +-----+---+-----------+------+-----------+--------+-----+------+------+
780
* | 0 1 | U | 1 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd |
781
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shrn(DisasContext *s, bool is_q,
782
}
783
784
785
-/* C3.6.14 AdvSIMD shift by immediate
786
+/* AdvSIMD shift by immediate
787
* 31 30 29 28 23 22 19 18 16 15 11 10 9 5 4 0
788
* +---+---+---+-------------+------+------+--------+---+------+------+
789
* | 0 | Q | U | 0 1 1 1 1 0 | immh | immb | opcode | 1 | Rn | Rd |
790
@@ -XXX,XX +XXX,XX @@ static void handle_pmull_64(DisasContext *s, int is_q, int rd, int rn, int rm)
791
tcg_temp_free_i64(tcg_res);
792
}
793
794
-/* C3.6.15 AdvSIMD three different
795
+/* AdvSIMD three different
796
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
797
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
798
* | 0 | Q | U | 0 1 1 1 0 | size | 1 | Rm | opcode | 0 0 | Rn | Rd |
799
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
800
}
801
}
802
803
-/* C3.6.16 AdvSIMD three same
804
+/* AdvSIMD three same
805
* 31 30 29 28 24 23 22 21 20 16 15 11 10 9 5 4 0
806
* +---+---+---+-----------+------+---+------+--------+---+------+------+
807
* | 0 | Q | U | 0 1 1 1 0 | size | 1 | Rm | opcode | 1 | Rn | Rd |
808
@@ -XXX,XX +XXX,XX @@ static void handle_shll(DisasContext *s, bool is_q, int size, int rn, int rd)
809
}
810
}
811
812
-/* C3.6.17 AdvSIMD two reg misc
813
+/* AdvSIMD two reg misc
814
* 31 30 29 28 24 23 22 21 17 16 12 11 10 9 5 4 0
815
* +---+---+---+-----------+------+-----------+--------+-----+------+------+
816
* | 0 | Q | U | 0 1 1 1 0 | size | 1 0 0 0 0 | opcode | 1 0 | Rn | Rd |
817
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
818
}
819
}
820
821
-/* C3.6.13 AdvSIMD scalar x indexed element
822
+/* AdvSIMD scalar x indexed element
823
* 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
824
* +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
825
* | 0 1 | U | 1 1 1 1 1 | size | L | M | Rm | opc | H | 0 | Rn | Rd |
826
* +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
827
- * C3.6.18 AdvSIMD vector x indexed element
828
+ * AdvSIMD vector x indexed element
829
* 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
830
* +---+---+---+-----------+------+---+---+------+-----+---+---+------+------+
831
* | 0 | Q | U | 0 1 1 1 1 | size | L | M | Rm | opc | H | 0 | Rn | Rd |
832
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
833
}
834
}
835
836
-/* C3.6.19 Crypto AES
837
+/* Crypto AES
838
* 31 24 23 22 21 17 16 12 11 10 9 5 4 0
839
* +-----------------+------+-----------+--------+-----+------+------+
840
* | 0 1 0 0 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 | Rn | Rd |
841
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
842
tcg_temp_free_i32(tcg_decrypt);
843
}
844
845
-/* C3.6.20 Crypto three-reg SHA
846
+/* Crypto three-reg SHA
847
* 31 24 23 22 21 20 16 15 14 12 11 10 9 5 4 0
848
* +-----------------+------+---+------+---+--------+-----+------+------+
849
* | 0 1 0 1 1 1 1 0 | size | 0 | Rm | 0 | opcode | 0 0 | Rn | Rd |
850
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
851
tcg_temp_free_i32(tcg_rm_regno);
852
}
853
854
-/* C3.6.21 Crypto two-reg SHA
855
+/* Crypto two-reg SHA
856
* 31 24 23 22 21 17 16 12 11 10 9 5 4 0
857
* +-----------------+------+-----------+--------+-----+------+------+
858
* | 0 1 0 1 1 1 1 0 | size | 1 0 1 0 0 | opcode | 1 0 | Rn | Rd |
859
--
36
--
860
2.7.4
37
2.25.1
861
38
862
39
diff view generated by jsdifflib
1
Update armv7m_nvic_acknowledge_irq() and armv7m_nvic_complete_irq()
1
From: Richard Henderson <richard.henderson@linaro.org>
2
to handle banked exceptions:
3
* acknowledge needs to use the correct vector, which may be
4
in sec_vectors[]
5
* acknowledge needs to return to its caller whether the
6
exception should be taken to secure or non-secure state
7
* complete needs its caller to tell it whether the exception
8
being completed is a secure one or not
9
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1505240046-11454-20-git-send-email-peter.maydell@linaro.org
13
---
6
---
14
target/arm/cpu.h | 15 +++++++++++++--
7
target/arm/translate.c | 9 +++++----
15
hw/intc/armv7m_nvic.c | 26 ++++++++++++++++++++------
8
1 file changed, 5 insertions(+), 4 deletions(-)
16
target/arm/helper.c | 8 +++++---
17
hw/intc/trace-events | 4 ++--
18
4 files changed, 40 insertions(+), 13 deletions(-)
19
9
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
21
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
12
--- a/target/arm/translate.c
23
+++ b/target/arm/cpu.h
13
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
14
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
25
* of architecturally banked exceptions.
26
*/
27
void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
28
-void armv7m_nvic_acknowledge_irq(void *opaque);
29
+/**
30
+ * armv7m_nvic_acknowledge_irq: make highest priority pending exception active
31
+ * @opaque: the NVIC
32
+ *
33
+ * Move the current highest priority pending exception from the pending
34
+ * state to the active state, and update v7m.exception to indicate that
35
+ * it is the exception currently being handled.
36
+ *
37
+ * Returns: true if exception should be taken to Secure state, false for NS
38
+ */
39
+bool armv7m_nvic_acknowledge_irq(void *opaque);
40
/**
41
* armv7m_nvic_complete_irq: complete specified interrupt or exception
42
* @opaque: the NVIC
43
* @irq: the exception number to complete
44
+ * @secure: true if this exception was secure
45
*
46
* Returns: -1 if the irq was not active
47
* 1 if completing this irq brought us back to base (no active irqs)
48
* 0 if there is still an irq active after this one was completed
49
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
50
*/
51
-int armv7m_nvic_complete_irq(void *opaque, int irq);
52
+int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
53
/**
54
* armv7m_nvic_raw_execution_priority: return the raw execution priority
55
* @opaque: the NVIC
56
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/armv7m_nvic.c
59
+++ b/hw/intc/armv7m_nvic.c
60
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
61
}
62
63
/* Make pending IRQ active. */
64
-void armv7m_nvic_acknowledge_irq(void *opaque)
65
+bool armv7m_nvic_acknowledge_irq(void *opaque)
66
{
15
{
67
NVICState *s = (NVICState *)opaque;
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
68
CPUARMState *env = &s->cpu->env;
17
CPUARMState *env = cpu->env_ptr;
69
const int pending = s->vectpending;
18
+ uint32_t pc = dc->base.pc_next;
70
const int running = nvic_exec_prio(s);
19
unsigned int insn;
71
VecInfo *vec;
20
72
+ bool targets_secure;
21
if (arm_pre_translate_insn(dc)) {
73
22
- dc->base.pc_next += 4;
74
assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq);
23
+ dc->base.pc_next = pc + 4;
75
24
return;
76
- vec = &s->vectors[pending];
77
+ if (s->vectpending_is_s_banked) {
78
+ vec = &s->sec_vectors[pending];
79
+ targets_secure = true;
80
+ } else {
81
+ vec = &s->vectors[pending];
82
+ targets_secure = !exc_is_banked(s->vectpending) &&
83
+ exc_targets_secure(s, s->vectpending);
84
+ }
85
86
assert(vec->enabled);
87
assert(vec->pending);
88
89
assert(s->vectpending_prio < running);
90
91
- trace_nvic_acknowledge_irq(pending, s->vectpending_prio);
92
+ trace_nvic_acknowledge_irq(pending, s->vectpending_prio, targets_secure);
93
94
vec->active = 1;
95
vec->pending = 0;
96
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque)
97
env->v7m.exception = s->vectpending;
98
99
nvic_irq_update(s);
100
+
101
+ return targets_secure;
102
}
103
104
-int armv7m_nvic_complete_irq(void *opaque, int irq)
105
+int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
106
{
107
NVICState *s = (NVICState *)opaque;
108
VecInfo *vec;
109
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq)
110
111
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
112
113
- vec = &s->vectors[irq];
114
+ if (secure && exc_is_banked(irq)) {
115
+ vec = &s->sec_vectors[irq];
116
+ } else {
117
+ vec = &s->vectors[irq];
118
+ }
119
120
- trace_nvic_complete_irq(irq);
121
+ trace_nvic_complete_irq(irq, secure);
122
123
if (!vec->active) {
124
/* Tell the caller this was an illegal exception return */
125
diff --git a/target/arm/helper.c b/target/arm/helper.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/target/arm/helper.c
128
+++ b/target/arm/helper.c
129
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
130
bool return_to_sp_process = false;
131
bool return_to_handler = false;
132
bool rettobase = false;
133
+ bool exc_secure = false;
134
135
/* We can only get here from an EXCP_EXCEPTION_EXIT, and
136
* gen_bx_excret() enforces the architectural rule
137
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
138
* which security state's faultmask to clear. (v8M ARM ARM R_KBNF.)
139
*/
140
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
141
- int es = excret & R_V7M_EXCRET_ES_MASK;
142
+ exc_secure = excret & R_V7M_EXCRET_ES_MASK;
143
if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) {
144
- env->v7m.faultmask[es] = 0;
145
+ env->v7m.faultmask[exc_secure] = 0;
146
}
147
} else {
148
env->v7m.faultmask[M_REG_NS] = 0;
149
}
150
}
25
}
151
26
152
- switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception)) {
27
- dc->pc_curr = dc->base.pc_next;
153
+ switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception,
28
- insn = arm_ldl_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
154
+ exc_secure)) {
29
+ dc->pc_curr = pc;
155
case -1:
30
+ insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
156
/* attempt to exit an exception that isn't active */
31
dc->insn = insn;
157
ufault = true;
32
- dc->base.pc_next += 4;
158
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
33
+ dc->base.pc_next = pc + 4;
159
index XXXXXXX..XXXXXXX 100644
34
disas_arm_insn(dc, insn);
160
--- a/hw/intc/trace-events
35
161
+++ b/hw/intc/trace-events
36
arm_post_translate_insn(dc);
162
@@ -XXX,XX +XXX,XX @@ nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
163
nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
164
nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
165
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
166
-nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
167
-nvic_complete_irq(int irq) "NVIC complete IRQ %d"
168
+nvic_acknowledge_irq(int irq, int prio, bool targets_secure) "NVIC acknowledge IRQ: %d now active (prio %d targets_secure %d)"
169
+nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
170
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
171
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
172
nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
173
--
37
--
174
2.7.4
38
2.25.1
175
39
176
40
diff view generated by jsdifflib
1
If AIRCR.BFHFNMINS is clear, then although NonSecure HardFault
1
From: Richard Henderson <richard.henderson@linaro.org>
2
can still be pended via SHCSR.HARDFAULTPENDED it mustn't actually
3
preempt execution. The simple way to achieve this is to clear the
4
enable bit for it, since the enable bit isn't guest visible.
5
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1505240046-11454-15-git-send-email-peter.maydell@linaro.org
9
---
6
---
10
hw/intc/armv7m_nvic.c | 12 ++++++++++--
7
target/arm/translate.c | 16 ++++++++--------
11
1 file changed, 10 insertions(+), 2 deletions(-)
8
1 file changed, 8 insertions(+), 8 deletions(-)
12
9
13
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
10
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/armv7m_nvic.c
12
--- a/target/arm/translate.c
16
+++ b/hw/intc/armv7m_nvic.c
13
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
14
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
18
(R_V7M_AIRCR_SYSRESETREQS_MASK |
15
{
19
R_V7M_AIRCR_BFHFNMINS_MASK |
16
DisasContext *dc = container_of(dcbase, DisasContext, base);
20
R_V7M_AIRCR_PRIS_MASK);
17
CPUARMState *env = cpu->env_ptr;
21
- /* BFHFNMINS changes the priority of Secure HardFault */
18
+ uint32_t pc = dc->base.pc_next;
22
+ /* BFHFNMINS changes the priority of Secure HardFault, and
19
uint32_t insn;
23
+ * allows a pending Non-secure HardFault to preempt (which
20
bool is_16bit;
24
+ * we implement by marking it enabled).
21
25
+ */
22
if (arm_pre_translate_insn(dc)) {
26
if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
23
- dc->base.pc_next += 2;
27
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
24
+ dc->base.pc_next = pc + 2;
28
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
25
return;
29
} else {
30
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
31
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
32
}
33
}
34
nvic_irq_update(s);
35
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
36
NVICState *s = NVIC(dev);
37
38
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
39
- s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
40
/* MEM, BUS, and USAGE are enabled through
41
* the System Handler Control register
42
*/
43
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
44
45
/* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
46
s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
47
+ /* If AIRCR.BFHFNMINS is 0 then NS HF is (effectively) disabled */
48
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 0;
49
+ } else {
50
+ s->vectors[ARMV7M_EXCP_HARD].enabled = 1;
51
}
26
}
52
27
53
/* Strictly speaking the reset handler should be enabled.
28
- dc->pc_curr = dc->base.pc_next;
29
- insn = arm_lduw_code(env, &dc->base, dc->base.pc_next, dc->sctlr_b);
30
+ dc->pc_curr = pc;
31
+ insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
32
is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
33
- dc->base.pc_next += 2;
34
+ pc += 2;
35
if (!is_16bit) {
36
- uint32_t insn2 = arm_lduw_code(env, &dc->base, dc->base.pc_next,
37
- dc->sctlr_b);
38
-
39
+ uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
40
insn = insn << 16 | insn2;
41
- dc->base.pc_next += 2;
42
+ pc += 2;
43
}
44
+ dc->base.pc_next = pc;
45
dc->insn = insn;
46
47
if (dc->pstate_il) {
54
--
48
--
55
2.7.4
49
2.25.1
56
50
57
51
diff view generated by jsdifflib
1
With banked exceptions, just the exception number in
1
From: Richard Henderson <richard.henderson@linaro.org>
2
s->vectpending is no longer sufficient to uniquely identify
3
the pending exception. Add a vectpending_is_s_banked bool
4
which is true if the exception is using the sec_vectors[]
5
array.
6
2
3
Create arm_check_ss_active and arm_check_kernelpage.
4
5
Reverse the order of the tests. While it doesn't matter in practice,
6
because only user-only has a kernel page and user-only never sets
7
ss_active, ss_active has priority over execution exceptions and it
8
is best to keep them in the proper order.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1505240046-11454-4-git-send-email-peter.maydell@linaro.org
9
---
13
---
10
include/hw/intc/armv7m_nvic.h | 11 +++++++++--
14
target/arm/translate.c | 10 +++++++---
11
hw/intc/armv7m_nvic.c | 1 +
15
1 file changed, 7 insertions(+), 3 deletions(-)
12
2 files changed, 10 insertions(+), 2 deletions(-)
13
16
14
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/intc/armv7m_nvic.h
19
--- a/target/arm/translate.c
17
+++ b/include/hw/intc/armv7m_nvic.h
20
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
21
@@ -XXX,XX +XXX,XX @@ static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
19
VecInfo sec_vectors[NVIC_INTERNAL_VECTORS];
22
dc->insn_start = tcg_last_op();
20
uint32_t prigroup;
21
22
- /* vectpending and exception_prio are both cached state that can
23
- * be recalculated from the vectors[] array and the prigroup field.
24
+ /* The following fields are all cached state that can be recalculated
25
+ * from the vectors[] and sec_vectors[] arrays and the prigroup field:
26
+ * - vectpending
27
+ * - vectpending_is_secure
28
+ * - exception_prio
29
*/
30
unsigned int vectpending; /* highest prio pending enabled exception */
31
+ /* true if vectpending is a banked secure exception, ie it is in
32
+ * sec_vectors[] rather than vectors[]
33
+ */
34
+ bool vectpending_is_s_banked;
35
int exception_prio; /* group prio of the highest prio active exception */
36
37
MemoryRegion sysregmem;
38
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/intc/armv7m_nvic.c
41
+++ b/hw/intc/armv7m_nvic.c
42
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
43
44
s->exception_prio = NVIC_NOEXC_PRIO;
45
s->vectpending = 0;
46
+ s->vectpending_is_s_banked = false;
47
}
23
}
48
24
49
static void nvic_systick_trigger(void *opaque, int n, int level)
25
-static bool arm_pre_translate_insn(DisasContext *dc)
26
+static bool arm_check_kernelpage(DisasContext *dc)
27
{
28
#ifdef CONFIG_USER_ONLY
29
/* Intercept jump to the magic kernel page. */
30
@@ -XXX,XX +XXX,XX @@ static bool arm_pre_translate_insn(DisasContext *dc)
31
return true;
32
}
33
#endif
34
+ return false;
35
+}
36
37
+static bool arm_check_ss_active(DisasContext *dc)
38
+{
39
if (dc->ss_active && !dc->pstate_ss) {
40
/* Singlestep state is Active-pending.
41
* If we're in this state at the start of a TB then either
42
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
43
uint32_t pc = dc->base.pc_next;
44
unsigned int insn;
45
46
- if (arm_pre_translate_insn(dc)) {
47
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
48
dc->base.pc_next = pc + 4;
49
return;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
52
uint32_t insn;
53
bool is_16bit;
54
55
- if (arm_pre_translate_insn(dc)) {
56
+ if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
57
dc->base.pc_next = pc + 2;
58
return;
59
}
50
--
60
--
51
2.7.4
61
2.25.1
52
62
53
63
diff view generated by jsdifflib
1
Don't use old_mmio in the memory region ops struct.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The size of the code covered by a TranslationBlock cannot be 0;
4
this is checked via assert in tb_gen_code.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1505580378-9044-6-git-send-email-peter.maydell@linaro.org
6
---
9
---
7
hw/i2c/omap_i2c.c | 44 ++++++++++++++++++++++++++++++++------------
10
target/arm/translate-a64.c | 1 +
8
1 file changed, 32 insertions(+), 12 deletions(-)
11
1 file changed, 1 insertion(+)
9
12
10
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/i2c/omap_i2c.c
15
--- a/target/arm/translate-a64.c
13
+++ b/hw/i2c/omap_i2c.c
16
+++ b/target/arm/translate-a64.c
14
@@ -XXX,XX +XXX,XX @@ static void omap_i2c_writeb(void *opaque, hwaddr addr,
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
18
assert(s->base.num_insns == 1);
19
gen_swstep_exception(s, 0, 0);
20
s->base.is_jmp = DISAS_NORETURN;
21
+ s->base.pc_next = pc + 4;
22
return;
15
}
23
}
16
}
17
18
+static uint64_t omap_i2c_readfn(void *opaque, hwaddr addr,
19
+ unsigned size)
20
+{
21
+ switch (size) {
22
+ case 2:
23
+ return omap_i2c_read(opaque, addr);
24
+ default:
25
+ return omap_badwidth_read16(opaque, addr);
26
+ }
27
+}
28
+
29
+static void omap_i2c_writefn(void *opaque, hwaddr addr,
30
+ uint64_t value, unsigned size)
31
+{
32
+ switch (size) {
33
+ case 1:
34
+ /* Only the last fifo write can be 8 bit. */
35
+ omap_i2c_writeb(opaque, addr, value);
36
+ break;
37
+ case 2:
38
+ omap_i2c_write(opaque, addr, value);
39
+ break;
40
+ default:
41
+ omap_badwidth_write16(opaque, addr, value);
42
+ break;
43
+ }
44
+}
45
+
46
static const MemoryRegionOps omap_i2c_ops = {
47
- .old_mmio = {
48
- .read = {
49
- omap_badwidth_read16,
50
- omap_i2c_read,
51
- omap_badwidth_read16,
52
- },
53
- .write = {
54
- omap_i2c_writeb, /* Only the last fifo write can be 8 bit. */
55
- omap_i2c_write,
56
- omap_badwidth_write16,
57
- },
58
- },
59
+ .read = omap_i2c_readfn,
60
+ .write = omap_i2c_writefn,
61
+ .valid.min_access_size = 1,
62
+ .valid.max_access_size = 4,
63
.endianness = DEVICE_NATIVE_ENDIAN,
64
};
65
24
66
--
25
--
67
2.7.4
26
2.25.1
68
27
69
28
diff view generated by jsdifflib
1
Now that we have a banked FAULTMASK register and banked exceptions,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
we can implement the correct check in cpu_mmu_index() for whether
3
the MPU_CTRL.HFNMIENA bit's effect should apply. This bit causes
4
handlers which have requested a negative execution priority to run
5
with the MPU disabled. In v8M the test has to check this for the
6
current security state and so takes account of banking.
7
2
3
We will reuse this section of arm_deliver_fault for
4
raising pc alignment faults.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1505240046-11454-17-git-send-email-peter.maydell@linaro.org
11
---
9
---
12
target/arm/cpu.h | 21 ++++++++++++++++-----
10
target/arm/tlb_helper.c | 45 +++++++++++++++++++++++++----------------
13
hw/intc/armv7m_nvic.c | 29 +++++++++++++++++++++++++++++
11
1 file changed, 28 insertions(+), 17 deletions(-)
14
2 files changed, 45 insertions(+), 5 deletions(-)
15
12
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
15
--- a/target/arm/tlb_helper.c
19
+++ b/target/arm/cpu.h
16
+++ b/target/arm/tlb_helper.c
20
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq);
17
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
21
* (v8M ARM ARM I_PKLD.)
18
return syn;
22
*/
23
int armv7m_nvic_raw_execution_priority(void *opaque);
24
+/**
25
+ * armv7m_nvic_neg_prio_requested: return true if the requested execution
26
+ * priority is negative for the specified security state.
27
+ * @opaque: the NVIC
28
+ * @secure: the security state to test
29
+ * This corresponds to the pseudocode IsReqExecPriNeg().
30
+ */
31
+#ifndef CONFIG_USER_ONLY
32
+bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure);
33
+#else
34
+static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
35
+{
36
+ return false;
37
+}
38
+#endif
39
40
/* Interface for defining coprocessor registers.
41
* Registers are defined in tables of arm_cp_reginfo structs
42
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
43
if (arm_feature(env, ARM_FEATURE_M)) {
44
ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv;
45
46
- /* Execution priority is negative if FAULTMASK is set or
47
- * we're in a HardFault or NMI handler.
48
- */
49
- if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
50
- || env->v7m.faultmask[env->v7m.secure]) {
51
+ if (armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) {
52
mmu_idx = ARMMMUIdx_MNegPri;
53
}
54
55
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/intc/armv7m_nvic.c
58
+++ b/hw/intc/armv7m_nvic.c
59
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
60
return MIN(running, s->exception_prio);
61
}
19
}
62
20
63
+bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure)
21
-static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
64
+{
22
- MMUAccessType access_type,
65
+ /* Return true if the requested execution priority is negative
23
- int mmu_idx, ARMMMUFaultInfo *fi)
66
+ * for the specified security state, ie that security state
24
+static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
67
+ * has an active NMI or HardFault or has set its FAULTMASK.
25
+ int target_el, int mmu_idx, uint32_t *ret_fsc)
68
+ * Note that this is not the same as whether the execution
26
{
69
+ * priority is actually negative (for instance AIRCR.PRIS may
27
- CPUARMState *env = &cpu->env;
70
+ * mean we don't allow FAULTMASK_NS to actually make the execution
28
- int target_el;
71
+ * priority negative). Compare pseudocode IsReqExcPriNeg().
29
- bool same_el;
72
+ */
30
- uint32_t syn, exc, fsr, fsc;
73
+ NVICState *s = opaque;
31
ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
74
+
32
-
75
+ if (s->cpu->env.v7m.faultmask[secure]) {
33
- target_el = exception_target_el(env);
76
+ return true;
34
- if (fi->stage2) {
77
+ }
35
- target_el = 2;
78
+
36
- env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
79
+ if (secure ? s->sec_vectors[ARMV7M_EXCP_HARD].active :
37
- if (arm_is_secure_below_el3(env) && fi->s1ns) {
80
+ s->vectors[ARMV7M_EXCP_HARD].active) {
38
- env->cp15.hpfar_el2 |= HPFAR_NS;
81
+ return true;
39
- }
82
+ }
40
- }
83
+
41
- same_el = (arm_current_el(env) == target_el);
84
+ if (s->vectors[ARMV7M_EXCP_NMI].active &&
42
+ uint32_t fsr, fsc;
85
+ exc_targets_secure(s, ARMV7M_EXCP_NMI) == secure) {
43
86
+ return true;
44
if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
87
+ }
45
arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
88
+
46
@@ -XXX,XX +XXX,XX @@ static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
89
+ return false;
47
fsc = 0x3f;
48
}
49
50
+ *ret_fsc = fsc;
51
+ return fsr;
90
+}
52
+}
91
+
53
+
92
bool armv7m_nvic_can_take_pending_exception(void *opaque)
54
+static void QEMU_NORETURN arm_deliver_fault(ARMCPU *cpu, vaddr addr,
93
{
55
+ MMUAccessType access_type,
94
NVICState *s = opaque;
56
+ int mmu_idx, ARMMMUFaultInfo *fi)
57
+{
58
+ CPUARMState *env = &cpu->env;
59
+ int target_el;
60
+ bool same_el;
61
+ uint32_t syn, exc, fsr, fsc;
62
+
63
+ target_el = exception_target_el(env);
64
+ if (fi->stage2) {
65
+ target_el = 2;
66
+ env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
67
+ if (arm_is_secure_below_el3(env) && fi->s1ns) {
68
+ env->cp15.hpfar_el2 |= HPFAR_NS;
69
+ }
70
+ }
71
+ same_el = (arm_current_el(env) == target_el);
72
+
73
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
74
+
75
if (access_type == MMU_INST_FETCH) {
76
syn = syn_insn_abort(same_el, fi->ea, fi->s1ptw, fsc);
77
exc = EXCP_PREFETCH_ABORT;
95
--
78
--
96
2.7.4
79
2.25.1
97
80
98
81
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Smartfusion2 SoC has hardened Microcontroller subsystem
3
For A64, any input to an indirect branch can cause this.
4
and flash based FPGA fabric. This patch adds support for
4
5
Microcontroller subsystem in the SoC.
5
For A32, many indirect branch paths force the branch to be aligned,
6
6
but BXWritePC does not. This includes the BX instruction but also
7
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
7
other interworking changes to PC. Prior to v8, this case is UNDEFINED.
8
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
With v8, this is CONSTRAINED UNPREDICTABLE and may either raise an
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
exception or force align the PC.
10
Message-id: 20170920201737.25723-5-f4bug@amsat.org
10
11
[PMD: drop cpu_model to directly use cpu type, check m3clk non null]
11
We choose to raise an exception because we have the infrastructure,
12
it makes the generated code for gen_bx simpler, and it has the
13
possibility of catching more guest bugs.
14
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
hw/arm/Makefile.objs | 1 +
19
target/arm/helper.h | 1 +
15
include/hw/arm/msf2-soc.h | 67 +++++++++++
20
target/arm/syndrome.h | 5 ++++
16
hw/arm/msf2-soc.c | 238 ++++++++++++++++++++++++++++++++++++++++
21
linux-user/aarch64/cpu_loop.c | 46 ++++++++++++++++++++---------------
17
default-configs/arm-softmmu.mak | 1 +
22
target/arm/tlb_helper.c | 18 ++++++++++++++
18
4 files changed, 307 insertions(+)
23
target/arm/translate-a64.c | 15 ++++++++++++
19
create mode 100644 include/hw/arm/msf2-soc.h
24
target/arm/translate.c | 22 ++++++++++++++++-
20
create mode 100644 hw/arm/msf2-soc.c
25
6 files changed, 87 insertions(+), 20 deletions(-)
21
26
22
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
27
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/Makefile.objs
29
--- a/target/arm/helper.h
25
+++ b/hw/arm/Makefile.objs
30
+++ b/target/arm/helper.h
26
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_FSL_IMX31) += fsl-imx31.o kzm.o
31
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sel_flags, TCG_CALL_NO_RWG_SE,
27
obj-$(CONFIG_FSL_IMX6) += fsl-imx6.o sabrelite.o
32
DEF_HELPER_2(exception_internal, void, env, i32)
28
obj-$(CONFIG_ASPEED_SOC) += aspeed_soc.o aspeed.o
33
DEF_HELPER_4(exception_with_syndrome, void, env, i32, i32, i32)
29
obj-$(CONFIG_MPS2) += mps2.o
34
DEF_HELPER_2(exception_bkpt_insn, void, env, i32)
30
+obj-$(CONFIG_MSF2) += msf2-soc.o
35
+DEF_HELPER_2(exception_pc_alignment, noreturn, env, tl)
31
diff --git a/include/hw/arm/msf2-soc.h b/include/hw/arm/msf2-soc.h
36
DEF_HELPER_1(setend, void, env)
32
new file mode 100644
37
DEF_HELPER_2(wfi, void, env, i32)
33
index XXXXXXX..XXXXXXX
38
DEF_HELPER_1(wfe, void, env)
34
--- /dev/null
39
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
35
+++ b/include/hw/arm/msf2-soc.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/syndrome.h
42
+++ b/target/arm/syndrome.h
43
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_illegalstate(void)
44
return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
45
}
46
47
+static inline uint32_t syn_pcalignment(void)
48
+{
49
+ return (EC_PCALIGNMENT << ARM_EL_EC_SHIFT) | ARM_EL_IL;
50
+}
51
+
52
#endif /* TARGET_ARM_SYNDROME_H */
53
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/linux-user/aarch64/cpu_loop.c
56
+++ b/linux-user/aarch64/cpu_loop.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_loop(CPUARMState *env)
58
break;
59
case EXCP_PREFETCH_ABORT:
60
case EXCP_DATA_ABORT:
61
- /* We should only arrive here with EC in {DATAABORT, INSNABORT}. */
62
ec = syn_get_ec(env->exception.syndrome);
63
- assert(ec == EC_DATAABORT || ec == EC_INSNABORT);
64
-
65
- /* Both EC have the same format for FSC, or close enough. */
66
- fsc = extract32(env->exception.syndrome, 0, 6);
67
- switch (fsc) {
68
- case 0x04 ... 0x07: /* Translation fault, level {0-3} */
69
- si_signo = TARGET_SIGSEGV;
70
- si_code = TARGET_SEGV_MAPERR;
71
+ switch (ec) {
72
+ case EC_DATAABORT:
73
+ case EC_INSNABORT:
74
+ /* Both EC have the same format for FSC, or close enough. */
75
+ fsc = extract32(env->exception.syndrome, 0, 6);
76
+ switch (fsc) {
77
+ case 0x04 ... 0x07: /* Translation fault, level {0-3} */
78
+ si_signo = TARGET_SIGSEGV;
79
+ si_code = TARGET_SEGV_MAPERR;
80
+ break;
81
+ case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
82
+ case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
83
+ si_signo = TARGET_SIGSEGV;
84
+ si_code = TARGET_SEGV_ACCERR;
85
+ break;
86
+ case 0x11: /* Synchronous Tag Check Fault */
87
+ si_signo = TARGET_SIGSEGV;
88
+ si_code = TARGET_SEGV_MTESERR;
89
+ break;
90
+ case 0x21: /* Alignment fault */
91
+ si_signo = TARGET_SIGBUS;
92
+ si_code = TARGET_BUS_ADRALN;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
break;
98
- case 0x09 ... 0x0b: /* Access flag fault, level {1-3} */
99
- case 0x0d ... 0x0f: /* Permission fault, level {1-3} */
100
- si_signo = TARGET_SIGSEGV;
101
- si_code = TARGET_SEGV_ACCERR;
102
- break;
103
- case 0x11: /* Synchronous Tag Check Fault */
104
- si_signo = TARGET_SIGSEGV;
105
- si_code = TARGET_SEGV_MTESERR;
106
- break;
107
- case 0x21: /* Alignment fault */
108
+ case EC_PCALIGNMENT:
109
si_signo = TARGET_SIGBUS;
110
si_code = TARGET_BUS_ADRALN;
111
break;
112
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/tlb_helper.c
115
+++ b/target/arm/tlb_helper.c
36
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
37
+/*
117
#include "cpu.h"
38
+ * Microsemi Smartfusion2 SoC
118
#include "internals.h"
39
+ *
119
#include "exec/exec-all.h"
40
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
120
+#include "exec/helper-proto.h"
41
+ *
121
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
122
static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
43
+ * of this software and associated documentation files (the "Software"), to deal
123
unsigned int target_el,
44
+ * in the Software without restriction, including without limitation the rights
124
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
125
arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
46
+ * copies of the Software, and to permit persons to whom the Software is
126
}
47
+ * furnished to do so, subject to the following conditions:
127
48
+ *
128
+void helper_exception_pc_alignment(CPUARMState *env, target_ulong pc)
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
60
+
61
+#ifndef HW_ARM_MSF2_SOC_H
62
+#define HW_ARM_MSF2_SOC_H
63
+
64
+#include "hw/arm/armv7m.h"
65
+#include "hw/timer/mss-timer.h"
66
+#include "hw/misc/msf2-sysreg.h"
67
+#include "hw/ssi/mss-spi.h"
68
+
69
+#define TYPE_MSF2_SOC "msf2-soc"
70
+#define MSF2_SOC(obj) OBJECT_CHECK(MSF2State, (obj), TYPE_MSF2_SOC)
71
+
72
+#define MSF2_NUM_SPIS 2
73
+#define MSF2_NUM_UARTS 2
74
+
75
+/*
76
+ * System timer consists of two programmable 32-bit
77
+ * decrementing counters that generate individual interrupts to
78
+ * the Cortex-M3 processor
79
+ */
80
+#define MSF2_NUM_TIMERS 2
81
+
82
+typedef struct MSF2State {
83
+ /*< private >*/
84
+ SysBusDevice parent_obj;
85
+ /*< public >*/
86
+
87
+ ARMv7MState armv7m;
88
+
89
+ char *cpu_type;
90
+ char *part_name;
91
+ uint64_t envm_size;
92
+ uint64_t esram_size;
93
+
94
+ uint32_t m3clk;
95
+ uint8_t apb0div;
96
+ uint8_t apb1div;
97
+
98
+ MSF2SysregState sysreg;
99
+ MSSTimerState timer;
100
+ MSSSpiState spi[MSF2_NUM_SPIS];
101
+} MSF2State;
102
+
103
+#endif
104
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
105
new file mode 100644
106
index XXXXXXX..XXXXXXX
107
--- /dev/null
108
+++ b/hw/arm/msf2-soc.c
109
@@ -XXX,XX +XXX,XX @@
110
+/*
111
+ * SmartFusion2 SoC emulation.
112
+ *
113
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
114
+ *
115
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
116
+ * of this software and associated documentation files (the "Software"), to deal
117
+ * in the Software without restriction, including without limitation the rights
118
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119
+ * copies of the Software, and to permit persons to whom the Software is
120
+ * furnished to do so, subject to the following conditions:
121
+ *
122
+ * The above copyright notice and this permission notice shall be included in
123
+ * all copies or substantial portions of the Software.
124
+ *
125
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
128
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
131
+ * THE SOFTWARE.
132
+ */
133
+
134
+#include "qemu/osdep.h"
135
+#include "qapi/error.h"
136
+#include "qemu-common.h"
137
+#include "hw/arm/arm.h"
138
+#include "exec/address-spaces.h"
139
+#include "hw/char/serial.h"
140
+#include "hw/boards.h"
141
+#include "sysemu/block-backend.h"
142
+#include "qemu/cutils.h"
143
+#include "hw/arm/msf2-soc.h"
144
+#include "hw/misc/unimp.h"
145
+
146
+#define MSF2_TIMER_BASE 0x40004000
147
+#define MSF2_SYSREG_BASE 0x40038000
148
+
149
+#define ENVM_BASE_ADDRESS 0x60000000
150
+
151
+#define SRAM_BASE_ADDRESS 0x20000000
152
+
153
+#define MSF2_ENVM_MAX_SIZE (512 * K_BYTE)
154
+
155
+/*
156
+ * eSRAM max size is 80k without SECDED(Single error correction and
157
+ * dual error detection) feature and 64k with SECDED.
158
+ * We do not support SECDED now.
159
+ */
160
+#define MSF2_ESRAM_MAX_SIZE (80 * K_BYTE)
161
+
162
+static const uint32_t spi_addr[MSF2_NUM_SPIS] = { 0x40001000 , 0x40011000 };
163
+static const uint32_t uart_addr[MSF2_NUM_UARTS] = { 0x40000000 , 0x40010000 };
164
+
165
+static const int spi_irq[MSF2_NUM_SPIS] = { 2, 3 };
166
+static const int uart_irq[MSF2_NUM_UARTS] = { 10, 11 };
167
+static const int timer_irq[MSF2_NUM_TIMERS] = { 14, 15 };
168
+
169
+static void m2sxxx_soc_initfn(Object *obj)
170
+{
129
+{
171
+ MSF2State *s = MSF2_SOC(obj);
130
+ ARMMMUFaultInfo fi = { .type = ARMFault_Alignment };
172
+ int i;
131
+ int target_el = exception_target_el(env);
173
+
132
+ int mmu_idx = cpu_mmu_index(env, true);
174
+ object_initialize(&s->armv7m, sizeof(s->armv7m), TYPE_ARMV7M);
133
+ uint32_t fsc;
175
+ qdev_set_parent_bus(DEVICE(&s->armv7m), sysbus_get_default());
134
+
176
+
135
+ env->exception.vaddress = pc;
177
+ object_initialize(&s->sysreg, sizeof(s->sysreg), TYPE_MSF2_SYSREG);
136
+
178
+ qdev_set_parent_bus(DEVICE(&s->sysreg), sysbus_get_default());
137
+ /*
179
+
138
+ * Note that the fsc is not applicable to this exception,
180
+ object_initialize(&s->timer, sizeof(s->timer), TYPE_MSS_TIMER);
139
+ * since any syndrome is pcalignment not insn_abort.
181
+ qdev_set_parent_bus(DEVICE(&s->timer), sysbus_get_default());
140
+ */
182
+
141
+ env->exception.fsr = compute_fsr_fsc(env, &fi, target_el, mmu_idx, &fsc);
183
+ for (i = 0; i < MSF2_NUM_SPIS; i++) {
142
+ raise_exception(env, EXCP_PREFETCH_ABORT, syn_pcalignment(), target_el);
184
+ object_initialize(&s->spi[i], sizeof(s->spi[i]),
185
+ TYPE_MSS_SPI);
186
+ qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
187
+ }
188
+}
143
+}
189
+
144
+
190
+static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
145
#if !defined(CONFIG_USER_ONLY)
191
+{
146
192
+ MSF2State *s = MSF2_SOC(dev_soc);
147
/*
193
+ DeviceState *dev, *armv7m;
148
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
194
+ SysBusDevice *busdev;
149
index XXXXXXX..XXXXXXX 100644
195
+ Error *err = NULL;
150
--- a/target/arm/translate-a64.c
196
+ int i;
151
+++ b/target/arm/translate-a64.c
197
+
152
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
198
+ MemoryRegion *system_memory = get_system_memory();
153
uint64_t pc = s->base.pc_next;
199
+ MemoryRegion *nvm = g_new(MemoryRegion, 1);
154
uint32_t insn;
200
+ MemoryRegion *nvm_alias = g_new(MemoryRegion, 1);
155
201
+ MemoryRegion *sram = g_new(MemoryRegion, 1);
156
+ /* Singlestep exceptions have the highest priority. */
202
+
157
if (s->ss_active && !s->pstate_ss) {
203
+ memory_region_init_rom(nvm, NULL, "MSF2.eNVM", s->envm_size,
158
/* Singlestep state is Active-pending.
204
+ &error_fatal);
159
* If we're in this state at the start of a TB then either
205
+ /*
160
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
206
+ * On power-on, the eNVM region 0x60000000 is automatically
161
return;
207
+ * remapped to the Cortex-M3 processor executable region
162
}
208
+ * start address (0x0). We do not support remapping other eNVM,
163
209
+ * eSRAM and DDR regions by guest(via Sysreg) currently.
164
+ if (pc & 3) {
210
+ */
165
+ /*
211
+ memory_region_init_alias(nvm_alias, NULL, "MSF2.eNVM",
166
+ * PC alignment fault. This has priority over the instruction abort
212
+ nvm, 0, s->envm_size);
167
+ * that we would receive from a translation fault via arm_ldl_code.
213
+
168
+ * This should only be possible after an indirect branch, at the
214
+ memory_region_add_subregion(system_memory, ENVM_BASE_ADDRESS, nvm);
169
+ * start of the TB.
215
+ memory_region_add_subregion(system_memory, 0, nvm_alias);
170
+ */
216
+
171
+ assert(s->base.num_insns == 1);
217
+ memory_region_init_ram(sram, NULL, "MSF2.eSRAM", s->esram_size,
172
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
218
+ &error_fatal);
173
+ s->base.is_jmp = DISAS_NORETURN;
219
+ memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, sram);
174
+ s->base.pc_next = QEMU_ALIGN_UP(pc, 4);
220
+
221
+ armv7m = DEVICE(&s->armv7m);
222
+ qdev_prop_set_uint32(armv7m, "num-irq", 81);
223
+ qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
224
+ object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
225
+ "memory", &error_abort);
226
+ object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
227
+ if (err != NULL) {
228
+ error_propagate(errp, err);
229
+ return;
175
+ return;
230
+ }
176
+ }
231
+
177
+
232
+ if (!s->m3clk) {
178
s->pc_curr = pc;
233
+ error_setg(errp, "Invalid m3clk value");
179
insn = arm_ldl_code(env, &s->base, pc, s->sctlr_b);
234
+ error_append_hint(errp, "m3clk can not be zero\n");
180
s->insn = insn;
181
diff --git a/target/arm/translate.c b/target/arm/translate.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate.c
184
+++ b/target/arm/translate.c
185
@@ -XXX,XX +XXX,XX @@ static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
186
uint32_t pc = dc->base.pc_next;
187
unsigned int insn;
188
189
- if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
190
+ /* Singlestep exceptions have the highest priority. */
191
+ if (arm_check_ss_active(dc)) {
192
+ dc->base.pc_next = pc + 4;
235
+ return;
193
+ return;
236
+ }
194
+ }
237
+ system_clock_scale = NANOSECONDS_PER_SECOND / s->m3clk;
195
+
238
+
196
+ if (pc & 3) {
239
+ for (i = 0; i < MSF2_NUM_UARTS; i++) {
197
+ /*
240
+ if (serial_hds[i]) {
198
+ * PC alignment fault. This has priority over the instruction abort
241
+ serial_mm_init(get_system_memory(), uart_addr[i], 2,
199
+ * that we would receive from a translation fault via arm_ldl_code
242
+ qdev_get_gpio_in(armv7m, uart_irq[i]),
200
+ * (or the execution of the kernelpage entrypoint). This should only
243
+ 115200, serial_hds[i], DEVICE_NATIVE_ENDIAN);
201
+ * be possible after an indirect branch, at the start of the TB.
244
+ }
202
+ */
245
+ }
203
+ assert(dc->base.num_insns == 1);
246
+
204
+ gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
247
+ dev = DEVICE(&s->timer);
205
+ dc->base.is_jmp = DISAS_NORETURN;
248
+ /* APB0 clock is the timer input clock */
206
+ dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
249
+ qdev_prop_set_uint32(dev, "clock-frequency", s->m3clk / s->apb0div);
250
+ object_property_set_bool(OBJECT(&s->timer), true, "realized", &err);
251
+ if (err != NULL) {
252
+ error_propagate(errp, err);
253
+ return;
207
+ return;
254
+ }
208
+ }
255
+ busdev = SYS_BUS_DEVICE(dev);
209
+
256
+ sysbus_mmio_map(busdev, 0, MSF2_TIMER_BASE);
210
+ if (arm_check_kernelpage(dc)) {
257
+ sysbus_connect_irq(busdev, 0,
211
dc->base.pc_next = pc + 4;
258
+ qdev_get_gpio_in(armv7m, timer_irq[0]));
212
return;
259
+ sysbus_connect_irq(busdev, 1,
213
}
260
+ qdev_get_gpio_in(armv7m, timer_irq[1]));
261
+
262
+ dev = DEVICE(&s->sysreg);
263
+ qdev_prop_set_uint32(dev, "apb0divisor", s->apb0div);
264
+ qdev_prop_set_uint32(dev, "apb1divisor", s->apb1div);
265
+ object_property_set_bool(OBJECT(&s->sysreg), true, "realized", &err);
266
+ if (err != NULL) {
267
+ error_propagate(errp, err);
268
+ return;
269
+ }
270
+ busdev = SYS_BUS_DEVICE(dev);
271
+ sysbus_mmio_map(busdev, 0, MSF2_SYSREG_BASE);
272
+
273
+ for (i = 0; i < MSF2_NUM_SPIS; i++) {
274
+ gchar *bus_name;
275
+
276
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
277
+ if (err != NULL) {
278
+ error_propagate(errp, err);
279
+ return;
280
+ }
281
+
282
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0, spi_addr[i]);
283
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
284
+ qdev_get_gpio_in(armv7m, spi_irq[i]));
285
+
286
+ /* Alias controller SPI bus to the SoC itself */
287
+ bus_name = g_strdup_printf("spi%d", i);
288
+ object_property_add_alias(OBJECT(s), bus_name,
289
+ OBJECT(&s->spi[i]), "spi",
290
+ &error_abort);
291
+ g_free(bus_name);
292
+ }
293
+
294
+ /* Below devices are not modelled yet. */
295
+ create_unimplemented_device("i2c_0", 0x40002000, 0x1000);
296
+ create_unimplemented_device("dma", 0x40003000, 0x1000);
297
+ create_unimplemented_device("watchdog", 0x40005000, 0x1000);
298
+ create_unimplemented_device("i2c_1", 0x40012000, 0x1000);
299
+ create_unimplemented_device("gpio", 0x40013000, 0x1000);
300
+ create_unimplemented_device("hs-dma", 0x40014000, 0x1000);
301
+ create_unimplemented_device("can", 0x40015000, 0x1000);
302
+ create_unimplemented_device("rtc", 0x40017000, 0x1000);
303
+ create_unimplemented_device("apb_config", 0x40020000, 0x10000);
304
+ create_unimplemented_device("emac", 0x40041000, 0x1000);
305
+ create_unimplemented_device("usb", 0x40043000, 0x1000);
306
+}
307
+
308
+static Property m2sxxx_soc_properties[] = {
309
+ /*
310
+ * part name specifies the type of SmartFusion2 device variant(this
311
+ * property is for information purpose only.
312
+ */
313
+ DEFINE_PROP_STRING("cpu-type", MSF2State, cpu_type),
314
+ DEFINE_PROP_STRING("part-name", MSF2State, part_name),
315
+ DEFINE_PROP_UINT64("eNVM-size", MSF2State, envm_size, MSF2_ENVM_MAX_SIZE),
316
+ DEFINE_PROP_UINT64("eSRAM-size", MSF2State, esram_size,
317
+ MSF2_ESRAM_MAX_SIZE),
318
+ /* Libero GUI shows 100Mhz as default for clocks */
319
+ DEFINE_PROP_UINT32("m3clk", MSF2State, m3clk, 100 * 1000000),
320
+ /* default divisors in Libero GUI */
321
+ DEFINE_PROP_UINT8("apb0div", MSF2State, apb0div, 2),
322
+ DEFINE_PROP_UINT8("apb1div", MSF2State, apb1div, 2),
323
+ DEFINE_PROP_END_OF_LIST(),
324
+};
325
+
326
+static void m2sxxx_soc_class_init(ObjectClass *klass, void *data)
327
+{
328
+ DeviceClass *dc = DEVICE_CLASS(klass);
329
+
330
+ dc->realize = m2sxxx_soc_realize;
331
+ dc->props = m2sxxx_soc_properties;
332
+}
333
+
334
+static const TypeInfo m2sxxx_soc_info = {
335
+ .name = TYPE_MSF2_SOC,
336
+ .parent = TYPE_SYS_BUS_DEVICE,
337
+ .instance_size = sizeof(MSF2State),
338
+ .instance_init = m2sxxx_soc_initfn,
339
+ .class_init = m2sxxx_soc_class_init,
340
+};
341
+
342
+static void m2sxxx_soc_types(void)
343
+{
344
+ type_register_static(&m2sxxx_soc_info);
345
+}
346
+
347
+type_init(m2sxxx_soc_types)
348
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
349
index XXXXXXX..XXXXXXX 100644
350
--- a/default-configs/arm-softmmu.mak
351
+++ b/default-configs/arm-softmmu.mak
352
@@ -XXX,XX +XXX,XX @@ CONFIG_ACPI=y
353
CONFIG_SMBIOS=y
354
CONFIG_ASPEED_SOC=y
355
CONFIG_GPIO_KEY=y
356
+CONFIG_MSF2=y
357
--
214
--
358
2.7.4
215
2.25.1
359
216
360
217
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Modelled Microsemi's Smartfusion2 SPI controller.
3
Misaligned thumb PC is architecturally impossible.
4
Assert is better than proceeding, in case we've missed
5
something somewhere.
4
6
5
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
7
Expand a comment about aligning the pc in gdbstub.
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Fail an incoming migrate if a thumb pc is misaligned.
7
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
8
Message-id: 20170920201737.25723-4-f4bug@amsat.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/ssi/Makefile.objs | 1 +
14
target/arm/gdbstub.c | 9 +++++++--
12
include/hw/ssi/mss-spi.h | 58 +++++++
15
target/arm/machine.c | 10 ++++++++++
13
hw/ssi/mss-spi.c | 404 +++++++++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 3 +++
14
3 files changed, 463 insertions(+)
17
3 files changed, 20 insertions(+), 2 deletions(-)
15
create mode 100644 include/hw/ssi/mss-spi.h
16
create mode 100644 hw/ssi/mss-spi.c
17
18
18
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
19
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/ssi/Makefile.objs
21
--- a/target/arm/gdbstub.c
21
+++ b/hw/ssi/Makefile.objs
22
+++ b/target/arm/gdbstub.c
22
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
23
@@ -XXX,XX +XXX,XX @@ int arm_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
23
common-obj-$(CONFIG_XILINX_SPIPS) += xilinx_spips.o
24
24
common-obj-$(CONFIG_ASPEED_SOC) += aspeed_smc.o
25
tmp = ldl_p(mem_buf);
25
common-obj-$(CONFIG_STM32F2XX_SPI) += stm32f2xx_spi.o
26
26
+common-obj-$(CONFIG_MSF2) += mss-spi.o
27
- /* Mask out low bit of PC to workaround gdb bugs. This will probably
27
28
- cause problems if we ever implement the Jazelle DBX extensions. */
28
obj-$(CONFIG_OMAP) += omap_spi.o
29
+ /*
29
obj-$(CONFIG_IMX) += imx_spi.o
30
+ * Mask out low bits of PC to workaround gdb bugs.
30
diff --git a/include/hw/ssi/mss-spi.h b/include/hw/ssi/mss-spi.h
31
+ * This avoids an assert in thumb_tr_translate_insn, because it is
31
new file mode 100644
32
+ * architecturally impossible to misalign the pc.
32
index XXXXXXX..XXXXXXX
33
+ * This will probably cause problems if we ever implement the
33
--- /dev/null
34
+ * Jazelle DBX extensions.
34
+++ b/include/hw/ssi/mss-spi.h
35
+ */
35
@@ -XXX,XX +XXX,XX @@
36
if (n == 15) {
36
+/*
37
tmp &= ~1;
37
+ * Microsemi SmartFusion2 SPI
38
}
38
+ *
39
diff --git a/target/arm/machine.c b/target/arm/machine.c
39
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
40
index XXXXXXX..XXXXXXX 100644
40
+ *
41
--- a/target/arm/machine.c
41
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
42
+++ b/target/arm/machine.c
42
+ * of this software and associated documentation files (the "Software"), to deal
43
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
43
+ * in the Software without restriction, including without limitation the rights
44
return -1;
44
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45
}
45
+ * copies of the Software, and to permit persons to whom the Software is
46
}
46
+ * furnished to do so, subject to the following conditions:
47
+ *
48
+ * The above copyright notice and this permission notice shall be included in
49
+ * all copies or substantial portions of the Software.
50
+ *
51
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
54
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57
+ * THE SOFTWARE.
58
+ */
59
+
60
+#ifndef HW_MSS_SPI_H
61
+#define HW_MSS_SPI_H
62
+
63
+#include "hw/sysbus.h"
64
+#include "hw/ssi/ssi.h"
65
+#include "qemu/fifo32.h"
66
+
67
+#define TYPE_MSS_SPI "mss-spi"
68
+#define MSS_SPI(obj) OBJECT_CHECK(MSSSpiState, (obj), TYPE_MSS_SPI)
69
+
70
+#define R_SPI_MAX 16
71
+
72
+typedef struct MSSSpiState {
73
+ SysBusDevice parent_obj;
74
+
75
+ MemoryRegion mmio;
76
+
77
+ qemu_irq irq;
78
+
79
+ qemu_irq cs_line;
80
+
81
+ SSIBus *spi;
82
+
83
+ Fifo32 rx_fifo;
84
+ Fifo32 tx_fifo;
85
+
86
+ int fifo_depth;
87
+ uint32_t frame_count;
88
+ bool enabled;
89
+
90
+ uint32_t regs[R_SPI_MAX];
91
+} MSSSpiState;
92
+
93
+#endif /* HW_MSS_SPI_H */
94
diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c
95
new file mode 100644
96
index XXXXXXX..XXXXXXX
97
--- /dev/null
98
+++ b/hw/ssi/mss-spi.c
99
@@ -XXX,XX +XXX,XX @@
100
+/*
101
+ * Block model of SPI controller present in
102
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
103
+ *
104
+ * Copyright (C) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
105
+ *
106
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
107
+ * of this software and associated documentation files (the "Software"), to deal
108
+ * in the Software without restriction, including without limitation the rights
109
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
110
+ * copies of the Software, and to permit persons to whom the Software is
111
+ * furnished to do so, subject to the following conditions:
112
+ *
113
+ * The above copyright notice and this permission notice shall be included in
114
+ * all copies or substantial portions of the Software.
115
+ *
116
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
117
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
118
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
119
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
120
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
121
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
122
+ * THE SOFTWARE.
123
+ */
124
+
125
+#include "qemu/osdep.h"
126
+#include "hw/ssi/mss-spi.h"
127
+#include "qemu/log.h"
128
+
129
+#ifndef MSS_SPI_ERR_DEBUG
130
+#define MSS_SPI_ERR_DEBUG 0
131
+#endif
132
+
133
+#define DB_PRINT_L(lvl, fmt, args...) do { \
134
+ if (MSS_SPI_ERR_DEBUG >= lvl) { \
135
+ qemu_log("%s: " fmt "\n", __func__, ## args); \
136
+ } \
137
+} while (0);
138
+
139
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
140
+
141
+#define FIFO_CAPACITY 32
142
+
143
+#define R_SPI_CONTROL 0
144
+#define R_SPI_DFSIZE 1
145
+#define R_SPI_STATUS 2
146
+#define R_SPI_INTCLR 3
147
+#define R_SPI_RX 4
148
+#define R_SPI_TX 5
149
+#define R_SPI_CLKGEN 6
150
+#define R_SPI_SS 7
151
+#define R_SPI_MIS 8
152
+#define R_SPI_RIS 9
153
+
154
+#define S_TXDONE (1 << 0)
155
+#define S_RXRDY (1 << 1)
156
+#define S_RXCHOVRF (1 << 2)
157
+#define S_RXFIFOFUL (1 << 4)
158
+#define S_RXFIFOFULNXT (1 << 5)
159
+#define S_RXFIFOEMP (1 << 6)
160
+#define S_RXFIFOEMPNXT (1 << 7)
161
+#define S_TXFIFOFUL (1 << 8)
162
+#define S_TXFIFOFULNXT (1 << 9)
163
+#define S_TXFIFOEMP (1 << 10)
164
+#define S_TXFIFOEMPNXT (1 << 11)
165
+#define S_FRAMESTART (1 << 12)
166
+#define S_SSEL (1 << 13)
167
+#define S_ACTIVE (1 << 14)
168
+
169
+#define C_ENABLE (1 << 0)
170
+#define C_MODE (1 << 1)
171
+#define C_INTRXDATA (1 << 4)
172
+#define C_INTTXDATA (1 << 5)
173
+#define C_INTRXOVRFLO (1 << 6)
174
+#define C_SPS (1 << 26)
175
+#define C_BIGFIFO (1 << 29)
176
+#define C_RESET (1 << 31)
177
+
178
+#define FRAMESZ_MASK 0x1F
179
+#define FMCOUNT_MASK 0x00FFFF00
180
+#define FMCOUNT_SHIFT 8
181
+
182
+static void txfifo_reset(MSSSpiState *s)
183
+{
184
+ fifo32_reset(&s->tx_fifo);
185
+
186
+ s->regs[R_SPI_STATUS] &= ~S_TXFIFOFUL;
187
+ s->regs[R_SPI_STATUS] |= S_TXFIFOEMP;
188
+}
189
+
190
+static void rxfifo_reset(MSSSpiState *s)
191
+{
192
+ fifo32_reset(&s->rx_fifo);
193
+
194
+ s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
195
+ s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
196
+}
197
+
198
+static void set_fifodepth(MSSSpiState *s)
199
+{
200
+ unsigned int size = s->regs[R_SPI_DFSIZE] & FRAMESZ_MASK;
201
+
202
+ if (size <= 8) {
203
+ s->fifo_depth = 32;
204
+ } else if (size <= 16) {
205
+ s->fifo_depth = 16;
206
+ } else if (size <= 32) {
207
+ s->fifo_depth = 8;
208
+ } else {
209
+ s->fifo_depth = 4;
210
+ }
211
+}
212
+
213
+static void update_mis(MSSSpiState *s)
214
+{
215
+ uint32_t reg = s->regs[R_SPI_CONTROL];
216
+ uint32_t tmp;
217
+
47
+
218
+ /*
48
+ /*
219
+ * form the Control register interrupt enable bits
49
+ * Misaligned thumb pc is architecturally impossible.
220
+ * same as RIS, MIS and Interrupt clear registers for simplicity
50
+ * We have an assert in thumb_tr_translate_insn to verify this.
51
+ * Fail an incoming migrate to avoid this assert.
221
+ */
52
+ */
222
+ tmp = ((reg & C_INTRXOVRFLO) >> 4) | ((reg & C_INTRXDATA) >> 3) |
53
+ if (!is_a64(env) && env->thumb && (env->regs[15] & 1)) {
223
+ ((reg & C_INTTXDATA) >> 5);
54
+ return -1;
224
+ s->regs[R_SPI_MIS] |= tmp & s->regs[R_SPI_RIS];
225
+}
226
+
227
+static void spi_update_irq(MSSSpiState *s)
228
+{
229
+ int irq;
230
+
231
+ update_mis(s);
232
+ irq = !!(s->regs[R_SPI_MIS]);
233
+
234
+ qemu_set_irq(s->irq, irq);
235
+}
236
+
237
+static void mss_spi_reset(DeviceState *d)
238
+{
239
+ MSSSpiState *s = MSS_SPI(d);
240
+
241
+ memset(s->regs, 0, sizeof s->regs);
242
+ s->regs[R_SPI_CONTROL] = 0x80000102;
243
+ s->regs[R_SPI_DFSIZE] = 0x4;
244
+ s->regs[R_SPI_STATUS] = S_SSEL | S_TXFIFOEMP | S_RXFIFOEMP;
245
+ s->regs[R_SPI_CLKGEN] = 0x7;
246
+ s->regs[R_SPI_RIS] = 0x0;
247
+
248
+ s->fifo_depth = 4;
249
+ s->frame_count = 1;
250
+ s->enabled = false;
251
+
252
+ rxfifo_reset(s);
253
+ txfifo_reset(s);
254
+}
255
+
256
+static uint64_t
257
+spi_read(void *opaque, hwaddr addr, unsigned int size)
258
+{
259
+ MSSSpiState *s = opaque;
260
+ uint32_t ret = 0;
261
+
262
+ addr >>= 2;
263
+ switch (addr) {
264
+ case R_SPI_RX:
265
+ s->regs[R_SPI_STATUS] &= ~S_RXFIFOFUL;
266
+ s->regs[R_SPI_STATUS] &= ~S_RXCHOVRF;
267
+ ret = fifo32_pop(&s->rx_fifo);
268
+ if (fifo32_is_empty(&s->rx_fifo)) {
269
+ s->regs[R_SPI_STATUS] |= S_RXFIFOEMP;
270
+ }
271
+ break;
272
+
273
+ case R_SPI_MIS:
274
+ update_mis(s);
275
+ ret = s->regs[R_SPI_MIS];
276
+ break;
277
+
278
+ default:
279
+ if (addr < ARRAY_SIZE(s->regs)) {
280
+ ret = s->regs[addr];
281
+ } else {
282
+ qemu_log_mask(LOG_GUEST_ERROR,
283
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
284
+ addr * 4);
285
+ return ret;
286
+ }
287
+ break;
288
+ }
55
+ }
289
+
56
+
290
+ DB_PRINT("addr=0x%" HWADDR_PRIx " = 0x%" PRIx32, addr * 4, ret);
57
if (!kvm_enabled()) {
291
+ spi_update_irq(s);
58
pmu_op_finish(&cpu->env);
292
+ return ret;
59
}
293
+}
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
uint32_t insn;
66
bool is_16bit;
67
68
+ /* Misaligned thumb PC is architecturally impossible. */
69
+ assert((dc->base.pc_next & 1) == 0);
294
+
70
+
295
+static void assert_cs(MSSSpiState *s)
71
if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
296
+{
72
dc->base.pc_next = pc + 2;
297
+ qemu_set_irq(s->cs_line, 0);
73
return;
298
+}
299
+
300
+static void deassert_cs(MSSSpiState *s)
301
+{
302
+ qemu_set_irq(s->cs_line, 1);
303
+}
304
+
305
+static void spi_flush_txfifo(MSSSpiState *s)
306
+{
307
+ uint32_t tx;
308
+ uint32_t rx;
309
+ bool sps = !!(s->regs[R_SPI_CONTROL] & C_SPS);
310
+
311
+ /*
312
+ * Chip Select(CS) is automatically controlled by this controller.
313
+ * If SPS bit is set in Control register then CS is asserted
314
+ * until all the frames set in frame count of Control register are
315
+ * transferred. If SPS is not set then CS pulses between frames.
316
+ * Note that Slave Select register specifies which of the CS line
317
+ * has to be controlled automatically by controller. Bits SS[7:1] are for
318
+ * masters in FPGA fabric since we model only Microcontroller subsystem
319
+ * of Smartfusion2 we control only one CS(SS[0]) line.
320
+ */
321
+ while (!fifo32_is_empty(&s->tx_fifo) && s->frame_count) {
322
+ assert_cs(s);
323
+
324
+ s->regs[R_SPI_STATUS] &= ~(S_TXDONE | S_RXRDY);
325
+
326
+ tx = fifo32_pop(&s->tx_fifo);
327
+ DB_PRINT("data tx:0x%" PRIx32, tx);
328
+ rx = ssi_transfer(s->spi, tx);
329
+ DB_PRINT("data rx:0x%" PRIx32, rx);
330
+
331
+ if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) {
332
+ s->regs[R_SPI_STATUS] |= S_RXCHOVRF;
333
+ s->regs[R_SPI_RIS] |= S_RXCHOVRF;
334
+ } else {
335
+ fifo32_push(&s->rx_fifo, rx);
336
+ s->regs[R_SPI_STATUS] &= ~S_RXFIFOEMP;
337
+ if (fifo32_num_used(&s->rx_fifo) == (s->fifo_depth - 1)) {
338
+ s->regs[R_SPI_STATUS] |= S_RXFIFOFULNXT;
339
+ } else if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) {
340
+ s->regs[R_SPI_STATUS] |= S_RXFIFOFUL;
341
+ }
342
+ }
343
+ s->frame_count--;
344
+ if (!sps) {
345
+ deassert_cs(s);
346
+ }
347
+ }
348
+
349
+ if (!s->frame_count) {
350
+ s->frame_count = (s->regs[R_SPI_CONTROL] & FMCOUNT_MASK) >>
351
+ FMCOUNT_SHIFT;
352
+ deassert_cs(s);
353
+ s->regs[R_SPI_RIS] |= S_TXDONE | S_RXRDY;
354
+ s->regs[R_SPI_STATUS] |= S_TXDONE | S_RXRDY;
355
+ }
356
+}
357
+
358
+static void spi_write(void *opaque, hwaddr addr,
359
+ uint64_t val64, unsigned int size)
360
+{
361
+ MSSSpiState *s = opaque;
362
+ uint32_t value = val64;
363
+
364
+ DB_PRINT("addr=0x%" HWADDR_PRIx " =0x%" PRIx32, addr, value);
365
+ addr >>= 2;
366
+
367
+ switch (addr) {
368
+ case R_SPI_TX:
369
+ /* adding to already full FIFO */
370
+ if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) {
371
+ break;
372
+ }
373
+ s->regs[R_SPI_STATUS] &= ~S_TXFIFOEMP;
374
+ fifo32_push(&s->tx_fifo, value);
375
+ if (fifo32_num_used(&s->tx_fifo) == (s->fifo_depth - 1)) {
376
+ s->regs[R_SPI_STATUS] |= S_TXFIFOFULNXT;
377
+ } else if (fifo32_num_used(&s->tx_fifo) == s->fifo_depth) {
378
+ s->regs[R_SPI_STATUS] |= S_TXFIFOFUL;
379
+ }
380
+ if (s->enabled) {
381
+ spi_flush_txfifo(s);
382
+ }
383
+ break;
384
+
385
+ case R_SPI_CONTROL:
386
+ s->regs[R_SPI_CONTROL] = value;
387
+ if (value & C_BIGFIFO) {
388
+ set_fifodepth(s);
389
+ } else {
390
+ s->fifo_depth = 4;
391
+ }
392
+ s->enabled = value & C_ENABLE;
393
+ s->frame_count = (value & FMCOUNT_MASK) >> FMCOUNT_SHIFT;
394
+ if (value & C_RESET) {
395
+ mss_spi_reset(DEVICE(s));
396
+ }
397
+ break;
398
+
399
+ case R_SPI_DFSIZE:
400
+ if (s->enabled) {
401
+ break;
402
+ }
403
+ s->regs[R_SPI_DFSIZE] = value;
404
+ break;
405
+
406
+ case R_SPI_INTCLR:
407
+ s->regs[R_SPI_INTCLR] = value;
408
+ if (value & S_TXDONE) {
409
+ s->regs[R_SPI_RIS] &= ~S_TXDONE;
410
+ }
411
+ if (value & S_RXRDY) {
412
+ s->regs[R_SPI_RIS] &= ~S_RXRDY;
413
+ }
414
+ if (value & S_RXCHOVRF) {
415
+ s->regs[R_SPI_RIS] &= ~S_RXCHOVRF;
416
+ }
417
+ break;
418
+
419
+ case R_SPI_MIS:
420
+ case R_SPI_STATUS:
421
+ case R_SPI_RIS:
422
+ qemu_log_mask(LOG_GUEST_ERROR,
423
+ "%s: Write to read only register 0x%" HWADDR_PRIx "\n",
424
+ __func__, addr * 4);
425
+ break;
426
+
427
+ default:
428
+ if (addr < ARRAY_SIZE(s->regs)) {
429
+ s->regs[addr] = value;
430
+ } else {
431
+ qemu_log_mask(LOG_GUEST_ERROR,
432
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__,
433
+ addr * 4);
434
+ }
435
+ break;
436
+ }
437
+
438
+ spi_update_irq(s);
439
+}
440
+
441
+static const MemoryRegionOps spi_ops = {
442
+ .read = spi_read,
443
+ .write = spi_write,
444
+ .endianness = DEVICE_NATIVE_ENDIAN,
445
+ .valid = {
446
+ .min_access_size = 1,
447
+ .max_access_size = 4
448
+ }
449
+};
450
+
451
+static void mss_spi_realize(DeviceState *dev, Error **errp)
452
+{
453
+ MSSSpiState *s = MSS_SPI(dev);
454
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
455
+
456
+ s->spi = ssi_create_bus(dev, "spi");
457
+
458
+ sysbus_init_irq(sbd, &s->irq);
459
+ ssi_auto_connect_slaves(dev, &s->cs_line, s->spi);
460
+ sysbus_init_irq(sbd, &s->cs_line);
461
+
462
+ memory_region_init_io(&s->mmio, OBJECT(s), &spi_ops, s,
463
+ TYPE_MSS_SPI, R_SPI_MAX * 4);
464
+ sysbus_init_mmio(sbd, &s->mmio);
465
+
466
+ fifo32_create(&s->tx_fifo, FIFO_CAPACITY);
467
+ fifo32_create(&s->rx_fifo, FIFO_CAPACITY);
468
+}
469
+
470
+static const VMStateDescription vmstate_mss_spi = {
471
+ .name = TYPE_MSS_SPI,
472
+ .version_id = 1,
473
+ .minimum_version_id = 1,
474
+ .fields = (VMStateField[]) {
475
+ VMSTATE_FIFO32(tx_fifo, MSSSpiState),
476
+ VMSTATE_FIFO32(rx_fifo, MSSSpiState),
477
+ VMSTATE_UINT32_ARRAY(regs, MSSSpiState, R_SPI_MAX),
478
+ VMSTATE_END_OF_LIST()
479
+ }
480
+};
481
+
482
+static void mss_spi_class_init(ObjectClass *klass, void *data)
483
+{
484
+ DeviceClass *dc = DEVICE_CLASS(klass);
485
+
486
+ dc->realize = mss_spi_realize;
487
+ dc->reset = mss_spi_reset;
488
+ dc->vmsd = &vmstate_mss_spi;
489
+}
490
+
491
+static const TypeInfo mss_spi_info = {
492
+ .name = TYPE_MSS_SPI,
493
+ .parent = TYPE_SYS_BUS_DEVICE,
494
+ .instance_size = sizeof(MSSSpiState),
495
+ .class_init = mss_spi_class_init,
496
+};
497
+
498
+static void mss_spi_register_types(void)
499
+{
500
+ type_register_static(&mss_spi_info);
501
+}
502
+
503
+type_init(mss_spi_register_types)
504
--
74
--
505
2.7.4
75
2.25.1
506
76
507
77
diff view generated by jsdifflib
1
Update the nvic_recompute_state() code to handle the security
1
From: Richard Henderson <richard.henderson@linaro.org>
2
extension and its associated banked registers.
3
2
4
Code that uses the resulting cached state (ie the irq
3
Both single-step and pc alignment faults have priority over
5
acknowledge and complete code) will be updated in a later
4
breakpoint exceptions.
6
commit.
7
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1505240046-11454-9-git-send-email-peter.maydell@linaro.org
11
---
9
---
12
hw/intc/armv7m_nvic.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++--
10
target/arm/debug_helper.c | 23 +++++++++++++++++++++++
13
hw/intc/trace-events | 1 +
11
1 file changed, 23 insertions(+)
14
2 files changed, 147 insertions(+), 5 deletions(-)
15
12
16
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/armv7m_nvic.c
15
--- a/target/arm/debug_helper.c
19
+++ b/hw/intc/armv7m_nvic.c
16
+++ b/target/arm/debug_helper.c
20
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
21
* (higher than the highest possible priority value)
18
{
22
*/
19
ARMCPU *cpu = ARM_CPU(cs);
23
#define NVIC_NOEXC_PRIO 0x100
20
CPUARMState *env = &cpu->env;
24
+/* Maximum priority of non-secure exceptions when AIRCR.PRIS is set */
21
+ target_ulong pc;
25
+#define NVIC_NS_PRIO_LIMIT 0x80
22
int n;
26
23
27
static const uint8_t nvic_id[] = {
24
/*
28
0x00, 0xb0, 0x1b, 0x00, 0x0d, 0xe0, 0x05, 0xb1
25
@@ -XXX,XX +XXX,XX @@ bool arm_debug_check_breakpoint(CPUState *cs)
29
@@ -XXX,XX +XXX,XX @@ static bool nvic_isrpending(NVICState *s)
26
return false;
30
return false;
27
}
31
}
28
32
29
+ /*
33
+static bool exc_is_banked(int exc)
30
+ * Single-step exceptions have priority over breakpoint exceptions.
34
+{
31
+ * If single-step state is active-pending, suppress the bp.
35
+ /* Return true if this is one of the limited set of exceptions which
36
+ * are banked (and thus have state in sec_vectors[])
37
+ */
32
+ */
38
+ return exc == ARMV7M_EXCP_HARD ||
33
+ if (arm_singlestep_active(env) && !(env->pstate & PSTATE_SS)) {
39
+ exc == ARMV7M_EXCP_MEM ||
40
+ exc == ARMV7M_EXCP_USAGE ||
41
+ exc == ARMV7M_EXCP_SVC ||
42
+ exc == ARMV7M_EXCP_PENDSV ||
43
+ exc == ARMV7M_EXCP_SYSTICK;
44
+}
45
+
46
/* Return a mask word which clears the subpriority bits from
47
* a priority value for an M-profile exception, leaving only
48
* the group priority.
49
*/
50
-static inline uint32_t nvic_gprio_mask(NVICState *s)
51
+static inline uint32_t nvic_gprio_mask(NVICState *s, bool secure)
52
+{
53
+ return ~0U << (s->prigroup[secure] + 1);
54
+}
55
+
56
+static bool exc_targets_secure(NVICState *s, int exc)
57
+{
58
+ /* Return true if this non-banked exception targets Secure state. */
59
+ if (!arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
60
+ return false;
34
+ return false;
61
+ }
35
+ }
62
+
36
+
63
+ if (exc >= NVIC_FIRST_IRQ) {
37
+ /*
64
+ return !s->itns[exc];
38
+ * PC alignment faults have priority over breakpoint exceptions.
39
+ */
40
+ pc = is_a64(env) ? env->pc : env->regs[15];
41
+ if ((is_a64(env) || !env->thumb) && (pc & 3) != 0) {
42
+ return false;
65
+ }
43
+ }
66
+
44
+
67
+ /* Function shouldn't be called for banked exceptions. */
45
+ /*
68
+ assert(!exc_is_banked(exc));
46
+ * Instruction aborts have priority over breakpoint exceptions.
47
+ * TODO: We would need to look up the page for PC and verify that
48
+ * it is present and executable.
49
+ */
69
+
50
+
70
+ switch (exc) {
51
for (n = 0; n < ARRAY_SIZE(env->cpu_breakpoint); n++) {
71
+ case ARMV7M_EXCP_NMI:
52
if (bp_wp_matches(cpu, n, false)) {
72
+ case ARMV7M_EXCP_BUS:
53
return true;
73
+ return !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK);
74
+ case ARMV7M_EXCP_SECURE:
75
+ return true;
76
+ case ARMV7M_EXCP_DEBUG:
77
+ /* TODO: controlled by DEMCR.SDME, which we don't yet implement */
78
+ return false;
79
+ default:
80
+ /* reset, and reserved (unused) low exception numbers.
81
+ * We'll get called by code that loops through all the exception
82
+ * numbers, but it doesn't matter what we return here as these
83
+ * non-existent exceptions will never be pended or active.
84
+ */
85
+ return true;
86
+ }
87
+}
88
+
89
+static int exc_group_prio(NVICState *s, int rawprio, bool targets_secure)
90
+{
91
+ /* Return the group priority for this exception, given its raw
92
+ * (group-and-subgroup) priority value and whether it is targeting
93
+ * secure state or not.
94
+ */
95
+ if (rawprio < 0) {
96
+ return rawprio;
97
+ }
98
+ rawprio &= nvic_gprio_mask(s, targets_secure);
99
+ /* AIRCR.PRIS causes us to squash all NS priorities into the
100
+ * lower half of the total range
101
+ */
102
+ if (!targets_secure &&
103
+ (s->cpu->env.v7m.aircr & R_V7M_AIRCR_PRIS_MASK)) {
104
+ rawprio = (rawprio >> 1) + NVIC_NS_PRIO_LIMIT;
105
+ }
106
+ return rawprio;
107
+}
108
+
109
+/* Recompute vectpending and exception_prio for a CPU which implements
110
+ * the Security extension
111
+ */
112
+static void nvic_recompute_state_secure(NVICState *s)
113
{
114
- return ~0U << (s->prigroup[M_REG_NS] + 1);
115
+ int i, bank;
116
+ int pend_prio = NVIC_NOEXC_PRIO;
117
+ int active_prio = NVIC_NOEXC_PRIO;
118
+ int pend_irq = 0;
119
+ bool pending_is_s_banked = false;
120
+
121
+ /* R_CQRV: precedence is by:
122
+ * - lowest group priority; if both the same then
123
+ * - lowest subpriority; if both the same then
124
+ * - lowest exception number; if both the same (ie banked) then
125
+ * - secure exception takes precedence
126
+ * Compare pseudocode RawExecutionPriority.
127
+ * Annoyingly, now we have two prigroup values (for S and NS)
128
+ * we can't do the loop comparison on raw priority values.
129
+ */
130
+ for (i = 1; i < s->num_irq; i++) {
131
+ for (bank = M_REG_S; bank >= M_REG_NS; bank--) {
132
+ VecInfo *vec;
133
+ int prio;
134
+ bool targets_secure;
135
+
136
+ if (bank == M_REG_S) {
137
+ if (!exc_is_banked(i)) {
138
+ continue;
139
+ }
140
+ vec = &s->sec_vectors[i];
141
+ targets_secure = true;
142
+ } else {
143
+ vec = &s->vectors[i];
144
+ targets_secure = !exc_is_banked(i) && exc_targets_secure(s, i);
145
+ }
146
+
147
+ prio = exc_group_prio(s, vec->prio, targets_secure);
148
+ if (vec->enabled && vec->pending && prio < pend_prio) {
149
+ pend_prio = prio;
150
+ pend_irq = i;
151
+ pending_is_s_banked = (bank == M_REG_S);
152
+ }
153
+ if (vec->active && prio < active_prio) {
154
+ active_prio = prio;
155
+ }
156
+ }
157
+ }
158
+
159
+ s->vectpending_is_s_banked = pending_is_s_banked;
160
+ s->vectpending = pend_irq;
161
+ s->vectpending_prio = pend_prio;
162
+ s->exception_prio = active_prio;
163
+
164
+ trace_nvic_recompute_state_secure(s->vectpending,
165
+ s->vectpending_is_s_banked,
166
+ s->vectpending_prio,
167
+ s->exception_prio);
168
}
169
170
/* Recompute vectpending and exception_prio */
171
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state(NVICState *s)
172
int active_prio = NVIC_NOEXC_PRIO;
173
int pend_irq = 0;
174
175
+ /* In theory we could write one function that handled both
176
+ * the "security extension present" and "not present"; however
177
+ * the security related changes significantly complicate the
178
+ * recomputation just by themselves and mixing both cases together
179
+ * would be even worse, so we retain a separate non-secure-only
180
+ * version for CPUs which don't implement the security extension.
181
+ */
182
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
183
+ nvic_recompute_state_secure(s);
184
+ return;
185
+ }
186
+
187
for (i = 1; i < s->num_irq; i++) {
188
VecInfo *vec = &s->vectors[i];
189
190
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state(NVICState *s)
191
}
192
193
if (active_prio > 0) {
194
- active_prio &= nvic_gprio_mask(s);
195
+ active_prio &= nvic_gprio_mask(s, false);
196
}
197
198
if (pend_prio > 0) {
199
- pend_prio &= nvic_gprio_mask(s);
200
+ pend_prio &= nvic_gprio_mask(s, false);
201
}
202
203
s->vectpending = pend_irq;
204
@@ -XXX,XX +XXX,XX @@ static inline int nvic_exec_prio(NVICState *s)
205
} else if (env->v7m.primask[env->v7m.secure]) {
206
running = 0;
207
} else if (env->v7m.basepri[env->v7m.secure] > 0) {
208
- running = env->v7m.basepri[env->v7m.secure] & nvic_gprio_mask(s);
209
+ running = env->v7m.basepri[env->v7m.secure] &
210
+ nvic_gprio_mask(s, env->v7m.secure);
211
} else {
212
running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
213
}
214
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/intc/trace-events
217
+++ b/hw/intc/trace-events
218
@@ -XXX,XX +XXX,XX @@ gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending S
219
220
# hw/intc/armv7m_nvic.c
221
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
222
+nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d"
223
nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d"
224
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
225
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
226
--
54
--
227
2.7.4
55
2.25.1
228
56
229
57
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Modelled System Timer in Microsemi's Smartfusion2 Soc.
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Timer has two 32bit down counters and two interrupts.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20170920201737.25723-2-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
6
---
13
hw/timer/Makefile.objs | 1 +
7
tests/tcg/aarch64/pcalign-a64.c | 37 +++++++++++++++++++++++++
14
include/hw/timer/mss-timer.h | 64 ++++++++++
8
tests/tcg/arm/pcalign-a32.c | 46 +++++++++++++++++++++++++++++++
15
hw/timer/mss-timer.c | 289 +++++++++++++++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/Makefile.target | 4 +--
16
3 files changed, 354 insertions(+)
10
tests/tcg/arm/Makefile.target | 4 +++
17
create mode 100644 include/hw/timer/mss-timer.h
11
4 files changed, 89 insertions(+), 2 deletions(-)
18
create mode 100644 hw/timer/mss-timer.c
12
create mode 100644 tests/tcg/aarch64/pcalign-a64.c
13
create mode 100644 tests/tcg/arm/pcalign-a32.c
19
14
20
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
15
diff --git a/tests/tcg/aarch64/pcalign-a64.c b/tests/tcg/aarch64/pcalign-a64.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/timer/Makefile.objs
23
+++ b/hw/timer/Makefile.objs
24
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o
25
26
common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
27
common-obj-$(CONFIG_CMSDK_APB_TIMER) += cmsdk-apb-timer.o
28
+common-obj-$(CONFIG_MSF2) += mss-timer.o
29
diff --git a/include/hw/timer/mss-timer.h b/include/hw/timer/mss-timer.h
30
new file mode 100644
16
new file mode 100644
31
index XXXXXXX..XXXXXXX
17
index XXXXXXX..XXXXXXX
32
--- /dev/null
18
--- /dev/null
33
+++ b/include/hw/timer/mss-timer.h
19
+++ b/tests/tcg/aarch64/pcalign-a64.c
34
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
35
+/*
21
+/* Test PC misalignment exception */
36
+ * Microsemi SmartFusion2 Timer.
37
+ *
38
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
39
+ *
40
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
41
+ * of this software and associated documentation files (the "Software"), to deal
42
+ * in the Software without restriction, including without limitation the rights
43
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44
+ * copies of the Software, and to permit persons to whom the Software is
45
+ * furnished to do so, subject to the following conditions:
46
+ *
47
+ * The above copyright notice and this permission notice shall be included in
48
+ * all copies or substantial portions of the Software.
49
+ *
50
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
53
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
56
+ * THE SOFTWARE.
57
+ */
58
+
22
+
59
+#ifndef HW_MSS_TIMER_H
23
+#include <assert.h>
60
+#define HW_MSS_TIMER_H
24
+#include <signal.h>
25
+#include <stdlib.h>
26
+#include <stdio.h>
61
+
27
+
62
+#include "hw/sysbus.h"
28
+static void *expected;
63
+#include "hw/ptimer.h"
64
+
29
+
65
+#define TYPE_MSS_TIMER "mss-timer"
30
+static void sigbus(int sig, siginfo_t *info, void *vuc)
66
+#define MSS_TIMER(obj) OBJECT_CHECK(MSSTimerState, \
31
+{
67
+ (obj), TYPE_MSS_TIMER)
32
+ assert(info->si_code == BUS_ADRALN);
33
+ assert(info->si_addr == expected);
34
+ exit(EXIT_SUCCESS);
35
+}
68
+
36
+
69
+/*
37
+int main()
70
+ * There are two 32-bit down counting timers.
38
+{
71
+ * Timers 1 and 2 can be concatenated into a single 64-bit Timer
39
+ void *tmp;
72
+ * that operates either in Periodic mode or in One-shot mode.
73
+ * Writing 1 to the TIM64_MODE register bit 0 sets the Timers in 64-bit mode.
74
+ * In 64-bit mode, writing to the 32-bit registers has no effect.
75
+ * Similarly, in 32-bit mode, writing to the 64-bit mode registers
76
+ * has no effect. Only two 32-bit timers are supported currently.
77
+ */
78
+#define NUM_TIMERS 2
79
+
40
+
80
+#define R_TIM1_MAX 6
41
+ struct sigaction sa = {
42
+ .sa_sigaction = sigbus,
43
+ .sa_flags = SA_SIGINFO
44
+ };
81
+
45
+
82
+struct Msf2Timer {
46
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
83
+ QEMUBH *bh;
47
+ perror("sigaction");
84
+ ptimer_state *ptimer;
48
+ return EXIT_FAILURE;
49
+ }
85
+
50
+
86
+ uint32_t regs[R_TIM1_MAX];
51
+ asm volatile("adr %0, 1f + 1\n\t"
87
+ qemu_irq irq;
52
+ "str %0, %1\n\t"
88
+};
53
+ "br %0\n"
89
+
54
+ "1:"
90
+typedef struct MSSTimerState {
55
+ : "=&r"(tmp), "=m"(expected));
91
+ SysBusDevice parent_obj;
56
+ abort();
92
+
57
+}
93
+ MemoryRegion mmio;
58
diff --git a/tests/tcg/arm/pcalign-a32.c b/tests/tcg/arm/pcalign-a32.c
94
+ uint32_t freq_hz;
95
+ struct Msf2Timer timers[NUM_TIMERS];
96
+} MSSTimerState;
97
+
98
+#endif /* HW_MSS_TIMER_H */
99
diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c
100
new file mode 100644
59
new file mode 100644
101
index XXXXXXX..XXXXXXX
60
index XXXXXXX..XXXXXXX
102
--- /dev/null
61
--- /dev/null
103
+++ b/hw/timer/mss-timer.c
62
+++ b/tests/tcg/arm/pcalign-a32.c
104
@@ -XXX,XX +XXX,XX @@
63
@@ -XXX,XX +XXX,XX @@
105
+/*
64
+/* Test PC misalignment exception */
106
+ * Block model of System timer present in
107
+ * Microsemi's SmartFusion2 and SmartFusion SoCs.
108
+ *
109
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>.
110
+ *
111
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
112
+ * of this software and associated documentation files (the "Software"), to deal
113
+ * in the Software without restriction, including without limitation the rights
114
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
115
+ * copies of the Software, and to permit persons to whom the Software is
116
+ * furnished to do so, subject to the following conditions:
117
+ *
118
+ * The above copyright notice and this permission notice shall be included in
119
+ * all copies or substantial portions of the Software.
120
+ *
121
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
122
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
123
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
124
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
125
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
126
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
127
+ * THE SOFTWARE.
128
+ */
129
+
65
+
130
+#include "qemu/osdep.h"
66
+#ifdef __thumb__
131
+#include "qemu/main-loop.h"
67
+#error "This test must be compiled for ARM"
132
+#include "qemu/log.h"
133
+#include "hw/timer/mss-timer.h"
134
+
135
+#ifndef MSS_TIMER_ERR_DEBUG
136
+#define MSS_TIMER_ERR_DEBUG 0
137
+#endif
68
+#endif
138
+
69
+
139
+#define DB_PRINT_L(lvl, fmt, args...) do { \
70
+#include <assert.h>
140
+ if (MSS_TIMER_ERR_DEBUG >= lvl) { \
71
+#include <signal.h>
141
+ qemu_log("%s: " fmt "\n", __func__, ## args); \
72
+#include <stdlib.h>
142
+ } \
73
+#include <stdio.h>
143
+} while (0);
144
+
74
+
145
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
75
+static void *expected;
146
+
76
+
147
+#define R_TIM_VAL 0
77
+static void sigbus(int sig, siginfo_t *info, void *vuc)
148
+#define R_TIM_LOADVAL 1
149
+#define R_TIM_BGLOADVAL 2
150
+#define R_TIM_CTRL 3
151
+#define R_TIM_RIS 4
152
+#define R_TIM_MIS 5
153
+
154
+#define TIMER_CTRL_ENBL (1 << 0)
155
+#define TIMER_CTRL_ONESHOT (1 << 1)
156
+#define TIMER_CTRL_INTR (1 << 2)
157
+#define TIMER_RIS_ACK (1 << 0)
158
+#define TIMER_RST_CLR (1 << 6)
159
+#define TIMER_MODE (1 << 0)
160
+
161
+static void timer_update_irq(struct Msf2Timer *st)
162
+{
78
+{
163
+ bool isr, ier;
79
+ assert(info->si_code == BUS_ADRALN);
164
+
80
+ assert(info->si_addr == expected);
165
+ isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
81
+ exit(EXIT_SUCCESS);
166
+ ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
167
+ qemu_set_irq(st->irq, (ier && isr));
168
+}
82
+}
169
+
83
+
170
+static void timer_update(struct Msf2Timer *st)
84
+int main()
171
+{
85
+{
172
+ uint64_t count;
86
+ void *tmp;
173
+
87
+
174
+ if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL)) {
88
+ struct sigaction sa = {
175
+ ptimer_stop(st->ptimer);
89
+ .sa_sigaction = sigbus,
176
+ return;
90
+ .sa_flags = SA_SIGINFO
91
+ };
92
+
93
+ if (sigaction(SIGBUS, &sa, NULL) < 0) {
94
+ perror("sigaction");
95
+ return EXIT_FAILURE;
177
+ }
96
+ }
178
+
97
+
179
+ count = st->regs[R_TIM_LOADVAL];
98
+ asm volatile("adr %0, 1f + 2\n\t"
180
+ ptimer_set_limit(st->ptimer, count, 1);
99
+ "str %0, %1\n\t"
181
+ ptimer_run(st->ptimer, 1);
100
+ "bx %0\n"
101
+ "1:"
102
+ : "=&r"(tmp), "=m"(expected));
103
+
104
+ /*
105
+ * From v8, it is CONSTRAINED UNPREDICTABLE whether BXWritePC aligns
106
+ * the address or not. If so, we can legitimately fall through.
107
+ */
108
+ return EXIT_SUCCESS;
182
+}
109
+}
110
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
111
index XXXXXXX..XXXXXXX 100644
112
--- a/tests/tcg/aarch64/Makefile.target
113
+++ b/tests/tcg/aarch64/Makefile.target
114
@@ -XXX,XX +XXX,XX @@ VPATH         += $(ARM_SRC)
115
AARCH64_SRC=$(SRC_PATH)/tests/tcg/aarch64
116
VPATH         += $(AARCH64_SRC)
117
118
-# Float-convert Tests
119
-AARCH64_TESTS=fcvt
120
+# Base architecture tests
121
+AARCH64_TESTS=fcvt pcalign-a64
122
123
fcvt: LDFLAGS+=-lm
124
125
diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target
126
index XXXXXXX..XXXXXXX 100644
127
--- a/tests/tcg/arm/Makefile.target
128
+++ b/tests/tcg/arm/Makefile.target
129
@@ -XXX,XX +XXX,XX @@ run-fcvt: fcvt
130
    $(call run-test,fcvt,$(QEMU) $<,"$< on $(TARGET_NAME)")
131
    $(call diff-out,fcvt,$(ARM_SRC)/fcvt.ref)
132
133
+# PC alignment test
134
+ARM_TESTS += pcalign-a32
135
+pcalign-a32: CFLAGS+=-marm
183
+
136
+
184
+static uint64_t
137
ifeq ($(CONFIG_ARM_COMPATIBLE_SEMIHOSTING),y)
185
+timer_read(void *opaque, hwaddr offset, unsigned int size)
138
186
+{
139
# Semihosting smoke test for linux-user
187
+ MSSTimerState *t = opaque;
188
+ hwaddr addr;
189
+ struct Msf2Timer *st;
190
+ uint32_t ret = 0;
191
+ int timer = 0;
192
+ int isr;
193
+ int ier;
194
+
195
+ addr = offset >> 2;
196
+ /*
197
+ * Two independent timers has same base address.
198
+ * Based on address passed figure out which timer is being used.
199
+ */
200
+ if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
201
+ timer = 1;
202
+ addr -= R_TIM1_MAX;
203
+ }
204
+
205
+ st = &t->timers[timer];
206
+
207
+ switch (addr) {
208
+ case R_TIM_VAL:
209
+ ret = ptimer_get_count(st->ptimer);
210
+ break;
211
+
212
+ case R_TIM_MIS:
213
+ isr = !!(st->regs[R_TIM_RIS] & TIMER_RIS_ACK);
214
+ ier = !!(st->regs[R_TIM_CTRL] & TIMER_CTRL_INTR);
215
+ ret = ier & isr;
216
+ break;
217
+
218
+ default:
219
+ if (addr < R_TIM1_MAX) {
220
+ ret = st->regs[addr];
221
+ } else {
222
+ qemu_log_mask(LOG_GUEST_ERROR,
223
+ TYPE_MSS_TIMER": 64-bit mode not supported\n");
224
+ return ret;
225
+ }
226
+ break;
227
+ }
228
+
229
+ DB_PRINT("timer=%d 0x%" HWADDR_PRIx "=0x%" PRIx32, timer, offset,
230
+ ret);
231
+ return ret;
232
+}
233
+
234
+static void
235
+timer_write(void *opaque, hwaddr offset,
236
+ uint64_t val64, unsigned int size)
237
+{
238
+ MSSTimerState *t = opaque;
239
+ hwaddr addr;
240
+ struct Msf2Timer *st;
241
+ int timer = 0;
242
+ uint32_t value = val64;
243
+
244
+ addr = offset >> 2;
245
+ /*
246
+ * Two independent timers has same base address.
247
+ * Based on addr passed figure out which timer is being used.
248
+ */
249
+ if ((addr >= R_TIM1_MAX) && (addr < NUM_TIMERS * R_TIM1_MAX)) {
250
+ timer = 1;
251
+ addr -= R_TIM1_MAX;
252
+ }
253
+
254
+ st = &t->timers[timer];
255
+
256
+ DB_PRINT("addr=0x%" HWADDR_PRIx " val=0x%" PRIx32 " (timer=%d)", offset,
257
+ value, timer);
258
+
259
+ switch (addr) {
260
+ case R_TIM_CTRL:
261
+ st->regs[R_TIM_CTRL] = value;
262
+ timer_update(st);
263
+ break;
264
+
265
+ case R_TIM_RIS:
266
+ if (value & TIMER_RIS_ACK) {
267
+ st->regs[R_TIM_RIS] &= ~TIMER_RIS_ACK;
268
+ }
269
+ break;
270
+
271
+ case R_TIM_LOADVAL:
272
+ st->regs[R_TIM_LOADVAL] = value;
273
+ if (st->regs[R_TIM_CTRL] & TIMER_CTRL_ENBL) {
274
+ timer_update(st);
275
+ }
276
+ break;
277
+
278
+ case R_TIM_BGLOADVAL:
279
+ st->regs[R_TIM_BGLOADVAL] = value;
280
+ st->regs[R_TIM_LOADVAL] = value;
281
+ break;
282
+
283
+ case R_TIM_VAL:
284
+ case R_TIM_MIS:
285
+ break;
286
+
287
+ default:
288
+ if (addr < R_TIM1_MAX) {
289
+ st->regs[addr] = value;
290
+ } else {
291
+ qemu_log_mask(LOG_GUEST_ERROR,
292
+ TYPE_MSS_TIMER": 64-bit mode not supported\n");
293
+ return;
294
+ }
295
+ break;
296
+ }
297
+ timer_update_irq(st);
298
+}
299
+
300
+static const MemoryRegionOps timer_ops = {
301
+ .read = timer_read,
302
+ .write = timer_write,
303
+ .endianness = DEVICE_NATIVE_ENDIAN,
304
+ .valid = {
305
+ .min_access_size = 1,
306
+ .max_access_size = 4
307
+ }
308
+};
309
+
310
+static void timer_hit(void *opaque)
311
+{
312
+ struct Msf2Timer *st = opaque;
313
+
314
+ st->regs[R_TIM_RIS] |= TIMER_RIS_ACK;
315
+
316
+ if (!(st->regs[R_TIM_CTRL] & TIMER_CTRL_ONESHOT)) {
317
+ timer_update(st);
318
+ }
319
+ timer_update_irq(st);
320
+}
321
+
322
+static void mss_timer_init(Object *obj)
323
+{
324
+ MSSTimerState *t = MSS_TIMER(obj);
325
+ int i;
326
+
327
+ /* Init all the ptimers. */
328
+ for (i = 0; i < NUM_TIMERS; i++) {
329
+ struct Msf2Timer *st = &t->timers[i];
330
+
331
+ st->bh = qemu_bh_new(timer_hit, st);
332
+ st->ptimer = ptimer_init(st->bh, PTIMER_POLICY_DEFAULT);
333
+ ptimer_set_freq(st->ptimer, t->freq_hz);
334
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &st->irq);
335
+ }
336
+
337
+ memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, TYPE_MSS_TIMER,
338
+ NUM_TIMERS * R_TIM1_MAX * 4);
339
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &t->mmio);
340
+}
341
+
342
+static const VMStateDescription vmstate_timers = {
343
+ .name = "mss-timer-block",
344
+ .version_id = 1,
345
+ .minimum_version_id = 1,
346
+ .fields = (VMStateField[]) {
347
+ VMSTATE_PTIMER(ptimer, struct Msf2Timer),
348
+ VMSTATE_UINT32_ARRAY(regs, struct Msf2Timer, R_TIM1_MAX),
349
+ VMSTATE_END_OF_LIST()
350
+ }
351
+};
352
+
353
+static const VMStateDescription vmstate_mss_timer = {
354
+ .name = TYPE_MSS_TIMER,
355
+ .version_id = 1,
356
+ .minimum_version_id = 1,
357
+ .fields = (VMStateField[]) {
358
+ VMSTATE_UINT32(freq_hz, MSSTimerState),
359
+ VMSTATE_STRUCT_ARRAY(timers, MSSTimerState, NUM_TIMERS, 0,
360
+ vmstate_timers, struct Msf2Timer),
361
+ VMSTATE_END_OF_LIST()
362
+ }
363
+};
364
+
365
+static Property mss_timer_properties[] = {
366
+ /* Libero GUI shows 100Mhz as default for clocks */
367
+ DEFINE_PROP_UINT32("clock-frequency", MSSTimerState, freq_hz,
368
+ 100 * 1000000),
369
+ DEFINE_PROP_END_OF_LIST(),
370
+};
371
+
372
+static void mss_timer_class_init(ObjectClass *klass, void *data)
373
+{
374
+ DeviceClass *dc = DEVICE_CLASS(klass);
375
+
376
+ dc->props = mss_timer_properties;
377
+ dc->vmsd = &vmstate_mss_timer;
378
+}
379
+
380
+static const TypeInfo mss_timer_info = {
381
+ .name = TYPE_MSS_TIMER,
382
+ .parent = TYPE_SYS_BUS_DEVICE,
383
+ .instance_size = sizeof(MSSTimerState),
384
+ .instance_init = mss_timer_init,
385
+ .class_init = mss_timer_class_init,
386
+};
387
+
388
+static void mss_timer_register_types(void)
389
+{
390
+ type_register_static(&mss_timer_info);
391
+}
392
+
393
+type_init(mss_timer_register_types)
394
--
140
--
395
2.7.4
141
2.25.1
396
142
397
143
diff view generated by jsdifflib
1
For the v8M security extension, some exceptions must be banked
1
In the SSE decode function gen_sse(), we combine a byte
2
between security states. Add the new vecinfo array which holds
2
'b' and a value 'b1' which can be [0..3], and switch on them:
3
the state for the banked exceptions and migrate it if the
3
b |= (b1 << 8);
4
CPU the NVIC is attached to implements the security extension.
4
switch (b) {
5
...
6
default:
7
unknown_op:
8
gen_unknown_opcode(env, s);
9
return;
10
}
5
11
12
In three cases inside this switch, we were then also checking for
13
"if (b1 >= 2) { goto unknown_op; }".
14
However, this can never happen, because the 'case' values in each place
15
are 0x0nn or 0x1nn and the switch will have directed the b1 == (2, 3)
16
cases to the default already.
17
18
This check was added in commit c045af25a52e9 in 2010; the added code
19
was unnecessary then as well, and was apparently intended only to
20
ensure that we never accidentally ended up indexing off the end
21
of an sse_op_table with only 2 entries as a result of future bugs
22
in the decode logic.
23
24
Change the checks to assert() instead, and make sure they're always
25
immediately before the array access they are protecting.
26
27
Fixes: Coverity CID 1460207
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
---
30
---
9
include/hw/intc/armv7m_nvic.h | 14 ++++++++++++
31
target/i386/tcg/translate.c | 12 +++---------
10
hw/intc/armv7m_nvic.c | 53 ++++++++++++++++++++++++++++++++++++++++++-
32
1 file changed, 3 insertions(+), 9 deletions(-)
11
2 files changed, 66 insertions(+), 1 deletion(-)
12
33
13
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
34
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/intc/armv7m_nvic.h
36
--- a/target/i386/tcg/translate.c
16
+++ b/include/hw/intc/armv7m_nvic.h
37
+++ b/target/i386/tcg/translate.c
17
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
18
39
case 0x171: /* shift xmm, im */
19
/* Highest permitted number of exceptions (architectural limit) */
40
case 0x172:
20
#define NVIC_MAX_VECTORS 512
41
case 0x173:
21
+/* Number of internal exceptions */
42
- if (b1 >= 2) {
22
+#define NVIC_INTERNAL_VECTORS 16
43
- goto unknown_op;
23
44
- }
24
typedef struct VecInfo {
45
val = x86_ldub_code(env, s);
25
/* Exception priorities can range from -3 to 255; only the unmodifiable
46
if (is_xmm) {
26
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
47
tcg_gen_movi_tl(s->T0, val);
27
ARMCPU *cpu;
48
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
28
49
offsetof(CPUX86State, mmx_t0.MMX_L(1)));
29
VecInfo vectors[NVIC_MAX_VECTORS];
50
op1_offset = offsetof(CPUX86State,mmx_t0);
30
+ /* If the v8M security extension is implemented, some of the internal
51
}
31
+ * exceptions are banked between security states (ie there exists both
52
+ assert(b1 < 2);
32
+ * a Secure and a NonSecure version of the exception and its state):
53
sse_fn_epp = sse_op_table2[((b - 1) & 3) * 8 +
33
+ * HardFault, MemManage, UsageFault, SVCall, PendSV, SysTick (R_PJHV)
54
(((modrm >> 3)) & 7)][b1];
34
+ * The rest (including all the external exceptions) are not banked, though
55
if (!sse_fn_epp) {
35
+ * they may be configurable to target either Secure or NonSecure state.
56
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
36
+ * We store the secure exception state in sec_vectors[] for the banked
57
rm = modrm & 7;
37
+ * exceptions, and otherwise use only vectors[] (including for exceptions
58
reg = ((modrm >> 3) & 7) | REX_R(s);
38
+ * like SecureFault that unconditionally target Secure state).
59
mod = (modrm >> 6) & 3;
39
+ * Entries in sec_vectors[] for non-banked exception numbers are unused.
60
- if (b1 >= 2) {
40
+ */
61
- goto unknown_op;
41
+ VecInfo sec_vectors[NVIC_INTERNAL_VECTORS];
62
- }
42
uint32_t prigroup;
63
43
64
+ assert(b1 < 2);
44
/* vectpending and exception_prio are both cached state that can
65
sse_fn_epp = sse_op_table6[b].op[b1];
45
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
66
if (!sse_fn_epp) {
46
index XXXXXXX..XXXXXXX 100644
67
goto unknown_op;
47
--- a/hw/intc/armv7m_nvic.c
68
@@ -XXX,XX +XXX,XX @@ static void gen_sse(CPUX86State *env, DisasContext *s, int b,
48
+++ b/hw/intc/armv7m_nvic.c
69
rm = modrm & 7;
49
@@ -XXX,XX +XXX,XX @@
70
reg = ((modrm >> 3) & 7) | REX_R(s);
50
* For historical reasons QEMU tends to use "interrupt" and
71
mod = (modrm >> 6) & 3;
51
* "exception" more or less interchangeably.
72
- if (b1 >= 2) {
52
*/
73
- goto unknown_op;
53
-#define NVIC_FIRST_IRQ 16
74
- }
54
+#define NVIC_FIRST_IRQ NVIC_INTERNAL_VECTORS
75
55
#define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ)
76
+ assert(b1 < 2);
56
77
sse_fn_eppi = sse_op_table7[b].op[b1];
57
/* Effective running priority of the CPU when no exception is active
78
if (!sse_fn_eppi) {
58
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_VecInfo = {
79
goto unknown_op;
59
}
60
};
61
62
+static bool nvic_security_needed(void *opaque)
63
+{
64
+ NVICState *s = opaque;
65
+
66
+ return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY);
67
+}
68
+
69
+static int nvic_security_post_load(void *opaque, int version_id)
70
+{
71
+ NVICState *s = opaque;
72
+ int i;
73
+
74
+ /* Check for out of range priority settings */
75
+ if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) {
76
+ return 1;
77
+ }
78
+ for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
79
+ if (s->sec_vectors[i].prio & ~0xff) {
80
+ return 1;
81
+ }
82
+ }
83
+ return 0;
84
+}
85
+
86
+static const VMStateDescription vmstate_nvic_security = {
87
+ .name = "nvic/m-security",
88
+ .version_id = 1,
89
+ .minimum_version_id = 1,
90
+ .needed = nvic_security_needed,
91
+ .post_load = &nvic_security_post_load,
92
+ .fields = (VMStateField[]) {
93
+ VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1,
94
+ vmstate_VecInfo, VecInfo),
95
+ VMSTATE_END_OF_LIST()
96
+ }
97
+};
98
+
99
static const VMStateDescription vmstate_nvic = {
100
.name = "armv7m_nvic",
101
.version_id = 4,
102
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic = {
103
vmstate_VecInfo, VecInfo),
104
VMSTATE_UINT32(prigroup, NVICState),
105
VMSTATE_END_OF_LIST()
106
+ },
107
+ .subsections = (const VMStateDescription*[]) {
108
+ &vmstate_nvic_security,
109
+ NULL
110
}
111
};
112
113
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
114
s->vectors[ARMV7M_EXCP_NMI].prio = -2;
115
s->vectors[ARMV7M_EXCP_HARD].prio = -1;
116
117
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
118
+ s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1;
119
+ s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1;
120
+ s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
121
+ s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
122
+
123
+ /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */
124
+ s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
125
+ }
126
+
127
/* Strictly speaking the reset handler should be enabled.
128
* However, we don't simulate soft resets through the NVIC,
129
* and the reset vector should never be pended.
130
--
80
--
131
2.7.4
81
2.25.1
132
82
133
83
diff view generated by jsdifflib
1
Don't use the old_mmio in the memory region ops struct.
1
The qemu-common.h header is not supposed to be included from any
2
other header files, only from .c files (as documented in a comment at
3
the start of it).
4
5
include/hw/i386/x86.h and include/hw/i386/microvm.h break this rule.
6
In fact, the include is not required at all, so we can just drop it
7
from both files.
2
8
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1505580378-9044-4-git-send-email-peter.maydell@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Message-id: 20211129200510.1233037-2-peter.maydell@linaro.org
6
---
13
---
7
hw/timer/omap_synctimer.c | 35 +++++++++++++++++++++--------------
14
include/hw/i386/microvm.h | 1 -
8
1 file changed, 21 insertions(+), 14 deletions(-)
15
include/hw/i386/x86.h | 1 -
16
2 files changed, 2 deletions(-)
9
17
10
diff --git a/hw/timer/omap_synctimer.c b/hw/timer/omap_synctimer.c
18
diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h
11
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/timer/omap_synctimer.c
20
--- a/include/hw/i386/microvm.h
13
+++ b/hw/timer/omap_synctimer.c
21
+++ b/include/hw/i386/microvm.h
14
@@ -XXX,XX +XXX,XX @@ static uint32_t omap_synctimer_readh(void *opaque, hwaddr addr)
22
@@ -XXX,XX +XXX,XX @@
15
}
23
#ifndef HW_I386_MICROVM_H
16
}
24
#define HW_I386_MICROVM_H
17
25
18
-static void omap_synctimer_write(void *opaque, hwaddr addr,
26
-#include "qemu-common.h"
19
- uint32_t value)
27
#include "exec/hwaddr.h"
20
+static uint64_t omap_synctimer_readfn(void *opaque, hwaddr addr,
28
#include "qemu/notify.h"
21
+ unsigned size)
29
22
+{
30
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
23
+ switch (size) {
31
index XXXXXXX..XXXXXXX 100644
24
+ case 1:
32
--- a/include/hw/i386/x86.h
25
+ return omap_badwidth_read32(opaque, addr);
33
+++ b/include/hw/i386/x86.h
26
+ case 2:
34
@@ -XXX,XX +XXX,XX @@
27
+ return omap_synctimer_readh(opaque, addr);
35
#ifndef HW_I386_X86_H
28
+ case 4:
36
#define HW_I386_X86_H
29
+ return omap_synctimer_readw(opaque, addr);
37
30
+ default:
38
-#include "qemu-common.h"
31
+ g_assert_not_reached();
39
#include "exec/hwaddr.h"
32
+ }
40
#include "qemu/notify.h"
33
+}
34
+
35
+static void omap_synctimer_writefn(void *opaque, hwaddr addr,
36
+ uint64_t value, unsigned size)
37
{
38
OMAP_BAD_REG(addr);
39
}
40
41
static const MemoryRegionOps omap_synctimer_ops = {
42
- .old_mmio = {
43
- .read = {
44
- omap_badwidth_read32,
45
- omap_synctimer_readh,
46
- omap_synctimer_readw,
47
- },
48
- .write = {
49
- omap_badwidth_write32,
50
- omap_synctimer_write,
51
- omap_synctimer_write,
52
- },
53
- },
54
+ .read = omap_synctimer_readfn,
55
+ .write = omap_synctimer_writefn,
56
+ .valid.min_access_size = 1,
57
+ .valid.max_access_size = 4,
58
.endianness = DEVICE_NATIVE_ENDIAN,
59
};
60
41
61
--
42
--
62
2.7.4
43
2.25.1
63
44
64
45
diff view generated by jsdifflib
1
When escalating to HardFault, we must go into Lockup if we
1
The qemu-common.h header is not supposed to be included from any
2
can't take the synchronous HardFault because the current
2
other header files, only from .c files (as documented in a comment at
3
execution priority is already at or below the priority of
3
the start of it).
4
HardFault. In v7M HF is always priority -1 so a simple < 0
4
5
comparison sufficed; in v8M the priority of HardFault can
5
Move the include to linux-user/hexagon/cpu_loop.c, which needs it for
6
vary depending on whether it is a Secure or NonSecure
6
the declaration of cpu_exec_step_atomic().
7
HardFault, so we must check against the priority of the
8
HardFault exception vector we're about to use.
9
7
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1505240046-11454-13-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Message-id: 20211129200510.1233037-3-peter.maydell@linaro.org
13
---
13
---
14
hw/intc/armv7m_nvic.c | 23 ++++++++++++-----------
14
target/hexagon/cpu.h | 1 -
15
1 file changed, 12 insertions(+), 11 deletions(-)
15
linux-user/hexagon/cpu_loop.c | 1 +
16
2 files changed, 1 insertion(+), 1 deletion(-)
16
17
17
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
18
diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/armv7m_nvic.c
20
--- a/target/hexagon/cpu.h
20
+++ b/hw/intc/armv7m_nvic.c
21
+++ b/target/hexagon/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUHexagonState CPUHexagonState;
22
}
23
23
24
#include "fpu/softfloat-types.h"
24
if (escalate) {
25
25
- if (running < 0) {
26
-#include "qemu-common.h"
26
- /* We want to escalate to HardFault but we can't take a
27
#include "exec/cpu-defs.h"
27
- * synchronous HardFault at this point either. This is a
28
#include "hex_regs.h"
28
- * Lockup condition due to a guest bug. We don't model
29
#include "mmvec/mmvec.h"
29
- * Lockup, so report via cpu_abort() instead.
30
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
30
- */
31
index XXXXXXX..XXXXXXX 100644
31
- cpu_abort(&s->cpu->parent_obj,
32
--- a/linux-user/hexagon/cpu_loop.c
32
- "Lockup: can't escalate %d to HardFault "
33
+++ b/linux-user/hexagon/cpu_loop.c
33
- "(current priority %d)\n", irq, running);
34
@@ -XXX,XX +XXX,XX @@
34
- }
35
*/
35
36
36
- /* We can do the escalation, so we take HardFault instead.
37
#include "qemu/osdep.h"
37
+ /* We need to escalate this exception to a synchronous HardFault.
38
+#include "qemu-common.h"
38
* If BFHFNMINS is set then we escalate to the banked HF for
39
#include "qemu.h"
39
* the target security state of the original exception; otherwise
40
#include "user-internals.h"
40
* we take a Secure HardFault.
41
#include "cpu_loop-common.h"
41
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
42
} else {
43
vec = &s->vectors[irq];
44
}
45
+ if (running <= vec->prio) {
46
+ /* We want to escalate to HardFault but we can't take the
47
+ * synchronous HardFault at this point either. This is a
48
+ * Lockup condition due to a guest bug. We don't model
49
+ * Lockup, so report via cpu_abort() instead.
50
+ */
51
+ cpu_abort(&s->cpu->parent_obj,
52
+ "Lockup: can't escalate %d to HardFault "
53
+ "(current priority %d)\n", irq, running);
54
+ }
55
+
56
/* HF may be banked but there is only one shared HFSR */
57
s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
58
}
59
--
42
--
60
2.7.4
43
2.25.1
61
44
62
45
diff view generated by jsdifflib
1
In v7M, the fixed-priority exceptions are:
1
The qemu-common.h header is not supposed to be included from any
2
Reset: -3
2
other header files, only from .c files (as documented in a comment at
3
NMI: -2
3
the start of it).
4
HardFault: -1
5
4
6
In v8M, this changes because Secure HardFault may need
5
Nothing actually relies on target/rx/cpu.h including it, so we can
7
to be prioritised above NMI:
6
just drop the include.
8
Reset: -4
9
Secure HardFault if AIRCR.BFHFNMINS == 1: -3
10
NMI: -2
11
Secure HardFault if AIRCR.BFHFNMINS == 0: -1
12
NonSecure HardFault: -1
13
14
Make these changes, including support for changing the
15
priority of Secure HardFault as AIRCR.BFHFNMINS changes.
16
7
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 1505240046-11454-14-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
12
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
13
Message-id: 20211129200510.1233037-4-peter.maydell@linaro.org
20
---
14
---
21
hw/intc/armv7m_nvic.c | 22 +++++++++++++++++++---
15
target/rx/cpu.h | 1 -
22
1 file changed, 19 insertions(+), 3 deletions(-)
16
1 file changed, 1 deletion(-)
23
17
24
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
18
diff --git a/target/rx/cpu.h b/target/rx/cpu.h
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/armv7m_nvic.c
20
--- a/target/rx/cpu.h
27
+++ b/hw/intc/armv7m_nvic.c
21
+++ b/target/rx/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
22
@@ -XXX,XX +XXX,XX @@
29
(R_V7M_AIRCR_SYSRESETREQS_MASK |
23
#define RX_CPU_H
30
R_V7M_AIRCR_BFHFNMINS_MASK |
24
31
R_V7M_AIRCR_PRIS_MASK);
25
#include "qemu/bitops.h"
32
+ /* BFHFNMINS changes the priority of Secure HardFault */
26
-#include "qemu-common.h"
33
+ if (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
27
#include "hw/registerfields.h"
34
+ s->sec_vectors[ARMV7M_EXCP_HARD].prio = -3;
28
#include "cpu-qom.h"
35
+ } else {
36
+ s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1;
37
+ }
38
}
39
nvic_irq_update(s);
40
}
41
@@ -XXX,XX +XXX,XX @@ static int nvic_post_load(void *opaque, int version_id)
42
{
43
NVICState *s = opaque;
44
unsigned i;
45
+ int resetprio;
46
47
/* Check for out of range priority settings */
48
- if (s->vectors[ARMV7M_EXCP_RESET].prio != -3 ||
49
+ resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
50
+
51
+ if (s->vectors[ARMV7M_EXCP_RESET].prio != resetprio ||
52
s->vectors[ARMV7M_EXCP_NMI].prio != -2 ||
53
s->vectors[ARMV7M_EXCP_HARD].prio != -1) {
54
return 1;
55
@@ -XXX,XX +XXX,XX @@ static int nvic_security_post_load(void *opaque, int version_id)
56
int i;
57
58
/* Check for out of range priority settings */
59
- if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) {
60
+ if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1
61
+ && s->sec_vectors[ARMV7M_EXCP_HARD].prio != -3) {
62
+ /* We can't cross-check against AIRCR.BFHFNMINS as we don't know
63
+ * if the CPU state has been migrated yet; a mismatch won't
64
+ * cause the emulation to blow up, though.
65
+ */
66
return 1;
67
}
68
for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) {
69
@@ -XXX,XX +XXX,XX @@ static Property props_nvic[] = {
70
71
static void armv7m_nvic_reset(DeviceState *dev)
72
{
73
+ int resetprio;
74
NVICState *s = NVIC(dev);
75
76
s->vectors[ARMV7M_EXCP_NMI].enabled = 1;
77
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_reset(DeviceState *dev)
78
s->vectors[ARMV7M_EXCP_PENDSV].enabled = 1;
79
s->vectors[ARMV7M_EXCP_SYSTICK].enabled = 1;
80
81
- s->vectors[ARMV7M_EXCP_RESET].prio = -3;
82
+ resetprio = arm_feature(&s->cpu->env, ARM_FEATURE_V8) ? -4 : -3;
83
+ s->vectors[ARMV7M_EXCP_RESET].prio = resetprio;
84
s->vectors[ARMV7M_EXCP_NMI].prio = -2;
85
s->vectors[ARMV7M_EXCP_HARD].prio = -1;
86
29
87
--
30
--
88
2.7.4
31
2.25.1
89
32
90
33
diff view generated by jsdifflib
1
Update the code in nvic_rettobase() so that it checks the
1
A lot of C files in hw/arm include qemu-common.h when they don't
2
sec_vectors[] array as well as the vectors[] array if needed.
2
need anything from it. Drop the include lines.
3
4
omap1.c, pxa2xx.c and strongarm.c retain the include because they
5
use it for the prototype of qemu_get_timedate().
3
6
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1505240046-11454-7-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Taylor Simpson <tsimpson@quicinc.com>
11
Reviewed-by: Yoshinori Sato <ysato@users.sourceforge.jp>
12
Message-id: 20211129200510.1233037-5-peter.maydell@linaro.org
7
---
13
---
8
hw/intc/armv7m_nvic.c | 5 ++++-
14
hw/arm/boot.c | 1 -
9
1 file changed, 4 insertions(+), 1 deletion(-)
15
hw/arm/digic_boards.c | 1 -
16
hw/arm/highbank.c | 1 -
17
hw/arm/npcm7xx_boards.c | 1 -
18
hw/arm/sbsa-ref.c | 1 -
19
hw/arm/stm32f405_soc.c | 1 -
20
hw/arm/vexpress.c | 1 -
21
hw/arm/virt.c | 1 -
22
8 files changed, 8 deletions(-)
10
23
11
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
24
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
12
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/armv7m_nvic.c
26
--- a/hw/arm/boot.c
14
+++ b/hw/intc/armv7m_nvic.c
27
+++ b/hw/arm/boot.c
15
@@ -XXX,XX +XXX,XX @@ static int nvic_pending_prio(NVICState *s)
28
@@ -XXX,XX +XXX,XX @@
16
static bool nvic_rettobase(NVICState *s)
29
*/
17
{
30
18
int irq, nhand = 0;
31
#include "qemu/osdep.h"
19
+ bool check_sec = arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY);
32
-#include "qemu-common.h"
20
33
#include "qemu/datadir.h"
21
for (irq = ARMV7M_EXCP_RESET; irq < s->num_irq; irq++) {
34
#include "qemu/error-report.h"
22
- if (s->vectors[irq].active) {
35
#include "qapi/error.h"
23
+ if (s->vectors[irq].active ||
36
diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c
24
+ (check_sec && irq < NVIC_INTERNAL_VECTORS &&
37
index XXXXXXX..XXXXXXX 100644
25
+ s->sec_vectors[irq].active)) {
38
--- a/hw/arm/digic_boards.c
26
nhand++;
39
+++ b/hw/arm/digic_boards.c
27
if (nhand == 2) {
40
@@ -XXX,XX +XXX,XX @@
28
return 0;
41
42
#include "qemu/osdep.h"
43
#include "qapi/error.h"
44
-#include "qemu-common.h"
45
#include "qemu/datadir.h"
46
#include "hw/boards.h"
47
#include "qemu/error-report.h"
48
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/highbank.c
51
+++ b/hw/arm/highbank.c
52
@@ -XXX,XX +XXX,XX @@
53
*/
54
55
#include "qemu/osdep.h"
56
-#include "qemu-common.h"
57
#include "qemu/datadir.h"
58
#include "qapi/error.h"
59
#include "hw/sysbus.h"
60
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx_boards.c
63
+++ b/hw/arm/npcm7xx_boards.c
64
@@ -XXX,XX +XXX,XX @@
65
#include "hw/qdev-core.h"
66
#include "hw/qdev-properties.h"
67
#include "qapi/error.h"
68
-#include "qemu-common.h"
69
#include "qemu/datadir.h"
70
#include "qemu/units.h"
71
#include "sysemu/blockdev.h"
72
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/arm/sbsa-ref.c
75
+++ b/hw/arm/sbsa-ref.c
76
@@ -XXX,XX +XXX,XX @@
77
*/
78
79
#include "qemu/osdep.h"
80
-#include "qemu-common.h"
81
#include "qemu/datadir.h"
82
#include "qapi/error.h"
83
#include "qemu/error-report.h"
84
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/arm/stm32f405_soc.c
87
+++ b/hw/arm/stm32f405_soc.c
88
@@ -XXX,XX +XXX,XX @@
89
90
#include "qemu/osdep.h"
91
#include "qapi/error.h"
92
-#include "qemu-common.h"
93
#include "exec/address-spaces.h"
94
#include "sysemu/sysemu.h"
95
#include "hw/arm/stm32f405_soc.h"
96
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/arm/vexpress.c
99
+++ b/hw/arm/vexpress.c
100
@@ -XXX,XX +XXX,XX @@
101
102
#include "qemu/osdep.h"
103
#include "qapi/error.h"
104
-#include "qemu-common.h"
105
#include "qemu/datadir.h"
106
#include "cpu.h"
107
#include "hw/sysbus.h"
108
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/arm/virt.c
111
+++ b/hw/arm/virt.c
112
@@ -XXX,XX +XXX,XX @@
113
*/
114
115
#include "qemu/osdep.h"
116
-#include "qemu-common.h"
117
#include "qemu/datadir.h"
118
#include "qemu/units.h"
119
#include "qemu/option.h"
29
--
120
--
30
2.7.4
121
2.25.1
31
122
32
123
diff view generated by jsdifflib
1
In v8M the MSR and MRS instructions have extra register value
1
The calculation of the length of TLB range invalidate operations
2
encodings to allow secure code to access the non-secure banked
2
in tlbi_aa64_range_get_length() is incorrect in two ways:
3
version of various special registers.
3
* the NUM field is 5 bits, but we read only 4 bits
4
* we miscalculate the page_shift value, because of an
5
off-by-one error:
6
TG 0b00 is invalid
7
TG 0b01 is 4K granule size == 4096 == 2^12
8
TG 0b10 is 16K granule size == 16384 == 2^14
9
TG 0b11 is 64K granule size == 65536 == 2^16
10
so page_shift should be (TG - 1) * 2 + 12
4
11
5
(We don't implement the MSPLIM_NS or PSPLIM_NS aliases, because
12
Thanks to the bug report submitter Cha HyunSoo for identifying
6
we don't currently implement the stack limit registers at all.)
13
both these errors.
7
14
15
Fixes: 84940ed82552d3c ("target/arm: Add support for FEAT_TLBIRANGE")
16
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/734
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 1505240046-11454-2-git-send-email-peter.maydell@linaro.org
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20211130173257.1274194-1-peter.maydell@linaro.org
11
---
22
---
12
target/arm/helper.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++
23
target/arm/helper.c | 6 +++---
13
1 file changed, 110 insertions(+)
24
1 file changed, 3 insertions(+), 3 deletions(-)
14
25
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
28
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
29
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
30
@@ -XXX,XX +XXX,XX @@ static uint64_t tlbi_aa64_range_get_length(CPUARMState *env,
20
break;
31
uint64_t exponent;
21
case 20: /* CONTROL */
32
uint64_t length;
22
return env->v7m.control[env->v7m.secure];
33
23
+ case 0x94: /* CONTROL_NS */
34
- num = extract64(value, 39, 4);
24
+ /* We have to handle this here because unprivileged Secure code
35
+ num = extract64(value, 39, 5);
25
+ * can read the NS CONTROL register.
36
scale = extract64(value, 44, 2);
26
+ */
37
page_size_granule = extract64(value, 46, 2);
27
+ if (!env->v7m.secure) {
38
28
+ return 0;
39
- page_shift = page_size_granule * 2 + 12;
29
+ }
40
-
30
+ return env->v7m.control[M_REG_NS];
41
if (page_size_granule == 0) {
42
qemu_log_mask(LOG_GUEST_ERROR, "Invalid page size granule %d\n",
43
page_size_granule);
44
return 0;
31
}
45
}
32
46
33
if (el == 0) {
47
+ page_shift = (page_size_granule - 1) * 2 + 12;
34
return 0; /* unprivileged reads others as zero */
35
}
36
37
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
38
+ switch (reg) {
39
+ case 0x88: /* MSP_NS */
40
+ if (!env->v7m.secure) {
41
+ return 0;
42
+ }
43
+ return env->v7m.other_ss_msp;
44
+ case 0x89: /* PSP_NS */
45
+ if (!env->v7m.secure) {
46
+ return 0;
47
+ }
48
+ return env->v7m.other_ss_psp;
49
+ case 0x90: /* PRIMASK_NS */
50
+ if (!env->v7m.secure) {
51
+ return 0;
52
+ }
53
+ return env->v7m.primask[M_REG_NS];
54
+ case 0x91: /* BASEPRI_NS */
55
+ if (!env->v7m.secure) {
56
+ return 0;
57
+ }
58
+ return env->v7m.basepri[M_REG_NS];
59
+ case 0x93: /* FAULTMASK_NS */
60
+ if (!env->v7m.secure) {
61
+ return 0;
62
+ }
63
+ return env->v7m.faultmask[M_REG_NS];
64
+ case 0x98: /* SP_NS */
65
+ {
66
+ /* This gives the non-secure SP selected based on whether we're
67
+ * currently in handler mode or not, using the NS CONTROL.SPSEL.
68
+ */
69
+ bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
70
+
48
+
71
+ if (!env->v7m.secure) {
49
exponent = (5 * scale) + 1;
72
+ return 0;
50
length = (num + 1) << (exponent + page_shift);
73
+ }
51
74
+ if (!arm_v7m_is_handler_mode(env) && spsel) {
75
+ return env->v7m.other_ss_psp;
76
+ } else {
77
+ return env->v7m.other_ss_msp;
78
+ }
79
+ }
80
+ default:
81
+ break;
82
+ }
83
+ }
84
+
85
switch (reg) {
86
case 8: /* MSP */
87
return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
88
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
89
return;
90
}
91
92
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
93
+ switch (reg) {
94
+ case 0x88: /* MSP_NS */
95
+ if (!env->v7m.secure) {
96
+ return;
97
+ }
98
+ env->v7m.other_ss_msp = val;
99
+ return;
100
+ case 0x89: /* PSP_NS */
101
+ if (!env->v7m.secure) {
102
+ return;
103
+ }
104
+ env->v7m.other_ss_psp = val;
105
+ return;
106
+ case 0x90: /* PRIMASK_NS */
107
+ if (!env->v7m.secure) {
108
+ return;
109
+ }
110
+ env->v7m.primask[M_REG_NS] = val & 1;
111
+ return;
112
+ case 0x91: /* BASEPRI_NS */
113
+ if (!env->v7m.secure) {
114
+ return;
115
+ }
116
+ env->v7m.basepri[M_REG_NS] = val & 0xff;
117
+ return;
118
+ case 0x93: /* FAULTMASK_NS */
119
+ if (!env->v7m.secure) {
120
+ return;
121
+ }
122
+ env->v7m.faultmask[M_REG_NS] = val & 1;
123
+ return;
124
+ case 0x98: /* SP_NS */
125
+ {
126
+ /* This gives the non-secure SP selected based on whether we're
127
+ * currently in handler mode or not, using the NS CONTROL.SPSEL.
128
+ */
129
+ bool spsel = env->v7m.control[M_REG_NS] & R_V7M_CONTROL_SPSEL_MASK;
130
+
131
+ if (!env->v7m.secure) {
132
+ return;
133
+ }
134
+ if (!arm_v7m_is_handler_mode(env) && spsel) {
135
+ env->v7m.other_ss_psp = val;
136
+ } else {
137
+ env->v7m.other_ss_msp = val;
138
+ }
139
+ return;
140
+ }
141
+ default:
142
+ break;
143
+ }
144
+ }
145
+
146
switch (reg) {
147
case 0 ... 7: /* xPSR sub-fields */
148
/* only APSR is actually writable */
149
--
52
--
150
2.7.4
53
2.25.1
151
54
152
55
diff view generated by jsdifflib
1
Make the set_prio() function take a bool indicating
1
From: Patrick Venture <venture@google.com>
2
whether to pend the secure or non-secure version of a banked
3
interrupt, and use this to implement the correct banking
4
semantics for the SHPR registers.
5
2
3
The rx_active boolean change to true should always trigger a try_read
4
call that flushes the queue.
5
6
Signed-off-by: Patrick Venture <venture@google.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20211203221002.1719306-1-venture@google.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1505240046-11454-11-git-send-email-peter.maydell@linaro.org
9
---
10
---
10
hw/intc/armv7m_nvic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++-----
11
hw/net/npcm7xx_emc.c | 18 ++++++++----------
11
hw/intc/trace-events | 2 +-
12
1 file changed, 8 insertions(+), 10 deletions(-)
12
2 files changed, 88 insertions(+), 10 deletions(-)
13
13
14
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
14
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/armv7m_nvic.c
16
--- a/hw/net/npcm7xx_emc.c
17
+++ b/hw/intc/armv7m_nvic.c
17
+++ b/hw/net/npcm7xx_emc.c
18
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_raw_execution_priority(void *opaque)
18
@@ -XXX,XX +XXX,XX @@ static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
19
return s->exception_prio;
19
emc_set_mista(emc, mista_flag);
20
}
20
}
21
21
22
-/* caller must call nvic_irq_update() after this */
22
+static void emc_enable_rx_and_flush(NPCM7xxEMCState *emc)
23
-static void set_prio(NVICState *s, unsigned irq, uint8_t prio)
23
+{
24
+/* caller must call nvic_irq_update() after this.
24
+ emc->rx_active = true;
25
+ * secure indicates the bank to use for banked exceptions (we assert if
25
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
26
+ * we are passed secure=true for a non-banked exception).
27
+ */
28
+static void set_prio(NVICState *s, unsigned irq, bool secure, uint8_t prio)
29
{
30
assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */
31
assert(irq < s->num_irq);
32
33
- s->vectors[irq].prio = prio;
34
+ if (secure) {
35
+ assert(exc_is_banked(irq));
36
+ s->sec_vectors[irq].prio = prio;
37
+ } else {
38
+ s->vectors[irq].prio = prio;
39
+ }
40
+
41
+ trace_nvic_set_prio(irq, secure, prio);
42
+}
26
+}
43
+
27
+
44
+/* Return the current raw priority register value.
28
static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
45
+ * secure indicates the bank to use for banked exceptions (we assert if
29
const NPCM7xxEMCTxDesc *tx_desc,
46
+ * we are passed secure=true for a non-banked exception).
30
uint32_t desc_addr)
47
+ */
31
@@ -XXX,XX +XXX,XX @@ static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
48
+static int get_prio(NVICState *s, unsigned irq, bool secure)
32
return len;
49
+{
50
+ assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */
51
+ assert(irq < s->num_irq);
52
53
- trace_nvic_set_prio(irq, prio);
54
+ if (secure) {
55
+ assert(exc_is_banked(irq));
56
+ return s->sec_vectors[irq].prio;
57
+ } else {
58
+ return s->vectors[irq].prio;
59
+ }
60
}
33
}
61
34
62
/* Recompute state and assert irq line accordingly.
35
-static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
63
@@ -XXX,XX +XXX,XX @@ static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs)
36
-{
64
}
37
- if (emc_can_receive(qemu_get_queue(emc->nic))) {
65
}
38
- qemu_flush_queued_packets(qemu_get_queue(emc->nic));
66
39
- }
67
+static int shpr_bank(NVICState *s, int exc, MemTxAttrs attrs)
40
-}
68
+{
41
-
69
+ /* Behaviour for the SHPR register field for this exception:
42
static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
70
+ * return M_REG_NS to use the nonsecure vector (including for
43
{
71
+ * non-banked exceptions), M_REG_S for the secure version of
44
NPCM7xxEMCState *emc = opaque;
72
+ * a banked exception, and -1 if this field should RAZ/WI.
45
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
73
+ */
46
emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
74
+ switch (exc) {
47
}
75
+ case ARMV7M_EXCP_MEM:
48
if (value & REG_MCMDR_RXON) {
76
+ case ARMV7M_EXCP_USAGE:
49
- emc->rx_active = true;
77
+ case ARMV7M_EXCP_SVC:
50
+ emc_enable_rx_and_flush(emc);
78
+ case ARMV7M_EXCP_PENDSV:
51
} else {
79
+ case ARMV7M_EXCP_SYSTICK:
52
emc_halt_rx(emc, 0);
80
+ /* Banked exceptions */
53
}
81
+ return attrs.secure;
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_emc_write(void *opaque, hwaddr offset,
82
+ case ARMV7M_EXCP_BUS:
55
break;
83
+ /* Not banked, RAZ/WI from nonsecure if BFHFNMINS is zero */
56
case REG_RSDR:
84
+ if (!attrs.secure &&
57
if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
85
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
58
- emc->rx_active = true;
86
+ return -1;
59
- emc_try_receive_next_packet(emc);
87
+ }
60
+ emc_enable_rx_and_flush(emc);
88
+ return M_REG_NS;
89
+ case ARMV7M_EXCP_SECURE:
90
+ /* Not banked, RAZ/WI from nonsecure */
91
+ if (!attrs.secure) {
92
+ return -1;
93
+ }
94
+ return M_REG_NS;
95
+ case ARMV7M_EXCP_DEBUG:
96
+ /* Not banked. TODO should RAZ/WI if DEMCR.SDME is set */
97
+ return M_REG_NS;
98
+ case 8 ... 10:
99
+ case 13:
100
+ /* RES0 */
101
+ return -1;
102
+ default:
103
+ /* Not reachable due to decode of SHPR register addresses */
104
+ g_assert_not_reached();
105
+ }
106
+}
107
+
108
static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
109
uint64_t *data, unsigned size,
110
MemTxAttrs attrs)
111
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr,
112
}
113
}
61
}
114
break;
62
break;
115
- case 0xd18 ... 0xd23: /* System Handler Priority. */
63
case REG_MIIDA:
116
+ case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3) */
117
val = 0;
118
for (i = 0; i < size; i++) {
119
- val |= s->vectors[(offset - 0xd14) + i].prio << (i * 8);
120
+ unsigned hdlidx = (offset - 0xd14) + i;
121
+ int sbank = shpr_bank(s, hdlidx, attrs);
122
+
123
+ if (sbank < 0) {
124
+ continue;
125
+ }
126
+ val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank));
127
}
128
break;
129
case 0xfe0 ... 0xfff: /* ID. */
130
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
131
132
for (i = 0; i < size && startvec + i < s->num_irq; i++) {
133
if (attrs.secure || s->itns[startvec + i]) {
134
- set_prio(s, startvec + i, (value >> (i * 8)) & 0xff);
135
+ set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff);
136
}
137
}
138
nvic_irq_update(s);
139
return MEMTX_OK;
140
- case 0xd18 ... 0xd23: /* System Handler Priority. */
141
+ case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3) */
142
for (i = 0; i < size; i++) {
143
unsigned hdlidx = (offset - 0xd14) + i;
144
- set_prio(s, hdlidx, (value >> (i * 8)) & 0xff);
145
+ int newprio = extract32(value, i * 8, 8);
146
+ int sbank = shpr_bank(s, hdlidx, attrs);
147
+
148
+ if (sbank < 0) {
149
+ continue;
150
+ }
151
+ set_prio(s, hdlidx, sbank, newprio);
152
}
153
nvic_irq_update(s);
154
return MEMTX_OK;
155
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
156
index XXXXXXX..XXXXXXX 100644
157
--- a/hw/intc/trace-events
158
+++ b/hw/intc/trace-events
159
@@ -XXX,XX +XXX,XX @@ gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending S
160
# hw/intc/armv7m_nvic.c
161
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
162
nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d"
163
-nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d"
164
+nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %d priority %d"
165
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
166
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
167
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
168
--
64
--
169
2.7.4
65
2.25.1
170
66
171
67
diff view generated by jsdifflib
1
Drop the use of old_mmio in the omap2_gpio memory ops.
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
When a virtio-iommu is instantiated, describe it using the ACPI VIOT
4
table.
5
6
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Message-id: 20211210170415.583179-2-jean-philippe@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1505580378-9044-3-git-send-email-peter.maydell@linaro.org
6
---
11
---
7
hw/gpio/omap_gpio.c | 26 ++++++++++++--------------
12
hw/arm/virt-acpi-build.c | 7 +++++++
8
1 file changed, 12 insertions(+), 14 deletions(-)
13
hw/arm/Kconfig | 1 +
14
2 files changed, 8 insertions(+)
9
15
10
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
16
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
11
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/gpio/omap_gpio.c
18
--- a/hw/arm/virt-acpi-build.c
13
+++ b/hw/gpio/omap_gpio.c
19
+++ b/hw/arm/virt-acpi-build.c
14
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_module_write(void *opaque, hwaddr addr,
20
@@ -XXX,XX +XXX,XX @@
21
#include "kvm_arm.h"
22
#include "migration/vmstate.h"
23
#include "hw/acpi/ghes.h"
24
+#include "hw/acpi/viot.h"
25
26
#define ARM_SPI_BASE 32
27
28
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
15
}
29
}
16
}
30
#endif
17
31
18
-static uint32_t omap2_gpio_module_readp(void *opaque, hwaddr addr)
32
+ if (vms->iommu == VIRT_IOMMU_VIRTIO) {
19
+static uint64_t omap2_gpio_module_readp(void *opaque, hwaddr addr,
33
+ acpi_add_table(table_offsets, tables_blob);
20
+ unsigned size)
34
+ build_viot(ms, tables_blob, tables->linker, vms->virtio_iommu_bdf,
21
{
35
+ vms->oem_id, vms->oem_table_id);
22
return omap2_gpio_module_read(opaque, addr & ~3) >> ((addr & 3) << 3);
23
}
24
25
static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
26
- uint32_t value)
27
+ uint64_t value, unsigned size)
28
{
29
uint32_t cur = 0;
30
uint32_t mask = 0xffff;
31
32
+ if (size == 4) {
33
+ omap2_gpio_module_write(opaque, addr, value);
34
+ return;
35
+ }
36
+ }
36
+
37
+
37
switch (addr & ~3) {
38
/* XSDT is pointed to by RSDP */
38
case 0x00:    /* GPIO_REVISION */
39
xsdt = tables_blob->len;
39
case 0x14:    /* GPIO_SYSSTATUS */
40
build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
40
@@ -XXX,XX +XXX,XX @@ static void omap2_gpio_module_writep(void *opaque, hwaddr addr,
41
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
41
}
42
index XXXXXXX..XXXXXXX 100644
42
43
--- a/hw/arm/Kconfig
43
static const MemoryRegionOps omap2_gpio_module_ops = {
44
+++ b/hw/arm/Kconfig
44
- .old_mmio = {
45
@@ -XXX,XX +XXX,XX @@ config ARM_VIRT
45
- .read = {
46
select DIMM
46
- omap2_gpio_module_readp,
47
select ACPI_HW_REDUCED
47
- omap2_gpio_module_readp,
48
select ACPI_APEI
48
- omap2_gpio_module_read,
49
+ select ACPI_VIOT
49
- },
50
50
- .write = {
51
config CHEETAH
51
- omap2_gpio_module_writep,
52
bool
52
- omap2_gpio_module_writep,
53
- omap2_gpio_module_write,
54
- },
55
- },
56
+ .read = omap2_gpio_module_readp,
57
+ .write = omap2_gpio_module_writep,
58
+ .valid.min_access_size = 1,
59
+ .valid.max_access_size = 4,
60
.endianness = DEVICE_NATIVE_ENDIAN,
61
};
62
63
--
53
--
64
2.7.4
54
2.25.1
65
55
66
56
diff view generated by jsdifflib
1
Update the static_ops functions to use new-style mmio
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
rather than the legacy old_mmio functions.
3
2
3
virtio-iommu is now supported with ACPI VIOT as well as device tree.
4
Remove the restriction that prevents from instantiating a virtio-iommu
5
device under ACPI.
6
7
Acked-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
10
Message-id: 20211210170415.583179-3-jean-philippe@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1505580378-9044-2-git-send-email-peter.maydell@linaro.org
7
---
12
---
8
hw/arm/palm.c | 30 ++++++++++--------------------
13
hw/arm/virt.c | 10 ++--------
9
1 file changed, 10 insertions(+), 20 deletions(-)
14
hw/virtio/virtio-iommu-pci.c | 12 ++----------
15
2 files changed, 4 insertions(+), 18 deletions(-)
10
16
11
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/palm.c
19
--- a/hw/arm/virt.c
14
+++ b/hw/arm/palm.c
20
+++ b/hw/arm/virt.c
15
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
16
#include "exec/address-spaces.h"
22
MachineClass *mc = MACHINE_GET_CLASS(machine);
17
#include "cpu.h"
23
18
24
if (device_is_dynamic_sysbus(mc, dev) ||
19
-static uint32_t static_readb(void *opaque, hwaddr offset)
25
- (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM))) {
20
+static uint64_t static_read(void *opaque, hwaddr offset, unsigned size)
26
+ object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
21
{
27
+ object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
22
- uint32_t *val = (uint32_t *) opaque;
28
return HOTPLUG_HANDLER(machine);
23
- return *val >> ((offset & 3) << 3);
29
}
24
-}
30
- if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI)) {
25
+ uint32_t *val = (uint32_t *)opaque;
31
- VirtMachineState *vms = VIRT_MACHINE(machine);
26
+ uint32_t sizemask = 7 >> size;
27
28
-static uint32_t static_readh(void *opaque, hwaddr offset)
29
-{
30
- uint32_t *val = (uint32_t *) opaque;
31
- return *val >> ((offset & 1) << 3);
32
-}
33
-
32
-
34
-static uint32_t static_readw(void *opaque, hwaddr offset)
33
- if (!vms->bootinfo.firmware_loaded || !virt_is_acpi_enabled(vms)) {
35
-{
34
- return HOTPLUG_HANDLER(machine);
36
- uint32_t *val = (uint32_t *) opaque;
35
- }
37
- return *val >> ((offset & 0) << 3);
36
- }
38
+ return *val >> ((offset & sizemask) << 3);
37
return NULL;
39
}
38
}
40
39
41
-static void static_write(void *opaque, hwaddr offset,
40
diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c
42
- uint32_t value)
41
index XXXXXXX..XXXXXXX 100644
43
+static void static_write(void *opaque, hwaddr offset, uint64_t value,
42
--- a/hw/virtio/virtio-iommu-pci.c
44
+ unsigned size)
43
+++ b/hw/virtio/virtio-iommu-pci.c
45
{
44
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
46
#ifdef SPY
45
VirtIOIOMMU *s = VIRTIO_IOMMU(vdev);
47
printf("%s: value %08lx written at " PA_FMT "\n",
46
48
@@ -XXX,XX +XXX,XX @@ static void static_write(void *opaque, hwaddr offset,
47
if (!qdev_get_machine_hotplug_handler(DEVICE(vpci_dev))) {
49
}
48
- MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine());
50
49
-
51
static const MemoryRegionOps static_ops = {
50
- error_setg(errp,
52
- .old_mmio = {
51
- "%s machine fails to create iommu-map device tree bindings",
53
- .read = { static_readb, static_readh, static_readw, },
52
- mc->name);
54
- .write = { static_write, static_write, static_write, },
53
- error_append_hint(errp,
55
- },
54
- "Check your machine implements a hotplug handler "
56
+ .read = static_read,
55
- "for the virtio-iommu-pci device\n");
57
+ .write = static_write,
56
- error_append_hint(errp, "Check the guest is booted without FW or with "
58
+ .valid.min_access_size = 1,
57
- "-no-acpi\n");
59
+ .valid.max_access_size = 4,
58
+ error_setg(errp, "Check your machine implements a hotplug handler "
60
.endianness = DEVICE_NATIVE_ENDIAN,
59
+ "for the virtio-iommu-pci device");
61
};
60
return;
62
61
}
62
for (int i = 0; i < s->nb_reserved_regions; i++) {
63
--
63
--
64
2.7.4
64
2.25.1
65
65
66
66
diff view generated by jsdifflib
1
Handle banking of SHCSR: some register bits are banked between
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
Secure and Non-Secure, and some are only accessible to Secure.
3
2
3
We do not support instantiating multiple IOMMUs. Before adding a
4
virtio-iommu, check that no other IOMMU is present. This will detect
5
both "iommu=smmuv3" machine parameter and another virtio-iommu instance.
6
7
Fixes: 70e89132c9 ("hw/arm/virt: Add the virtio-iommu device tree mappings")
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-4-jean-philippe@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 1505240046-11454-19-git-send-email-peter.maydell@linaro.org
7
---
13
---
8
hw/intc/armv7m_nvic.c | 221 ++++++++++++++++++++++++++++++++++++++------------
14
hw/arm/virt.c | 5 +++++
9
1 file changed, 169 insertions(+), 52 deletions(-)
15
1 file changed, 5 insertions(+)
10
16
11
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/intc/armv7m_nvic.c
19
--- a/hw/arm/virt.c
14
+++ b/hw/intc/armv7m_nvic.c
20
+++ b/hw/arm/virt.c
15
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
16
val = cpu->env.v7m.ccr[attrs.secure];
22
hwaddr db_start = 0, db_end = 0;
17
val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK;
23
char *resv_prop_str;
18
return val;
24
19
- case 0xd24: /* System Handler Status. */
25
+ if (vms->iommu != VIRT_IOMMU_NONE) {
20
+ case 0xd24: /* System Handler Control and State (SHCSR) */
26
+ error_setg(errp, "virt machine does not support multiple IOMMUs");
21
val = 0;
27
+ return;
22
- if (s->vectors[ARMV7M_EXCP_MEM].active) {
23
- val |= (1 << 0);
24
- }
25
- if (s->vectors[ARMV7M_EXCP_BUS].active) {
26
- val |= (1 << 1);
27
- }
28
- if (s->vectors[ARMV7M_EXCP_USAGE].active) {
29
- val |= (1 << 3);
30
+ if (attrs.secure) {
31
+ if (s->sec_vectors[ARMV7M_EXCP_MEM].active) {
32
+ val |= (1 << 0);
33
+ }
34
+ if (s->sec_vectors[ARMV7M_EXCP_HARD].active) {
35
+ val |= (1 << 2);
36
+ }
37
+ if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) {
38
+ val |= (1 << 3);
39
+ }
40
+ if (s->sec_vectors[ARMV7M_EXCP_SVC].active) {
41
+ val |= (1 << 7);
42
+ }
43
+ if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) {
44
+ val |= (1 << 10);
45
+ }
46
+ if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) {
47
+ val |= (1 << 11);
48
+ }
49
+ if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) {
50
+ val |= (1 << 12);
51
+ }
52
+ if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) {
53
+ val |= (1 << 13);
54
+ }
55
+ if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) {
56
+ val |= (1 << 15);
57
+ }
58
+ if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) {
59
+ val |= (1 << 16);
60
+ }
61
+ if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) {
62
+ val |= (1 << 18);
63
+ }
64
+ if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) {
65
+ val |= (1 << 21);
66
+ }
67
+ /* SecureFault is not banked but is always RAZ/WI to NS */
68
+ if (s->vectors[ARMV7M_EXCP_SECURE].active) {
69
+ val |= (1 << 4);
70
+ }
71
+ if (s->vectors[ARMV7M_EXCP_SECURE].enabled) {
72
+ val |= (1 << 19);
73
+ }
74
+ if (s->vectors[ARMV7M_EXCP_SECURE].pending) {
75
+ val |= (1 << 20);
76
+ }
77
+ } else {
78
+ if (s->vectors[ARMV7M_EXCP_MEM].active) {
79
+ val |= (1 << 0);
80
+ }
81
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
82
+ /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */
83
+ if (s->vectors[ARMV7M_EXCP_HARD].active) {
84
+ val |= (1 << 2);
85
+ }
86
+ if (s->vectors[ARMV7M_EXCP_HARD].pending) {
87
+ val |= (1 << 21);
88
+ }
89
+ }
90
+ if (s->vectors[ARMV7M_EXCP_USAGE].active) {
91
+ val |= (1 << 3);
92
+ }
93
+ if (s->vectors[ARMV7M_EXCP_SVC].active) {
94
+ val |= (1 << 7);
95
+ }
96
+ if (s->vectors[ARMV7M_EXCP_PENDSV].active) {
97
+ val |= (1 << 10);
98
+ }
99
+ if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {
100
+ val |= (1 << 11);
101
+ }
102
+ if (s->vectors[ARMV7M_EXCP_USAGE].pending) {
103
+ val |= (1 << 12);
104
+ }
105
+ if (s->vectors[ARMV7M_EXCP_MEM].pending) {
106
+ val |= (1 << 13);
107
+ }
108
+ if (s->vectors[ARMV7M_EXCP_SVC].pending) {
109
+ val |= (1 << 15);
110
+ }
111
+ if (s->vectors[ARMV7M_EXCP_MEM].enabled) {
112
+ val |= (1 << 16);
113
+ }
114
+ if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {
115
+ val |= (1 << 18);
116
+ }
117
}
118
- if (s->vectors[ARMV7M_EXCP_SVC].active) {
119
- val |= (1 << 7);
120
+ if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
121
+ if (s->vectors[ARMV7M_EXCP_BUS].active) {
122
+ val |= (1 << 1);
123
+ }
124
+ if (s->vectors[ARMV7M_EXCP_BUS].pending) {
125
+ val |= (1 << 14);
126
+ }
127
+ if (s->vectors[ARMV7M_EXCP_BUS].enabled) {
128
+ val |= (1 << 17);
129
+ }
130
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8) &&
131
+ s->vectors[ARMV7M_EXCP_NMI].active) {
132
+ /* NMIACT is not present in v7M */
133
+ val |= (1 << 5);
134
+ }
135
}
136
+
137
+ /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
138
if (s->vectors[ARMV7M_EXCP_DEBUG].active) {
139
val |= (1 << 8);
140
}
141
- if (s->vectors[ARMV7M_EXCP_PENDSV].active) {
142
- val |= (1 << 10);
143
- }
144
- if (s->vectors[ARMV7M_EXCP_SYSTICK].active) {
145
- val |= (1 << 11);
146
- }
147
- if (s->vectors[ARMV7M_EXCP_USAGE].pending) {
148
- val |= (1 << 12);
149
- }
150
- if (s->vectors[ARMV7M_EXCP_MEM].pending) {
151
- val |= (1 << 13);
152
- }
153
- if (s->vectors[ARMV7M_EXCP_BUS].pending) {
154
- val |= (1 << 14);
155
- }
156
- if (s->vectors[ARMV7M_EXCP_SVC].pending) {
157
- val |= (1 << 15);
158
- }
159
- if (s->vectors[ARMV7M_EXCP_MEM].enabled) {
160
- val |= (1 << 16);
161
- }
162
- if (s->vectors[ARMV7M_EXCP_BUS].enabled) {
163
- val |= (1 << 17);
164
- }
165
- if (s->vectors[ARMV7M_EXCP_USAGE].enabled) {
166
- val |= (1 << 18);
167
- }
168
return val;
169
case 0xd28: /* Configurable Fault Status. */
170
/* The BFSR bits [15:8] are shared between security states
171
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
172
173
cpu->env.v7m.ccr[attrs.secure] = value;
174
break;
175
- case 0xd24: /* System Handler Control. */
176
- s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
177
- s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;
178
- s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
179
- s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
180
+ case 0xd24: /* System Handler Control and State (SHCSR) */
181
+ if (attrs.secure) {
182
+ s->sec_vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
183
+ /* Secure HardFault active bit cannot be written */
184
+ s->sec_vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
185
+ s->sec_vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
186
+ s->sec_vectors[ARMV7M_EXCP_PENDSV].active =
187
+ (value & (1 << 10)) != 0;
188
+ s->sec_vectors[ARMV7M_EXCP_SYSTICK].active =
189
+ (value & (1 << 11)) != 0;
190
+ s->sec_vectors[ARMV7M_EXCP_USAGE].pending =
191
+ (value & (1 << 12)) != 0;
192
+ s->sec_vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
193
+ s->sec_vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
194
+ s->sec_vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
195
+ s->sec_vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
196
+ s->sec_vectors[ARMV7M_EXCP_USAGE].enabled =
197
+ (value & (1 << 18)) != 0;
198
+ /* SecureFault not banked, but RAZ/WI to NS */
199
+ s->vectors[ARMV7M_EXCP_SECURE].active = (value & (1 << 4)) != 0;
200
+ s->vectors[ARMV7M_EXCP_SECURE].enabled = (value & (1 << 19)) != 0;
201
+ s->vectors[ARMV7M_EXCP_SECURE].pending = (value & (1 << 20)) != 0;
202
+ } else {
203
+ s->vectors[ARMV7M_EXCP_MEM].active = (value & (1 << 0)) != 0;
204
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
205
+ /* HARDFAULTPENDED is not present in v7M */
206
+ s->vectors[ARMV7M_EXCP_HARD].pending = (value & (1 << 21)) != 0;
207
+ }
208
+ s->vectors[ARMV7M_EXCP_USAGE].active = (value & (1 << 3)) != 0;
209
+ s->vectors[ARMV7M_EXCP_SVC].active = (value & (1 << 7)) != 0;
210
+ s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;
211
+ s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;
212
+ s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;
213
+ s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
214
+ s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
215
+ s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
216
+ s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
217
+ }
218
+ if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
219
+ s->vectors[ARMV7M_EXCP_BUS].active = (value & (1 << 1)) != 0;
220
+ s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;
221
+ s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
222
+ }
223
+ /* NMIACT can only be written if the write is of a zero, with
224
+ * BFHFNMINS 1, and by the CPU in secure state via the NS alias.
225
+ */
226
+ if (!attrs.secure && cpu->env.v7m.secure &&
227
+ (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
228
+ (value & (1 << 5)) == 0) {
229
+ s->vectors[ARMV7M_EXCP_NMI].active = 0;
230
+ }
231
+ /* HARDFAULTACT can only be written if the write is of a zero
232
+ * to the non-secure HardFault state by the CPU in secure state.
233
+ * The only case where we can be targeting the non-secure HF state
234
+ * when in secure state is if this is a write via the NS alias
235
+ * and BFHFNMINS is 1.
236
+ */
237
+ if (!attrs.secure && cpu->env.v7m.secure &&
238
+ (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) &&
239
+ (value & (1 << 2)) == 0) {
240
+ s->vectors[ARMV7M_EXCP_HARD].active = 0;
241
+ }
28
+ }
242
+
29
+
243
+ /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */
30
switch (vms->msi_controller) {
244
s->vectors[ARMV7M_EXCP_DEBUG].active = (value & (1 << 8)) != 0;
31
case VIRT_MSI_CTRL_NONE:
245
- s->vectors[ARMV7M_EXCP_PENDSV].active = (value & (1 << 10)) != 0;
32
return;
246
- s->vectors[ARMV7M_EXCP_SYSTICK].active = (value & (1 << 11)) != 0;
247
- s->vectors[ARMV7M_EXCP_USAGE].pending = (value & (1 << 12)) != 0;
248
- s->vectors[ARMV7M_EXCP_MEM].pending = (value & (1 << 13)) != 0;
249
- s->vectors[ARMV7M_EXCP_BUS].pending = (value & (1 << 14)) != 0;
250
- s->vectors[ARMV7M_EXCP_SVC].pending = (value & (1 << 15)) != 0;
251
- s->vectors[ARMV7M_EXCP_MEM].enabled = (value & (1 << 16)) != 0;
252
- s->vectors[ARMV7M_EXCP_BUS].enabled = (value & (1 << 17)) != 0;
253
- s->vectors[ARMV7M_EXCP_USAGE].enabled = (value & (1 << 18)) != 0;
254
nvic_irq_update(s);
255
break;
256
case 0xd28: /* Configurable Fault Status. */
257
--
33
--
258
2.7.4
34
2.25.1
259
35
260
36
diff view generated by jsdifflib
1
Make the armv7m_nvic_set_pending() and armv7m_nvic_clear_pending()
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
functions take a bool indicating whether to pend the secure
3
or non-secure version of a banked interrupt, and update the
4
callsites accordingly.
5
2
6
In most callsites we can simply pass the correct security
3
To propagate errors to the caller of the pre_plug callback, use the
7
state in; in a couple of cases we use TODO comments to indicate
4
object_poperty_set*() functions directly instead of the qdev_prop_set*()
8
that we will return the code in a subsequent commit.
5
helpers.
9
6
7
Suggested-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-5-jean-philippe@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1505240046-11454-10-git-send-email-peter.maydell@linaro.org
13
---
13
---
14
target/arm/cpu.h | 14 ++++++++++-
14
hw/arm/virt.c | 5 +++--
15
hw/intc/armv7m_nvic.c | 64 ++++++++++++++++++++++++++++++++++++++-------------
15
1 file changed, 3 insertions(+), 2 deletions(-)
16
target/arm/helper.c | 24 +++++++++++--------
17
hw/intc/trace-events | 4 ++--
18
4 files changed, 77 insertions(+), 29 deletions(-)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
19
--- a/hw/arm/virt.c
23
+++ b/target/arm/cpu.h
20
+++ b/hw/arm/virt.c
24
@@ -XXX,XX +XXX,XX @@ static inline bool armv7m_nvic_can_take_pending_exception(void *opaque)
21
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
25
return true;
22
db_start, db_end,
26
}
23
VIRTIO_IOMMU_RESV_MEM_T_MSI);
27
#endif
24
28
-void armv7m_nvic_set_pending(void *opaque, int irq);
25
- qdev_prop_set_uint32(dev, "len-reserved-regions", 1);
29
+/**
26
- qdev_prop_set_string(dev, "reserved-regions[0]", resv_prop_str);
30
+ * armv7m_nvic_set_pending: mark the specified exception as pending
27
+ object_property_set_uint(OBJECT(dev), "len-reserved-regions", 1, errp);
31
+ * @opaque: the NVIC
28
+ object_property_set_str(OBJECT(dev), "reserved-regions[0]",
32
+ * @irq: the exception number to mark pending
29
+ resv_prop_str, errp);
33
+ * @secure: false for non-banked exceptions or for the nonsecure
30
g_free(resv_prop_str);
34
+ * version of a banked exception, true for the secure version of a banked
35
+ * exception.
36
+ *
37
+ * Marks the specified exception as pending. Note that we will assert()
38
+ * if @secure is true and @irq does not specify one of the fixed set
39
+ * of architecturally banked exceptions.
40
+ */
41
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
42
void armv7m_nvic_acknowledge_irq(void *opaque);
43
/**
44
* armv7m_nvic_complete_irq: complete specified interrupt or exception
45
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/intc/armv7m_nvic.c
48
+++ b/hw/intc/armv7m_nvic.c
49
@@ -XXX,XX +XXX,XX @@ static void nvic_irq_update(NVICState *s)
50
qemu_set_irq(s->excpout, lvl);
51
}
52
53
-static void armv7m_nvic_clear_pending(void *opaque, int irq)
54
+/**
55
+ * armv7m_nvic_clear_pending: mark the specified exception as not pending
56
+ * @opaque: the NVIC
57
+ * @irq: the exception number to mark as not pending
58
+ * @secure: false for non-banked exceptions or for the nonsecure
59
+ * version of a banked exception, true for the secure version of a banked
60
+ * exception.
61
+ *
62
+ * Marks the specified exception as not pending. Note that we will assert()
63
+ * if @secure is true and @irq does not specify one of the fixed set
64
+ * of architecturally banked exceptions.
65
+ */
66
+static void armv7m_nvic_clear_pending(void *opaque, int irq, bool secure)
67
{
68
NVICState *s = (NVICState *)opaque;
69
VecInfo *vec;
70
71
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
72
73
- vec = &s->vectors[irq];
74
- trace_nvic_clear_pending(irq, vec->enabled, vec->prio);
75
+ if (secure) {
76
+ assert(exc_is_banked(irq));
77
+ vec = &s->sec_vectors[irq];
78
+ } else {
79
+ vec = &s->vectors[irq];
80
+ }
81
+ trace_nvic_clear_pending(irq, secure, vec->enabled, vec->prio);
82
if (vec->pending) {
83
vec->pending = 0;
84
nvic_irq_update(s);
85
}
31
}
86
}
32
}
87
88
-void armv7m_nvic_set_pending(void *opaque, int irq)
89
+void armv7m_nvic_set_pending(void *opaque, int irq, bool secure)
90
{
91
NVICState *s = (NVICState *)opaque;
92
+ bool banked = exc_is_banked(irq);
93
VecInfo *vec;
94
95
assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
96
+ assert(!secure || banked);
97
98
- vec = &s->vectors[irq];
99
- trace_nvic_set_pending(irq, vec->enabled, vec->prio);
100
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
101
102
+ trace_nvic_set_pending(irq, secure, vec->enabled, vec->prio);
103
104
if (irq >= ARMV7M_EXCP_HARD && irq < ARMV7M_EXCP_PENDSV) {
105
/* If a synchronous exception is pending then it may be
106
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq)
107
"(current priority %d)\n", irq, running);
108
}
109
110
- /* We can do the escalation, so we take HardFault instead */
111
+ /* We can do the escalation, so we take HardFault instead.
112
+ * If BFHFNMINS is set then we escalate to the banked HF for
113
+ * the target security state of the original exception; otherwise
114
+ * we take a Secure HardFault.
115
+ */
116
irq = ARMV7M_EXCP_HARD;
117
- vec = &s->vectors[irq];
118
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
119
+ (secure ||
120
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
121
+ vec = &s->sec_vectors[irq];
122
+ } else {
123
+ vec = &s->vectors[irq];
124
+ }
125
+ /* HF may be banked but there is only one shared HFSR */
126
s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
127
}
128
}
129
@@ -XXX,XX +XXX,XX @@ static void set_irq_level(void *opaque, int n, int level)
130
if (level != vec->level) {
131
vec->level = level;
132
if (level) {
133
- armv7m_nvic_set_pending(s, n);
134
+ armv7m_nvic_set_pending(s, n, false);
135
}
136
}
137
}
138
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
139
}
140
case 0xd04: /* Interrupt Control State. */
141
if (value & (1 << 31)) {
142
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI);
143
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
144
}
145
if (value & (1 << 28)) {
146
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV);
147
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
148
} else if (value & (1 << 27)) {
149
- armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV);
150
+ armv7m_nvic_clear_pending(s, ARMV7M_EXCP_PENDSV, attrs.secure);
151
}
152
if (value & (1 << 26)) {
153
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
154
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
155
} else if (value & (1 << 25)) {
156
- armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK);
157
+ armv7m_nvic_clear_pending(s, ARMV7M_EXCP_SYSTICK, attrs.secure);
158
}
159
break;
160
case 0xd08: /* Vector Table Offset. */
161
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
162
{
163
int excnum = (value & 0x1ff) + NVIC_FIRST_IRQ;
164
if (excnum < s->num_irq) {
165
- armv7m_nvic_set_pending(s, excnum);
166
+ armv7m_nvic_set_pending(s, excnum, false);
167
}
168
break;
169
}
170
@@ -XXX,XX +XXX,XX @@ static void nvic_systick_trigger(void *opaque, int n, int level)
171
/* SysTick just asked us to pend its exception.
172
* (This is different from an external interrupt line's
173
* behaviour.)
174
+ * TODO: when we implement the banked systicks we must make
175
+ * this pend the correct banked exception.
176
*/
177
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK);
178
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, false);
179
}
180
}
181
182
diff --git a/target/arm/helper.c b/target/arm/helper.c
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/helper.c
185
+++ b/target/arm/helper.c
186
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
187
* stack, directly take a usage fault on the current stack.
188
*/
189
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
190
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
191
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
192
v7m_exception_taken(cpu, excret);
193
qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing "
194
"stackframe: failed exception return integrity check\n");
195
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
196
* exception return excret specified then this is a UsageFault.
197
*/
198
if (return_to_handler != arm_v7m_is_handler_mode(env)) {
199
- /* Take an INVPC UsageFault by pushing the stack again. */
200
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
201
+ /* Take an INVPC UsageFault by pushing the stack again.
202
+ * TODO: the v8M version of this code should target the
203
+ * background state for this exception.
204
+ */
205
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false);
206
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK;
207
v7m_push_stack(cpu);
208
v7m_exception_taken(cpu, excret);
209
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
210
handle it. */
211
switch (cs->exception_index) {
212
case EXCP_UDEF:
213
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
214
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
215
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
216
break;
217
case EXCP_NOCP:
218
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
219
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
220
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
221
break;
222
case EXCP_INVSTATE:
223
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
224
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
225
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
226
break;
227
case EXCP_SWI:
228
/* The PC already points to the next instruction. */
229
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
230
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
231
break;
232
case EXCP_PREFETCH_ABORT:
233
case EXCP_DATA_ABORT:
234
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
235
env->v7m.bfar);
236
break;
237
}
238
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS);
239
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
240
break;
241
default:
242
/* All other FSR values are either MPU faults or "can't happen
243
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
244
env->v7m.mmfar[env->v7m.secure]);
245
break;
246
}
247
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
248
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM,
249
+ env->v7m.secure);
250
break;
251
}
252
break;
253
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
254
return;
255
}
256
}
257
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
258
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG, false);
259
break;
260
case EXCP_IRQ:
261
break;
262
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
263
index XXXXXXX..XXXXXXX 100644
264
--- a/hw/intc/trace-events
265
+++ b/hw/intc/trace-events
266
@@ -XXX,XX +XXX,XX @@ nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d"
267
nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d"
268
nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d"
269
nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"
270
-nvic_set_pending(int irq, int en, int prio) "NVIC set pending irq %d (enabled: %d priority %d)"
271
-nvic_clear_pending(int irq, int en, int prio) "NVIC clear pending irq %d (enabled: %d priority %d)"
272
+nvic_set_pending(int irq, bool secure, int en, int prio) "NVIC set pending irq %d secure-bank %d (enabled: %d priority %d)"
273
+nvic_clear_pending(int irq, bool secure, int en, int prio) "NVIC clear pending irq %d secure-bank %d (enabled: %d priority %d)"
274
nvic_set_pending_level(int irq) "NVIC set pending: irq %d higher prio than vectpending: setting irq line to 1"
275
nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (prio %d)"
276
nvic_complete_irq(int irq) "NVIC complete IRQ %d"
277
--
33
--
278
2.7.4
34
2.25.1
279
35
280
36
diff view generated by jsdifflib
1
From: Subbaraya Sundeep <sundeep.lkml@gmail.com>
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Added Sytem register block of Smartfusion2.
3
Create empty data files and allow updates for the upcoming VIOT tests.
4
This block has PLL registers which are accessed by guest.
5
4
6
Signed-off-by: Subbaraya Sundeep <sundeep.lkml@gmail.com>
5
Acked-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Acked-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
9
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20211210170415.583179-6-jean-philippe@linaro.org
10
Message-id: 20170920201737.25723-3-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/misc/Makefile.objs | 1 +
11
tests/qtest/bios-tables-test-allowed-diff.h | 3 +++
14
include/hw/misc/msf2-sysreg.h | 77 ++++++++++++++++++++
12
tests/data/acpi/q35/DSDT.viot | 0
15
hw/misc/msf2-sysreg.c | 160 ++++++++++++++++++++++++++++++++++++++++++
13
tests/data/acpi/q35/VIOT.viot | 0
16
hw/misc/trace-events | 5 ++
14
tests/data/acpi/virt/VIOT | 0
17
4 files changed, 243 insertions(+)
15
4 files changed, 3 insertions(+)
18
create mode 100644 include/hw/misc/msf2-sysreg.h
16
create mode 100644 tests/data/acpi/q35/DSDT.viot
19
create mode 100644 hw/misc/msf2-sysreg.c
17
create mode 100644 tests/data/acpi/q35/VIOT.viot
18
create mode 100644 tests/data/acpi/virt/VIOT
20
19
21
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/misc/Makefile.objs
22
--- a/tests/qtest/bios-tables-test-allowed-diff.h
24
+++ b/hw/misc/Makefile.objs
23
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
25
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
24
@@ -1 +1,4 @@
26
obj-$(CONFIG_AUX) += auxbus.o
25
/* List of comma-separated changed AML files to ignore */
27
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
26
+"tests/data/acpi/virt/VIOT",
28
obj-y += mmio_interface.o
27
+"tests/data/acpi/q35/DSDT.viot",
29
+obj-$(CONFIG_MSF2) += msf2-sysreg.o
28
+"tests/data/acpi/q35/VIOT.viot",
30
diff --git a/include/hw/misc/msf2-sysreg.h b/include/hw/misc/msf2-sysreg.h
29
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
31
new file mode 100644
30
new file mode 100644
32
index XXXXXXX..XXXXXXX
31
index XXXXXXX..XXXXXXX
33
--- /dev/null
32
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
34
+++ b/include/hw/misc/msf2-sysreg.h
35
@@ -XXX,XX +XXX,XX @@
36
+/*
37
+ * Microsemi SmartFusion2 SYSREG
38
+ *
39
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
40
+ *
41
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
42
+ * of this software and associated documentation files (the "Software"), to deal
43
+ * in the Software without restriction, including without limitation the rights
44
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
45
+ * copies of the Software, and to permit persons to whom the Software is
46
+ * furnished to do so, subject to the following conditions:
47
+ *
48
+ * The above copyright notice and this permission notice shall be included in
49
+ * all copies or substantial portions of the Software.
50
+ *
51
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
54
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
56
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
57
+ * THE SOFTWARE.
58
+ */
59
+
60
+#ifndef HW_MSF2_SYSREG_H
61
+#define HW_MSF2_SYSREG_H
62
+
63
+#include "hw/sysbus.h"
64
+
65
+enum {
66
+ ESRAM_CR = 0x00 / 4,
67
+ ESRAM_MAX_LAT,
68
+ DDR_CR,
69
+ ENVM_CR,
70
+ ENVM_REMAP_BASE_CR,
71
+ ENVM_REMAP_FAB_CR,
72
+ CC_CR,
73
+ CC_REGION_CR,
74
+ CC_LOCK_BASE_ADDR_CR,
75
+ CC_FLUSH_INDX_CR,
76
+ DDRB_BUF_TIMER_CR,
77
+ DDRB_NB_ADDR_CR,
78
+ DDRB_NB_SIZE_CR,
79
+ DDRB_CR,
80
+
81
+ SOFT_RESET_CR = 0x48 / 4,
82
+ M3_CR,
83
+
84
+ GPIO_SYSRESET_SEL_CR = 0x58 / 4,
85
+
86
+ MDDR_CR = 0x60 / 4,
87
+
88
+ MSSDDR_PLL_STATUS_LOW_CR = 0x90 / 4,
89
+ MSSDDR_PLL_STATUS_HIGH_CR,
90
+ MSSDDR_FACC1_CR,
91
+ MSSDDR_FACC2_CR,
92
+
93
+ MSSDDR_PLL_STATUS = 0x150 / 4,
94
+};
95
+
96
+#define MSF2_SYSREG_MMIO_SIZE 0x300
97
+
98
+#define TYPE_MSF2_SYSREG "msf2-sysreg"
99
+#define MSF2_SYSREG(obj) OBJECT_CHECK(MSF2SysregState, (obj), TYPE_MSF2_SYSREG)
100
+
101
+typedef struct MSF2SysregState {
102
+ SysBusDevice parent_obj;
103
+
104
+ MemoryRegion iomem;
105
+
106
+ uint8_t apb0div;
107
+ uint8_t apb1div;
108
+
109
+ uint32_t regs[MSF2_SYSREG_MMIO_SIZE / 4];
110
+} MSF2SysregState;
111
+
112
+#endif /* HW_MSF2_SYSREG_H */
113
diff --git a/hw/misc/msf2-sysreg.c b/hw/misc/msf2-sysreg.c
114
new file mode 100644
33
new file mode 100644
115
index XXXXXXX..XXXXXXX
34
index XXXXXXX..XXXXXXX
116
--- /dev/null
35
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
117
+++ b/hw/misc/msf2-sysreg.c
36
new file mode 100644
118
@@ -XXX,XX +XXX,XX @@
37
index XXXXXXX..XXXXXXX
119
+/*
120
+ * System Register block model of Microsemi SmartFusion2.
121
+ *
122
+ * Copyright (c) 2017 Subbaraya Sundeep <sundeep.lkml@gmail.com>
123
+ *
124
+ * This program is free software; you can redistribute it and/or
125
+ * modify it under the terms of the GNU General Public License
126
+ * as published by the Free Software Foundation; either version
127
+ * 2 of the License, or (at your option) any later version.
128
+ *
129
+ * You should have received a copy of the GNU General Public License along
130
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
131
+ */
132
+
133
+#include "qemu/osdep.h"
134
+#include "qapi/error.h"
135
+#include "qemu/log.h"
136
+#include "hw/misc/msf2-sysreg.h"
137
+#include "qemu/error-report.h"
138
+#include "trace.h"
139
+
140
+static inline int msf2_divbits(uint32_t div)
141
+{
142
+ int r = ctz32(div);
143
+
144
+ return (div < 8) ? r : r + 1;
145
+}
146
+
147
+static void msf2_sysreg_reset(DeviceState *d)
148
+{
149
+ MSF2SysregState *s = MSF2_SYSREG(d);
150
+
151
+ s->regs[MSSDDR_PLL_STATUS_LOW_CR] = 0x021A2358;
152
+ s->regs[MSSDDR_PLL_STATUS] = 0x3;
153
+ s->regs[MSSDDR_FACC1_CR] = msf2_divbits(s->apb0div) << 5 |
154
+ msf2_divbits(s->apb1div) << 2;
155
+}
156
+
157
+static uint64_t msf2_sysreg_read(void *opaque, hwaddr offset,
158
+ unsigned size)
159
+{
160
+ MSF2SysregState *s = opaque;
161
+ uint32_t ret = 0;
162
+
163
+ offset >>= 2;
164
+ if (offset < ARRAY_SIZE(s->regs)) {
165
+ ret = s->regs[offset];
166
+ trace_msf2_sysreg_read(offset << 2, ret);
167
+ } else {
168
+ qemu_log_mask(LOG_GUEST_ERROR,
169
+ "%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
170
+ offset << 2);
171
+ }
172
+
173
+ return ret;
174
+}
175
+
176
+static void msf2_sysreg_write(void *opaque, hwaddr offset,
177
+ uint64_t val, unsigned size)
178
+{
179
+ MSF2SysregState *s = opaque;
180
+ uint32_t newval = val;
181
+
182
+ offset >>= 2;
183
+
184
+ switch (offset) {
185
+ case MSSDDR_PLL_STATUS:
186
+ trace_msf2_sysreg_write_pll_status();
187
+ break;
188
+
189
+ case ESRAM_CR:
190
+ case DDR_CR:
191
+ case ENVM_REMAP_BASE_CR:
192
+ if (newval != s->regs[offset]) {
193
+ qemu_log_mask(LOG_UNIMP,
194
+ TYPE_MSF2_SYSREG": remapping not supported\n");
195
+ }
196
+ break;
197
+
198
+ default:
199
+ if (offset < ARRAY_SIZE(s->regs)) {
200
+ trace_msf2_sysreg_write(offset << 2, newval, s->regs[offset]);
201
+ s->regs[offset] = newval;
202
+ } else {
203
+ qemu_log_mask(LOG_GUEST_ERROR,
204
+ "%s: Bad offset 0x%08" HWADDR_PRIx "\n", __func__,
205
+ offset << 2);
206
+ }
207
+ break;
208
+ }
209
+}
210
+
211
+static const MemoryRegionOps sysreg_ops = {
212
+ .read = msf2_sysreg_read,
213
+ .write = msf2_sysreg_write,
214
+ .endianness = DEVICE_NATIVE_ENDIAN,
215
+};
216
+
217
+static void msf2_sysreg_init(Object *obj)
218
+{
219
+ MSF2SysregState *s = MSF2_SYSREG(obj);
220
+
221
+ memory_region_init_io(&s->iomem, obj, &sysreg_ops, s, TYPE_MSF2_SYSREG,
222
+ MSF2_SYSREG_MMIO_SIZE);
223
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
224
+}
225
+
226
+static const VMStateDescription vmstate_msf2_sysreg = {
227
+ .name = TYPE_MSF2_SYSREG,
228
+ .version_id = 1,
229
+ .minimum_version_id = 1,
230
+ .fields = (VMStateField[]) {
231
+ VMSTATE_UINT32_ARRAY(regs, MSF2SysregState, MSF2_SYSREG_MMIO_SIZE / 4),
232
+ VMSTATE_END_OF_LIST()
233
+ }
234
+};
235
+
236
+static Property msf2_sysreg_properties[] = {
237
+ /* default divisors in Libero GUI */
238
+ DEFINE_PROP_UINT8("apb0divisor", MSF2SysregState, apb0div, 2),
239
+ DEFINE_PROP_UINT8("apb1divisor", MSF2SysregState, apb1div, 2),
240
+ DEFINE_PROP_END_OF_LIST(),
241
+};
242
+
243
+static void msf2_sysreg_realize(DeviceState *dev, Error **errp)
244
+{
245
+ MSF2SysregState *s = MSF2_SYSREG(dev);
246
+
247
+ if ((s->apb0div > 32 || !is_power_of_2(s->apb0div))
248
+ || (s->apb1div > 32 || !is_power_of_2(s->apb1div))) {
249
+ error_setg(errp, "Invalid apb divisor value");
250
+ error_append_hint(errp, "apb divisor must be a power of 2"
251
+ " and maximum value is 32\n");
252
+ }
253
+}
254
+
255
+static void msf2_sysreg_class_init(ObjectClass *klass, void *data)
256
+{
257
+ DeviceClass *dc = DEVICE_CLASS(klass);
258
+
259
+ dc->vmsd = &vmstate_msf2_sysreg;
260
+ dc->reset = msf2_sysreg_reset;
261
+ dc->props = msf2_sysreg_properties;
262
+ dc->realize = msf2_sysreg_realize;
263
+}
264
+
265
+static const TypeInfo msf2_sysreg_info = {
266
+ .name = TYPE_MSF2_SYSREG,
267
+ .parent = TYPE_SYS_BUS_DEVICE,
268
+ .class_init = msf2_sysreg_class_init,
269
+ .instance_size = sizeof(MSF2SysregState),
270
+ .instance_init = msf2_sysreg_init,
271
+};
272
+
273
+static void msf2_sysreg_register_types(void)
274
+{
275
+ type_register_static(&msf2_sysreg_info);
276
+}
277
+
278
+type_init(msf2_sysreg_register_types)
279
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
280
index XXXXXXX..XXXXXXX 100644
281
--- a/hw/misc/trace-events
282
+++ b/hw/misc/trace-events
283
@@ -XXX,XX +XXX,XX @@ mps2_scc_reset(void) "MPS2 SCC: reset"
284
mps2_scc_leds(char led7, char led6, char led5, char led4, char led3, char led2, char led1, char led0) "MPS2 SCC LEDs: %c%c%c%c%c%c%c%c"
285
mps2_scc_cfg_write(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config write: function %d device %d data 0x%" PRIx32
286
mps2_scc_cfg_read(unsigned function, unsigned device, uint32_t value) "MPS2 SCC config read: function %d device %d data 0x%" PRIx32
287
+
288
+# hw/misc/msf2-sysreg.c
289
+msf2_sysreg_write(uint64_t offset, uint32_t val, uint32_t prev) "msf2-sysreg write: addr 0x%08" HWADDR_PRIx " data 0x%" PRIx32 " prev 0x%" PRIx32
290
+msf2_sysreg_read(uint64_t offset, uint32_t val) "msf2-sysreg read: addr 0x%08" HWADDR_PRIx " data 0x%08" PRIx32
291
+msf2_sysreg_write_pll_status(void) "Invalid write to read only PLL status register"
292
--
38
--
293
2.7.4
39
2.25.1
294
40
295
41
diff view generated by jsdifflib
1
Don't use the old_mmio struct in memory region ops.
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
2
3
Add two test cases for VIOT, one on the q35 machine and the other on
4
virt. To test complex topologies the q35 test has two PCIe buses that
5
bypass the IOMMU (and are therefore not described by VIOT), and two
6
buses that are translated by virtio-iommu.
7
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
11
Message-id: 20211210170415.583179-7-jean-philippe@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 1505580378-9044-5-git-send-email-peter.maydell@linaro.org
6
---
13
---
7
hw/timer/omap_gptimer.c | 49 +++++++++++++++++++++++++++++++++++++------------
14
tests/qtest/bios-tables-test.c | 38 ++++++++++++++++++++++++++++++++++
8
1 file changed, 37 insertions(+), 12 deletions(-)
15
1 file changed, 38 insertions(+)
9
16
10
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
17
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
11
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/timer/omap_gptimer.c
19
--- a/tests/qtest/bios-tables-test.c
13
+++ b/hw/timer/omap_gptimer.c
20
+++ b/tests/qtest/bios-tables-test.c
14
@@ -XXX,XX +XXX,XX @@ static void omap_gp_timer_writeh(void *opaque, hwaddr addr,
21
@@ -XXX,XX +XXX,XX @@ static void test_acpi_virt_tcg(void)
15
s->writeh = (uint16_t) value;
22
free_test_data(&data);
16
}
23
}
17
24
18
+static uint64_t omap_gp_timer_readfn(void *opaque, hwaddr addr,
25
+static void test_acpi_q35_viot(void)
19
+ unsigned size)
20
+{
26
+{
21
+ switch (size) {
27
+ test_data data = {
22
+ case 1:
28
+ .machine = MACHINE_Q35,
23
+ return omap_badwidth_read32(opaque, addr);
29
+ .variant = ".viot",
24
+ case 2:
30
+ };
25
+ return omap_gp_timer_readh(opaque, addr);
31
+
26
+ case 4:
32
+ /*
27
+ return omap_gp_timer_readw(opaque, addr);
33
+ * To keep things interesting, two buses bypass the IOMMU.
28
+ default:
34
+ * VIOT should only describes the other two buses.
29
+ g_assert_not_reached();
35
+ */
30
+ }
36
+ test_acpi_one("-machine default_bus_bypass_iommu=on "
37
+ "-device virtio-iommu-pci "
38
+ "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 "
39
+ "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
40
+ "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
41
+ &data);
42
+ free_test_data(&data);
31
+}
43
+}
32
+
44
+
33
+static void omap_gp_timer_writefn(void *opaque, hwaddr addr,
45
+static void test_acpi_virt_viot(void)
34
+ uint64_t value, unsigned size)
35
+{
46
+{
36
+ switch (size) {
47
+ test_data data = {
37
+ case 1:
48
+ .machine = "virt",
38
+ omap_badwidth_write32(opaque, addr, value);
49
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
39
+ break;
50
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
40
+ case 2:
51
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
41
+ omap_gp_timer_writeh(opaque, addr, value);
52
+ .ram_start = 0x40000000ULL,
42
+ break;
53
+ .scan_len = 128ULL * 1024 * 1024,
43
+ case 4:
54
+ };
44
+ omap_gp_timer_write(opaque, addr, value);
55
+
45
+ break;
56
+ test_acpi_one("-cpu cortex-a57 "
46
+ default:
57
+ "-device virtio-iommu-pci", &data);
47
+ g_assert_not_reached();
58
+ free_test_data(&data);
48
+ }
49
+}
59
+}
50
+
60
+
51
static const MemoryRegionOps omap_gp_timer_ops = {
61
static void test_oem_fields(test_data *data)
52
- .old_mmio = {
62
{
53
- .read = {
63
int i;
54
- omap_badwidth_read32,
64
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
55
- omap_gp_timer_readh,
65
qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic);
56
- omap_gp_timer_readw,
66
qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar);
57
- },
67
}
58
- .write = {
68
+ qtest_add_func("acpi/q35/viot", test_acpi_q35_viot);
59
- omap_badwidth_write32,
69
} else if (strcmp(arch, "aarch64") == 0) {
60
- omap_gp_timer_writeh,
70
if (has_tcg) {
61
- omap_gp_timer_write,
71
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
62
- },
72
@@ -XXX,XX +XXX,XX @@ int main(int argc, char *argv[])
63
- },
73
qtest_add_func("acpi/virt/memhp", test_acpi_virt_tcg_memhp);
64
+ .read = omap_gp_timer_readfn,
74
qtest_add_func("acpi/virt/pxb", test_acpi_virt_tcg_pxb);
65
+ .write = omap_gp_timer_writefn,
75
qtest_add_func("acpi/virt/oem-fields", test_acpi_oem_fields_virt);
66
+ .valid.min_access_size = 1,
76
+ qtest_add_func("acpi/virt/viot", test_acpi_virt_viot);
67
+ .valid.max_access_size = 4,
77
}
68
.endianness = DEVICE_NATIVE_ENDIAN,
78
}
69
};
79
ret = g_test_run();
70
71
--
80
--
72
2.7.4
81
2.25.1
73
82
74
83
diff view generated by jsdifflib
1
Update nvic_exec_prio() to support the v8M changes:
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
* BASEPRI, FAULTMASK and PRIMASK are all banked
2
3
* AIRCR.PRIS can affect NS priorities
3
Add expected blobs of the VIOT and DSDT table for the VIOT test on the
4
* AIRCR.BFHFNMINS affects FAULTMASK behaviour
4
q35 machine.
5
5
6
These changes mean that it's no longer possible to
6
Since the test instantiates a virtio device and two PCIe expander
7
definitely say that if FAULTMASK is set it overrides
7
bridges, DSDT.viot has more blocks than the base DSDT.
8
PRIMASK, and if PRIMASK is set it overrides BASEPRI
8
9
(since if PRIMASK_NS is set and AIRCR.PRIS is set then
9
The VIOT table generated for the q35 test is:
10
whether that 0x80 priority should take effect or the
10
11
priority in BASEPRI_S depends on the value of BASEPRI_S,
11
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
12
for instance). So we switch to the same approach used
12
[004h 0004 4] Table Length : 00000070
13
by the pseudocode of working through BASEPRI, PRIMASK
13
[008h 0008 1] Revision : 00
14
and FAULTMASK and overriding the previous values if
14
[009h 0009 1] Checksum : 3D
15
needed.
15
[00Ah 0010 6] Oem ID : "BOCHS "
16
16
[010h 0016 8] Oem Table ID : "BXPC "
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
[018h 0024 4] Oem Revision : 00000001
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
[01Ch 0028 4] Asl Compiler ID : "BXPC"
19
Message-id: 1505240046-11454-16-git-send-email-peter.maydell@linaro.org
19
[020h 0032 4] Asl Compiler Revision : 00000001
20
---
20
21
hw/intc/armv7m_nvic.c | 51 ++++++++++++++++++++++++++++++++++++++++++---------
21
[024h 0036 2] Node count : 0003
22
1 file changed, 42 insertions(+), 9 deletions(-)
22
[026h 0038 2] Node offset : 0030
23
23
[028h 0040 8] Reserved : 0000000000000000
24
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
24
25
index XXXXXXX..XXXXXXX 100644
25
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
26
--- a/hw/intc/armv7m_nvic.c
26
[031h 0049 1] Reserved : 00
27
+++ b/hw/intc/armv7m_nvic.c
27
[032h 0050 2] Length : 0010
28
@@ -XXX,XX +XXX,XX @@ static void nvic_recompute_state(NVICState *s)
28
29
static inline int nvic_exec_prio(NVICState *s)
29
[034h 0052 2] PCI Segment : 0000
30
{
30
[036h 0054 2] PCI BDF number : 0010
31
CPUARMState *env = &s->cpu->env;
31
[038h 0056 8] Reserved : 0000000000000000
32
- int running;
32
33
+ int running = NVIC_NOEXC_PRIO;
33
[040h 0064 1] Type : 01 [PCI Range]
34
34
[041h 0065 1] Reserved : 00
35
- if (env->v7m.faultmask[env->v7m.secure]) {
35
[042h 0066 2] Length : 0018
36
- running = -1;
36
37
- } else if (env->v7m.primask[env->v7m.secure]) {
37
[044h 0068 4] Endpoint start : 00003000
38
+ if (env->v7m.basepri[M_REG_NS] > 0) {
38
[048h 0072 2] PCI Segment start : 0000
39
+ running = exc_group_prio(s, env->v7m.basepri[M_REG_NS], M_REG_NS);
39
[04Ah 0074 2] PCI Segment end : 0000
40
+ }
40
[04Ch 0076 2] PCI BDF start : 3000
41
+
41
[04Eh 0078 2] PCI BDF end : 30FF
42
+ if (env->v7m.basepri[M_REG_S] > 0) {
42
[050h 0080 2] Output node : 0030
43
+ int basepri = exc_group_prio(s, env->v7m.basepri[M_REG_S], M_REG_S);
43
[052h 0082 6] Reserved : 000000000000
44
+ if (running > basepri) {
44
45
+ running = basepri;
45
[058h 0088 1] Type : 01 [PCI Range]
46
[059h 0089 1] Reserved : 00
47
[05Ah 0090 2] Length : 0018
48
49
[05Ch 0092 4] Endpoint start : 00001000
50
[060h 0096 2] PCI Segment start : 0000
51
[062h 0098 2] PCI Segment end : 0000
52
[064h 0100 2] PCI BDF start : 1000
53
[066h 0102 2] PCI BDF end : 10FF
54
[068h 0104 2] Output node : 0030
55
[06Ah 0106 6] Reserved : 000000000000
56
57
And the DSDT diff is:
58
59
@@ -XXX,XX +XXX,XX @@
60
*
61
* Disassembling to symbolic ASL+ operators
62
*
63
- * Disassembly of tests/data/acpi/q35/DSDT, Fri Dec 10 15:03:08 2021
64
+ * Disassembly of /tmp/aml-H9Y5D1, Fri Dec 10 15:02:27 2021
65
*
66
* Original Table Header:
67
* Signature "DSDT"
68
- * Length 0x00002061 (8289)
69
+ * Length 0x000024B6 (9398)
70
* Revision 0x01 **** 32-bit table (V1), no 64-bit math support
71
- * Checksum 0xFA
72
+ * Checksum 0xA7
73
* OEM ID "BOCHS "
74
* OEM Table ID "BXPC "
75
* OEM Revision 0x00000001 (1)
76
@@ -XXX,XX +XXX,XX @@
77
}
78
}
79
80
+ Scope (\_SB)
81
+ {
82
+ Device (PC30)
83
+ {
84
+ Name (_UID, 0x30) // _UID: Unique ID
85
+ Name (_BBN, 0x30) // _BBN: BIOS Bus Number
86
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
87
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
88
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
89
+ {
90
+ CreateDWordField (Arg3, Zero, CDW1)
91
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
92
+ {
93
+ CreateDWordField (Arg3, 0x04, CDW2)
94
+ CreateDWordField (Arg3, 0x08, CDW3)
95
+ Local0 = CDW3 /* \_SB_.PC30._OSC.CDW3 */
96
+ Local0 &= 0x1F
97
+ If ((Arg1 != One))
98
+ {
99
+ CDW1 |= 0x08
100
+ }
101
+
102
+ If ((CDW3 != Local0))
103
+ {
104
+ CDW1 |= 0x10
105
+ }
106
+
107
+ CDW3 = Local0
108
+ }
109
+ Else
110
+ {
111
+ CDW1 |= 0x04
112
+ }
113
+
114
+ Return (Arg3)
115
+ }
116
+
117
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
118
+ {
119
+ Local0 = Package (0x80){}
120
+ Local1 = Zero
121
+ While ((Local1 < 0x80))
122
+ {
123
+ Local2 = (Local1 >> 0x02)
124
+ Local3 = ((Local1 + Local2) & 0x03)
125
+ If ((Local3 == Zero))
126
+ {
127
+ Local4 = Package (0x04)
128
+ {
129
+ Zero,
130
+ Zero,
131
+ LNKD,
132
+ Zero
133
+ }
134
+ }
135
+
136
+ If ((Local3 == One))
137
+ {
138
+ Local4 = Package (0x04)
139
+ {
140
+ Zero,
141
+ Zero,
142
+ LNKA,
143
+ Zero
144
+ }
145
+ }
146
+
147
+ If ((Local3 == 0x02))
148
+ {
149
+ Local4 = Package (0x04)
150
+ {
151
+ Zero,
152
+ Zero,
153
+ LNKB,
154
+ Zero
155
+ }
156
+ }
157
+
158
+ If ((Local3 == 0x03))
159
+ {
160
+ Local4 = Package (0x04)
161
+ {
162
+ Zero,
163
+ Zero,
164
+ LNKC,
165
+ Zero
166
+ }
167
+ }
168
+
169
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
170
+ Local4 [One] = (Local1 & 0x03)
171
+ Local0 [Local1] = Local4
172
+ Local1++
173
+ }
174
+
175
+ Return (Local0)
176
+ }
177
+
178
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
179
+ {
180
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
181
+ 0x0000, // Granularity
182
+ 0x0030, // Range Minimum
183
+ 0x0030, // Range Maximum
184
+ 0x0000, // Translation Offset
185
+ 0x0001, // Length
186
+ ,, )
187
+ })
46
+ }
188
+ }
47
+ }
189
+ }
48
+
190
+
49
+ if (env->v7m.primask[M_REG_NS]) {
191
+ Scope (\_SB)
50
+ if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) {
192
+ {
51
+ if (running > NVIC_NS_PRIO_LIMIT) {
193
+ Device (PC20)
52
+ running = NVIC_NS_PRIO_LIMIT;
194
+ {
53
+ }
195
+ Name (_UID, 0x20) // _UID: Unique ID
54
+ } else {
196
+ Name (_BBN, 0x20) // _BBN: BIOS Bus Number
55
+ running = 0;
197
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
198
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
199
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
200
+ {
201
+ CreateDWordField (Arg3, Zero, CDW1)
202
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
203
+ {
204
+ CreateDWordField (Arg3, 0x04, CDW2)
205
+ CreateDWordField (Arg3, 0x08, CDW3)
206
+ Local0 = CDW3 /* \_SB_.PC20._OSC.CDW3 */
207
+ Local0 &= 0x1F
208
+ If ((Arg1 != One))
209
+ {
210
+ CDW1 |= 0x08
211
+ }
212
+
213
+ If ((CDW3 != Local0))
214
+ {
215
+ CDW1 |= 0x10
216
+ }
217
+
218
+ CDW3 = Local0
219
+ }
220
+ Else
221
+ {
222
+ CDW1 |= 0x04
223
+ }
224
+
225
+ Return (Arg3)
226
+ }
227
+
228
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
229
+ {
230
+ Local0 = Package (0x80){}
231
+ Local1 = Zero
232
+ While ((Local1 < 0x80))
233
+ {
234
+ Local2 = (Local1 >> 0x02)
235
+ Local3 = ((Local1 + Local2) & 0x03)
236
+ If ((Local3 == Zero))
237
+ {
238
+ Local4 = Package (0x04)
239
+ {
240
+ Zero,
241
+ Zero,
242
+ LNKD,
243
+ Zero
244
+ }
245
+ }
246
+
247
+ If ((Local3 == One))
248
+ {
249
+ Local4 = Package (0x04)
250
+ {
251
+ Zero,
252
+ Zero,
253
+ LNKA,
254
+ Zero
255
+ }
256
+ }
257
+
258
+ If ((Local3 == 0x02))
259
+ {
260
+ Local4 = Package (0x04)
261
+ {
262
+ Zero,
263
+ Zero,
264
+ LNKB,
265
+ Zero
266
+ }
267
+ }
268
+
269
+ If ((Local3 == 0x03))
270
+ {
271
+ Local4 = Package (0x04)
272
+ {
273
+ Zero,
274
+ Zero,
275
+ LNKC,
276
+ Zero
277
+ }
278
+ }
279
+
280
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
281
+ Local4 [One] = (Local1 & 0x03)
282
+ Local0 [Local1] = Local4
283
+ Local1++
284
+ }
285
+
286
+ Return (Local0)
287
+ }
288
+
289
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
290
+ {
291
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
292
+ 0x0000, // Granularity
293
+ 0x0020, // Range Minimum
294
+ 0x0020, // Range Maximum
295
+ 0x0000, // Translation Offset
296
+ 0x0001, // Length
297
+ ,, )
298
+ })
56
+ }
299
+ }
57
+ }
300
+ }
58
+
301
+
59
+ if (env->v7m.primask[M_REG_S]) {
302
+ Scope (\_SB)
60
running = 0;
303
+ {
61
- } else if (env->v7m.basepri[env->v7m.secure] > 0) {
304
+ Device (PC10)
62
- running = env->v7m.basepri[env->v7m.secure] &
305
+ {
63
- nvic_gprio_mask(s, env->v7m.secure);
306
+ Name (_UID, 0x10) // _UID: Unique ID
64
- } else {
307
+ Name (_BBN, 0x10) // _BBN: BIOS Bus Number
65
- running = NVIC_NOEXC_PRIO; /* lower than any possible priority */
308
+ Name (_HID, EisaId ("PNP0A08") /* PCI Express Bus */) // _HID: Hardware ID
66
}
309
+ Name (_CID, EisaId ("PNP0A03") /* PCI Bus */) // _CID: Compatible ID
67
+
310
+ Method (_OSC, 4, NotSerialized) // _OSC: Operating System Capabilities
68
+ if (env->v7m.faultmask[M_REG_NS]) {
311
+ {
69
+ if (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
312
+ CreateDWordField (Arg3, Zero, CDW1)
70
+ running = -1;
313
+ If ((Arg0 == ToUUID ("33db4d5b-1ff7-401c-9657-7441c03dd766") /* PCI Host Bridge Device */))
71
+ } else {
314
+ {
72
+ if (env->v7m.aircr & R_V7M_AIRCR_PRIS_MASK) {
315
+ CreateDWordField (Arg3, 0x04, CDW2)
73
+ if (running > NVIC_NS_PRIO_LIMIT) {
316
+ CreateDWordField (Arg3, 0x08, CDW3)
74
+ running = NVIC_NS_PRIO_LIMIT;
317
+ Local0 = CDW3 /* \_SB_.PC10._OSC.CDW3 */
75
+ }
318
+ Local0 &= 0x1F
76
+ } else {
319
+ If ((Arg1 != One))
77
+ running = 0;
320
+ {
78
+ }
321
+ CDW1 |= 0x08
322
+ }
323
+
324
+ If ((CDW3 != Local0))
325
+ {
326
+ CDW1 |= 0x10
327
+ }
328
+
329
+ CDW3 = Local0
330
+ }
331
+ Else
332
+ {
333
+ CDW1 |= 0x04
334
+ }
335
+
336
+ Return (Arg3)
337
+ }
338
+
339
+ Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
340
+ {
341
+ Local0 = Package (0x80){}
342
+ Local1 = Zero
343
+ While ((Local1 < 0x80))
344
+ {
345
+ Local2 = (Local1 >> 0x02)
346
+ Local3 = ((Local1 + Local2) & 0x03)
347
+ If ((Local3 == Zero))
348
+ {
349
+ Local4 = Package (0x04)
350
+ {
351
+ Zero,
352
+ Zero,
353
+ LNKD,
354
+ Zero
355
+ }
356
+ }
357
+
358
+ If ((Local3 == One))
359
+ {
360
+ Local4 = Package (0x04)
361
+ {
362
+ Zero,
363
+ Zero,
364
+ LNKA,
365
+ Zero
366
+ }
367
+ }
368
+
369
+ If ((Local3 == 0x02))
370
+ {
371
+ Local4 = Package (0x04)
372
+ {
373
+ Zero,
374
+ Zero,
375
+ LNKB,
376
+ Zero
377
+ }
378
+ }
379
+
380
+ If ((Local3 == 0x03))
381
+ {
382
+ Local4 = Package (0x04)
383
+ {
384
+ Zero,
385
+ Zero,
386
+ LNKC,
387
+ Zero
388
+ }
389
+ }
390
+
391
+ Local4 [Zero] = ((Local2 << 0x10) | 0xFFFF)
392
+ Local4 [One] = (Local1 & 0x03)
393
+ Local0 [Local1] = Local4
394
+ Local1++
395
+ }
396
+
397
+ Return (Local0)
398
+ }
399
+
400
+ Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
401
+ {
402
+ WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
403
+ 0x0000, // Granularity
404
+ 0x0010, // Range Minimum
405
+ 0x0010, // Range Maximum
406
+ 0x0000, // Translation Offset
407
+ 0x0001, // Length
408
+ ,, )
409
+ })
79
+ }
410
+ }
80
+ }
411
+ }
81
+
412
+
82
+ if (env->v7m.faultmask[M_REG_S]) {
413
Scope (\_SB.PCI0)
83
+ running = (env->v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) ? -3 : -1;
414
{
84
+ }
415
Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings
85
+
416
@@ -XXX,XX +XXX,XX @@
86
/* consider priority of active handler */
417
WordBusNumber (ResourceProducer, MinFixed, MaxFixed, PosDecode,
87
return MIN(running, s->exception_prio);
418
0x0000, // Granularity
88
}
419
0x0000, // Range Minimum
420
- 0x00FF, // Range Maximum
421
+ 0x000F, // Range Maximum
422
0x0000, // Translation Offset
423
- 0x0100, // Length
424
+ 0x0010, // Length
425
,, )
426
IO (Decode16,
427
0x0CF8, // Range Minimum
428
@@ -XXX,XX +XXX,XX @@
429
}
430
}
431
432
+ Device (S10)
433
+ {
434
+ Name (_ADR, 0x00020000) // _ADR: Address
435
+ }
436
+
437
+ Device (S18)
438
+ {
439
+ Name (_ADR, 0x00030000) // _ADR: Address
440
+ }
441
+
442
+ Device (S20)
443
+ {
444
+ Name (_ADR, 0x00040000) // _ADR: Address
445
+ }
446
+
447
+ Device (S28)
448
+ {
449
+ Name (_ADR, 0x00050000) // _ADR: Address
450
+ }
451
+
452
Method (PCNT, 0, NotSerialized)
453
{
454
}
455
456
Reviewed-by: Eric Auger <eric.auger@redhat.com>
457
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
458
Message-id: 20211210170415.583179-8-jean-philippe@linaro.org
459
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
460
---
461
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
462
tests/data/acpi/q35/DSDT.viot | Bin 0 -> 9398 bytes
463
tests/data/acpi/q35/VIOT.viot | Bin 0 -> 112 bytes
464
3 files changed, 2 deletions(-)
465
466
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
467
index XXXXXXX..XXXXXXX 100644
468
--- a/tests/qtest/bios-tables-test-allowed-diff.h
469
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
470
@@ -XXX,XX +XXX,XX @@
471
/* List of comma-separated changed AML files to ignore */
472
"tests/data/acpi/virt/VIOT",
473
-"tests/data/acpi/q35/DSDT.viot",
474
-"tests/data/acpi/q35/VIOT.viot",
475
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
476
index XXXXXXX..XXXXXXX 100644
477
GIT binary patch
478
literal 9398
479
zcmeHNO>7&-8J*>iv|O&FB}G~Oi$yp||57BBoWHhc5OS9yDTx$CQgH$r;8Idr*-4Q_
480
z5(9Az1F`}niVsB-)<KW7p`g9Br(A2Gm-gmc1N78GFS!;)e2V(MnH_0{q<{#yMgn&C
481
zn|*J-d9yqFhO_H6z19~`FlPL*u<DkZ*}|)JH;X@mF-FI<cPg<fti9tEN*yB^i5czN
482
zNq&q?!OZ;BE3B7{KWzJ-`Tn~f`9?Qj8~2^N8{Oc8J%57{==w%rS#;nOCp*nTr@iZ1
483
zb+?i;JLQUJ=O0?8*>S~D)a>NF1~WVB6^~_B#yhJ`H+JU@=6aXs`?Yv)J2h=N?drcS
484
zeLZ*n<<Bm^n}6`jfBx#u8&(W}1?)}iF9o#mZ~E2+zwdn7yK3AbIzKnxpZ>JRPm3~#
485
z&ICS{+_OayRW-l=Mtk=~uaS3o8z<_udd|(wqg`&JnVPfCe>BUOO`Su3e>pff_^UW%
486
z&JE^NO`)=Amg~iqRB1pPscP?(>#ZuY8GHCmlEvD$9g3%4Db~Dfz2SATnddvrR-Oe^
487
z;s;dJec!hnzi)ri^I6YN9vtkm{^TdUF8h7gX8-<Qe4p)GQ=)AtYx2VcwdLVAEXEjG
488
z^Mj|UHPqkj-LsWuzQem1>F3atdZn=zv3$#RmZzSHN+6-yyU#8cJb=YDilX&sl}vNm
489
znkgAR^O<3kj4if>{ly5fwRfMWuC5=lrlvKPX~i#654Cp}R_d*JS$9laZ$ra6)<ns8
490
zFZy28G%xP(nit&F>LDi%G<tIc=TY=gl$jSD&Uv!Yat~XR46h%rI$!}a%!|xG7u8Zn
491
zeY8_|n=K>xz_v_W8VX$W-Fg-qFWcT}7MCyz{%%{ia7hZ>Law-k6NOr}VI&_48U=2l
492
zwqDKFE8eTwwozDdms#e?x?5a|v>&JF;2_v0L~z5n%BYU^52<*cWuD4|GYUm@1+?))
493
zte^45>Rz)t*<T5V#={r>@t@{%?^i#W{i=HAZ*Dc9y59Va-+#P!jrGs;u38a{fLr`N
494
zvT@rUu>DljxJ?^&Z?-?vyJn3C>3D=qux{Y*bs5|5n)Qmi$TD^Zdn4GU$ocJS2Hh-<
495
z`xPI^^+v0nUVdjMos8k`WGl7hA`{03ju%<lrgAHSpd^DRf-*}_#Ly0mB!LSfVgWcQ
496
z&T$@~G9)JI=hz5m0vkrel+Xy{Oh7pkAu-V!j*W7rY(bO}Q$nMH2`FbGB&N)QaV4<4
497
zo)~9JXiP9=;}NPl<C@MmXG&;XFlFNrsyfFsonxFSp<}vEgsRSQP3O3#b6nSnP}ON_
498
zI!#Tdsp~|j>ckUB>FI=~GokB5sOq#dotCE4(sd$KbtW~PNlj-`*NIToiD#j5J#9^=
499
zt?NXn>YUJYPG~wObe#xQos*i*NloXZt`niEb4t@WrRki~bs|)CI+{*L)9L6s5vn><
500
zn$DD_Go|Z9sOn5>I@6lYw5}7Os&iV?Ij!lO)^#FOb!If38BJ$K*NIToIiu;E(R9w}
501
zIuWWmPiZ<&X*y5oIuWWmF_XaEC!a&Jn$B5WCqh-{X-(&8P3LJ{Cqh-{8P3dyPr@^t
502
zSqL9?X9Uwd3W@23*s~h*tj0X6GZCuHa~kuU#yqDp5vt7d8uPryJg+kms?5hU=3^T3
503
zF`bD}WnSP+=`t5MQ$FJ_2&Q~+BP6E0f^%BVIW6a$o)e+SX~IDBih-7z6{O~7YTy`&
504
zLjy&Cv?7QikV#>n0>>@MV8oK`Gmun34-FKdlm-J8SZSaNlnhir4-FI{S|bfqV8e)V
505
zss<{chX#reE#g=hsKAC%sF6d-Km}BWs!kZFsFpKfpbC@>6rprQGEjt4Ck#|zITHq|
506
zK*>M_l;<P^MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=xY&!axO<
507
zGhv_#lnhirIg<<&q0|Wj6<E%MfhtfkPyyvkGEjt4Ck#|zITHq|K*>M_lrzad5lWpf
508
zP=V!47^ngz0~JutBm+e#b;3XemNQ|X3X}{~Ksl2P6rt1!0~J`#gn=qhGEf2KOfpb}
509
zQYQ>lU^x>8szAv=1(Y+%KoLrvFi?TzOc<yFB?A>u&LjgxD0RX>1(q{mpbC@>R6seC
510
z3>2Z%2?G^a&V+#~P%=;f<xDbAgi<FARA4z12C6{GKn0XD$v_cGoiI>=<xCi;0wn_#
511
zP|hR+MJRQ`Kn0dFVW0|>3{*fllMEE0)CmI>Sk8ojDo`>|0p(0GP=rz^3{+q_69%e4
512
z$v_2^Gs!>^N}VuJf#pmXr~)Me6;RG314Srx!axxz28u{EP=u<1B2)}iVZuNaCK;&0
513
zBm-5LFi?dF167!0pbC==RAItE6($T+VUmF=Ofpb~2?JG_Fi?d_2C6X0Kouqo6p_5T
514
zFi=FeV!SiSKoR0H$dH(_Z(*Q_WZ%L-5y`$K14StNmJAdjmWs}HV4<vU_xO+1efmLq
515
zZ;W>N_U)fP6Qy6Nw5mbt9Y(#emWSi66=>tq#xoh#Ue=0qyhxi8ZOUe5y0V7VfPUhp
516
zwX=;ymc+i5%sg9Ja~lZ&8oAV@mHc>&CHP9v4R(jhtT?un;O4e9#pno)Xkh7OWgK&a
517
zyj=3Iv0OuoK_;5rOr5f(Kb~ZXDBO+V`OWYo#_C08imwChQxnjdd?wZLDou8aj;$SD
518
zGDYiA3<$Tu<JnHL(KPOChi#zrR32t83}naR$+ym4P_h?z_5#|cW-nw$XD_sOtE62l
519
zrD3@*)NVyiklt0&yF9%+klsBey&I<Y2E<!f(E8TuJte)z(|ZHyy<^gQVfx}=`q&B5
520
z7nSryp1wGczIaUfVwiq$Fn#<4=@*ssi#+|}K>EdF(l3VTOM~ghPLRH&q%ZOGrGfON
521
zW73zx^yR_y<0nX8R??Sw`tm^f@-gYlNFSp|*<gA{q?Zp5Oe-+l#rmyYmKozi9y=P>
522
zVReJU*h=ZuVXiS$ohTbw-O#v9>(yZbGE|)?8(H1ZIKvV!jWa0>vy!3eMA^vdhQ>`s
523
zuMSg{q3T50$m)j1!HixV<}X9liL#N^4c*tL^y)CF8LCc{jjV3yKAqL8!%SzWI#H%q
524
z=bSrQ&)%JCRttF5g4Zf`6l?y@>PzD7MA^D>wBlcH6r1ucwJ<p0O%rZ?JzIY3-QdmZ
525
zzs|n>`a5r3e|z)wcUaqS>nqFQ-8x}eCF4u`OWUxqst-@1rSmUs%WmKP5e0dcb?e2N
526
z;Z|x*!);VwF|Yuhqs^khqOM!@u*jY!WYldISF(V6`BoNd&6Qfk3>X#SuD^7J>p_D=
527
zBPa51y^_n#=cpOt#Zf$ya$Ae9Mfz56n|<i!a=ELS@)%a{^NIH3SDuN<R~sah1km#P
528
zU@?*f%<rG=4W1wgfi;C?_n|W@%lm$&8YfvNOJodIg&IcIpIJQRHr<+ej11GQ6)&eF
529
z2Lam*jIH}#y0>KnY%4JQfOYS$*uU%f#@$U6`N8I3N-lV?5ErFCdv~xDmu2(wexld4
530
z4v^;aVAT2k6GJ^m*FD(Wqc(Qg^)6a<?}h$zLoj}4;PP!+(O{@!a1y-hoAhF_7!z+6
531
zslpAmNtYbjHrw-~#SPVk_FUf>-Obg6yV`8o$8_`PyJe_;bY5_EMBfBfWU!Q=*9HsG
532
z%_Cda{@_Krr!oHVhv9+y+T5qR8zZ2aZ>5r!$*|f$^U%yBUYfR&B!+EYy_PwL!BeUi
533
zJH^}r3r9Q+B)X@Z)fk=P13w&7x#wBtXTZ)g>WITPg5r&pQc!nmyrmk#S(>>b9xnNr
534
zx_b#v9Xv-Y><Wb%?S^0Xe&<)bbKl_=Z|3C$tf|F<bYzE*mfHB;uC)`q-?buaBe?l?
535
zcLTpK*k<49Z32`K?|nSBMFqxTK^_IE-li2fEGdK~(ZdoKBl6ab4a;Hler#`xvEXJG
536
zb?<E%EZExfX>jcOVhS*0rS~RS1dA#xhkv@Nct@#q?LyeKS<$uFec!bw>{@uu$gZ6a
537
zyVen1i{1BKd%~`D7|m$;U0a<I*3I7%^N%N%lGYdU_GS!gaR8T$NA@GzFi~z`l7hdl
538
zarZy6590|88pi(1zq;V(>38zM0sT&<zX;R5$1w3;`_JMG`;&I&0Y23DMx1%@(w(R9
539
z4M$j;D5J+Gy%fijRQsctzFKf&cv|BAz#YLq3CZJWDdtL4u1u1|mkdcUp7|sxJC+?Y
540
z_@@s`v3j}Q7*z>6X~cwUxUL8G1KT)_XTp!KAbs;vCp{K3&~_X@+ew=-D}v`2MbFV0
541
zQsVsL=rXi-pI*G|iiz;VTCutgUs)hDzV1+4?8KcoP3xROf<M%qC6lgVdpFt4<-|uM
542
z=#rl_b1#YjSIl6Toj2z_hOZcKupkdE(LozC(fN=FY(x|sk)ym|;Rq2E1xJWD%Z!ol
543
Gu>S+TT-130
544
545
literal 0
546
HcmV?d00001
547
548
diff --git a/tests/data/acpi/q35/VIOT.viot b/tests/data/acpi/q35/VIOT.viot
549
index XXXXXXX..XXXXXXX 100644
550
GIT binary patch
551
literal 112
552
zcmWIZ^baXu00LVle`k+i1*eDrX9XZ&1PX!JAex!M0Hgv8m>C3sGzdcgBZCA3T-xBj
553
Q0Zb)W9Hva*zW_`e0M!8s0RR91
554
555
literal 0
556
HcmV?d00001
557
89
--
558
--
90
2.7.4
559
2.25.1
91
560
92
561
diff view generated by jsdifflib
1
The Application Interrupt and Reset Control Register has some changes
1
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
2
for v8M:
3
* new bits SYSRESETREQS, BFHFNMINS and PRIS: these all have
4
real state if the security extension is implemented and otherwise
5
are constant
6
* the PRIGROUP field is banked between security states
7
* non-secure code can be blocked from using the SYSRESET bit
8
to reset the system if SYSRESETREQS is set
9
2
10
Implement the new state and the changes to register read and write.
3
The VIOT blob contains the following:
11
For the moment we ignore the effects of the secure PRIGROUP.
12
We will implement the effects of PRIS and BFHFNMIS later.
13
4
5
[000h 0000 4] Signature : "VIOT" [Virtual I/O Translation Table]
6
[004h 0004 4] Table Length : 00000058
7
[008h 0008 1] Revision : 00
8
[009h 0009 1] Checksum : 66
9
[00Ah 0010 6] Oem ID : "BOCHS "
10
[010h 0016 8] Oem Table ID : "BXPC "
11
[018h 0024 4] Oem Revision : 00000001
12
[01Ch 0028 4] Asl Compiler ID : "BXPC"
13
[020h 0032 4] Asl Compiler Revision : 00000001
14
15
[024h 0036 2] Node count : 0002
16
[026h 0038 2] Node offset : 0030
17
[028h 0040 8] Reserved : 0000000000000000
18
19
[030h 0048 1] Type : 03 [VirtIO-PCI IOMMU]
20
[031h 0049 1] Reserved : 00
21
[032h 0050 2] Length : 0010
22
23
[034h 0052 2] PCI Segment : 0000
24
[036h 0054 2] PCI BDF number : 0008
25
[038h 0056 8] Reserved : 0000000000000000
26
27
[040h 0064 1] Type : 01 [PCI Range]
28
[041h 0065 1] Reserved : 00
29
[042h 0066 2] Length : 0018
30
31
[044h 0068 4] Endpoint start : 00000000
32
[048h 0072 2] PCI Segment start : 0000
33
[04Ah 0074 2] PCI Segment end : 0000
34
[04Ch 0076 2] PCI BDF start : 0000
35
[04Eh 0078 2] PCI BDF end : 00FF
36
[050h 0080 2] Output node : 0030
37
[052h 0082 6] Reserved : 000000000000
38
39
Acked-by: Ani Sinha <ani@anisinha.ca>
40
Reviewed-by: Eric Auger <eric.auger@redhat.com>
41
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
42
Message-id: 20211210170415.583179-9-jean-philippe@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 1505240046-11454-6-git-send-email-peter.maydell@linaro.org
17
---
44
---
18
include/hw/intc/armv7m_nvic.h | 3 ++-
45
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
19
target/arm/cpu.h | 12 +++++++++++
46
tests/data/acpi/virt/VIOT | Bin 0 -> 88 bytes
20
hw/intc/armv7m_nvic.c | 49 +++++++++++++++++++++++++++++++++----------
47
2 files changed, 1 deletion(-)
21
target/arm/cpu.c | 7 +++++++
22
4 files changed, 59 insertions(+), 12 deletions(-)
23
48
24
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
49
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
25
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/intc/armv7m_nvic.h
51
--- a/tests/qtest/bios-tables-test-allowed-diff.h
27
+++ b/include/hw/intc/armv7m_nvic.h
52
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
53
@@ -1,2 +1 @@
29
* Entries in sec_vectors[] for non-banked exception numbers are unused.
54
/* List of comma-separated changed AML files to ignore */
30
*/
55
-"tests/data/acpi/virt/VIOT",
31
VecInfo sec_vectors[NVIC_INTERNAL_VECTORS];
56
diff --git a/tests/data/acpi/virt/VIOT b/tests/data/acpi/virt/VIOT
32
- uint32_t prigroup;
33
+ /* The PRIGROUP field in AIRCR is banked */
34
+ uint32_t prigroup[M_REG_NUM_BANKS];
35
36
/* The following fields are all cached state that can be recalculated
37
* from the vectors[] and sec_vectors[] arrays and the prigroup field:
38
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
39
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/cpu.h
58
GIT binary patch
41
+++ b/target/arm/cpu.h
59
literal 88
42
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
60
zcmWIZ^bd((0D?3pe`k+i1*eDrX9XZ&1PX!JAexE60Hgv8m>C3sGzXN&z`)2L0cSHX
43
int exception;
61
I{D-Rq0Q5fy0RR91
44
uint32_t primask[M_REG_NUM_BANKS];
62
45
uint32_t faultmask[M_REG_NUM_BANKS];
63
literal 0
46
+ uint32_t aircr; /* only holds r/w state if security extn implemented */
64
HcmV?d00001
47
uint32_t secure; /* Is CPU in Secure state? (not guest visible) */
65
48
} v7m;
49
50
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CCR, STKALIGN, 9, 1)
51
FIELD(V7M_CCR, DC, 16, 1)
52
FIELD(V7M_CCR, IC, 17, 1)
53
54
+/* V7M AIRCR bits */
55
+FIELD(V7M_AIRCR, VECTRESET, 0, 1)
56
+FIELD(V7M_AIRCR, VECTCLRACTIVE, 1, 1)
57
+FIELD(V7M_AIRCR, SYSRESETREQ, 2, 1)
58
+FIELD(V7M_AIRCR, SYSRESETREQS, 3, 1)
59
+FIELD(V7M_AIRCR, PRIGROUP, 8, 3)
60
+FIELD(V7M_AIRCR, BFHFNMINS, 13, 1)
61
+FIELD(V7M_AIRCR, PRIS, 14, 1)
62
+FIELD(V7M_AIRCR, ENDIANNESS, 15, 1)
63
+FIELD(V7M_AIRCR, VECTKEY, 16, 16)
64
+
65
/* V7M CFSR bits for MMFSR */
66
FIELD(V7M_CFSR, IACCVIOL, 0, 1)
67
FIELD(V7M_CFSR, DACCVIOL, 1, 1)
68
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/intc/armv7m_nvic.c
71
+++ b/hw/intc/armv7m_nvic.c
72
@@ -XXX,XX +XXX,XX @@ static bool nvic_isrpending(NVICState *s)
73
*/
74
static inline uint32_t nvic_gprio_mask(NVICState *s)
75
{
76
- return ~0U << (s->prigroup + 1);
77
+ return ~0U << (s->prigroup[M_REG_NS] + 1);
78
}
79
80
/* Recompute vectpending and exception_prio */
81
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
82
return val;
83
case 0xd08: /* Vector Table Offset. */
84
return cpu->env.v7m.vecbase[attrs.secure];
85
- case 0xd0c: /* Application Interrupt/Reset Control. */
86
- return 0xfa050000 | (s->prigroup << 8);
87
+ case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
88
+ val = 0xfa050000 | (s->prigroup[attrs.secure] << 8);
89
+ if (attrs.secure) {
90
+ /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */
91
+ val |= cpu->env.v7m.aircr;
92
+ } else {
93
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
94
+ /* BFHFNMINS is R/O from NS; other bits are RAZ/WI. If
95
+ * security isn't supported then BFHFNMINS is RAO (and
96
+ * the bit in env.v7m.aircr is always set).
97
+ */
98
+ val |= cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK;
99
+ }
100
+ }
101
+ return val;
102
case 0xd10: /* System Control. */
103
/* TODO: Implement SLEEPONEXIT. */
104
return 0;
105
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
106
case 0xd08: /* Vector Table Offset. */
107
cpu->env.v7m.vecbase[attrs.secure] = value & 0xffffff80;
108
break;
109
- case 0xd0c: /* Application Interrupt/Reset Control. */
110
- if ((value >> 16) == 0x05fa) {
111
- if (value & 4) {
112
- qemu_irq_pulse(s->sysresetreq);
113
+ case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */
114
+ if ((value >> R_V7M_AIRCR_VECTKEY_SHIFT) == 0x05fa) {
115
+ if (value & R_V7M_AIRCR_SYSRESETREQ_MASK) {
116
+ if (attrs.secure ||
117
+ !(cpu->env.v7m.aircr & R_V7M_AIRCR_SYSRESETREQS_MASK)) {
118
+ qemu_irq_pulse(s->sysresetreq);
119
+ }
120
}
121
- if (value & 2) {
122
+ if (value & R_V7M_AIRCR_VECTCLRACTIVE_MASK) {
123
qemu_log_mask(LOG_GUEST_ERROR,
124
"Setting VECTCLRACTIVE when not in DEBUG mode "
125
"is UNPREDICTABLE\n");
126
}
127
- if (value & 1) {
128
+ if (value & R_V7M_AIRCR_VECTRESET_MASK) {
129
+ /* NB: this bit is RES0 in v8M */
130
qemu_log_mask(LOG_GUEST_ERROR,
131
"Setting VECTRESET when not in DEBUG mode "
132
"is UNPREDICTABLE\n");
133
}
134
- s->prigroup = extract32(value, 8, 3);
135
+ s->prigroup[attrs.secure] = extract32(value,
136
+ R_V7M_AIRCR_PRIGROUP_SHIFT,
137
+ R_V7M_AIRCR_PRIGROUP_LENGTH);
138
+ if (attrs.secure) {
139
+ /* These bits are only writable by secure */
140
+ cpu->env.v7m.aircr = value &
141
+ (R_V7M_AIRCR_SYSRESETREQS_MASK |
142
+ R_V7M_AIRCR_BFHFNMINS_MASK |
143
+ R_V7M_AIRCR_PRIS_MASK);
144
+ }
145
nvic_irq_update(s);
146
}
147
break;
148
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic_security = {
149
.fields = (VMStateField[]) {
150
VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1,
151
vmstate_VecInfo, VecInfo),
152
+ VMSTATE_UINT32(prigroup[M_REG_S], NVICState),
153
VMSTATE_END_OF_LIST()
154
}
155
};
156
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_nvic = {
157
.fields = (VMStateField[]) {
158
VMSTATE_STRUCT_ARRAY(vectors, NVICState, NVIC_MAX_VECTORS, 1,
159
vmstate_VecInfo, VecInfo),
160
- VMSTATE_UINT32(prigroup, NVICState),
161
+ VMSTATE_UINT32(prigroup[M_REG_NS], NVICState),
162
VMSTATE_END_OF_LIST()
163
},
164
.subsections = (const VMStateDescription*[]) {
165
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
166
index XXXXXXX..XXXXXXX 100644
167
--- a/target/arm/cpu.c
168
+++ b/target/arm/cpu.c
169
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
170
171
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
172
env->v7m.secure = true;
173
+ } else {
174
+ /* This bit resets to 0 if security is supported, but 1 if
175
+ * it is not. The bit is not present in v7M, but we set it
176
+ * here so we can avoid having to make checks on it conditional
177
+ * on ARM_FEATURE_V8 (we don't let the guest see the bit).
178
+ */
179
+ env->v7m.aircr = R_V7M_AIRCR_BFHFNMINS_MASK;
180
}
181
182
/* In v7M the reset value of this bit is IMPDEF, but ARM recommends
183
--
66
--
184
2.7.4
67
2.25.1
185
68
186
69
diff view generated by jsdifflib