1
First pullreq for arm of the 4.1 series, since I'm back from
1
Hi; here's a target-arm pullreq. Mostly this is RTH's FEAT_RME
2
holiday now. This is mostly my M-profile FPU series and Philippe's
2
series; there are also a handful of bug fixes including some
3
devices.h cleanup. I have a pile of other patchsets to work through
3
which aren't arm-specific but which it's convenient to include
4
in my to-review folder, but 42 patches is definitely quite
4
here.
5
big enough to send now...
6
5
7
thanks
6
thanks
8
-- PMM
7
-- PMM
9
8
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
9
The following changes since commit b455ce4c2f300c8ba47cba7232dd03261368a4cb:
11
10
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
11
Merge tag 'q800-for-8.1-pull-request' of https://github.com/vivier/qemu-m68k into staging (2023-06-22 10:18:32 +0200)
13
12
14
are available in the Git repository at:
13
are available in the Git repository at:
15
14
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230623
17
16
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
17
for you to fetch changes up to 497fad38979c16b6412388927401e577eba43d26:
19
18
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
19
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym (2023-06-23 11:46:02 +0100)
21
20
22
----------------------------------------------------------------
21
----------------------------------------------------------------
23
target-arm queue:
22
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
23
* Add (experimental) support for FEAT_RME
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
24
* host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
26
* hw/dma: Compile the bcm2835_dma device as common object
25
* target/arm: Restructure has_vfp_d32 test
27
* configure: Remove --source-path option
26
* hw/arm/sbsa-ref: add ITS support in SBSA GIC
28
* hw/ssi/xilinx_spips: Avoid variable length array
27
* target/arm: Fix sve predicate store, 8 <= VQ <= 15
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
28
* pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
30
29
31
----------------------------------------------------------------
30
----------------------------------------------------------------
32
Eric Auger (1):
31
Peter Maydell (2):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
32
host-utils: Avoid using __builtin_subcll on buggy versions of Apple Clang
33
pc-bios/keymaps: Use the official xkb name for Arabic layout, not the legacy synonym
34
34
35
Peter Maydell (28):
35
Richard Henderson (23):
36
hw/ssi/xilinx_spips: Avoid variable length array
36
target/arm: Add isar_feature_aa64_rme
37
configure: Remove --source-path option
37
target/arm: Update SCR and HCR for RME
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
38
target/arm: SCR_EL3.NS may be RES1
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
39
target/arm: Add RME cpregs
40
target/arm: Implement dummy versions of M-profile FP-related registers
40
target/arm: Introduce ARMSecuritySpace
41
target/arm: Disable most VFP sysregs for M-profile
41
include/exec/memattrs: Add two bits of space to MemTxAttrs
42
target/arm: Honour M-profile FP enable bits
42
target/arm: Adjust the order of Phys and Stage2 ARMMMUIdx
43
target/arm: Decode FP instructions for M profile
43
target/arm: Introduce ARMMMUIdx_Phys_{Realm,Root}
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
44
target/arm: Remove __attribute__((nonnull)) from ptw.c
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
45
target/arm: Pipe ARMSecuritySpace through ptw.c
46
target/arm/helper: don't return early for STKOF faults during stacking
46
target/arm: NSTable is RES0 for the RME EL3 regime
47
target/arm: Handle floating point registers in exception entry
47
target/arm: Handle Block and Page bits for security space
48
target/arm: Implement v7m_update_fpccr()
48
target/arm: Handle no-execute for Realm and Root regimes
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
49
target/arm: Use get_phys_addr_with_struct in S1_ptw_translate
50
target/arm: Clean excReturn bits when tail chaining
50
target/arm: Move s1_is_el0 into S1Translate
51
target/arm: Allow for floating point in callee stack integrity check
51
target/arm: Use get_phys_addr_with_struct for stage2
52
target/arm: Handle floating point registers in exception return
52
target/arm: Add GPC syndrome
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
53
target/arm: Implement GPC exceptions
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
54
target/arm: Implement the granule protection check
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
55
target/arm: Add cpu properties for enabling FEAT_RME
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
56
docs/system/arm: Document FEAT_RME
57
target/arm: New helper function arm_v7m_mmu_idx_all()
57
target/arm: Restructure has_vfp_d32 test
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
58
target/arm: Fix sve predicate store, 8 <= VQ <= 15
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
64
59
65
Philippe Mathieu-Daudé (13):
60
Shashi Mallela (1):
66
hw/dma: Compile the bcm2835_dma device as common object
61
hw/arm/sbsa-ref: add ITS support in SBSA GIC
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
69
hw/display/tc6393xb: Remove unused functions
70
hw/devices: Move TC6393XB declarations into a new header
71
hw/devices: Move Blizzard declarations into a new header
72
hw/devices: Move CBus declarations into a new header
73
hw/devices: Move Gamepad declarations into a new header
74
hw/devices: Move TI touchscreen declarations into a new header
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
79
62
80
configure | 10 +-
63
docs/system/arm/cpu-features.rst | 23 ++
81
hw/dma/Makefile.objs | 2 +-
64
docs/system/arm/emulation.rst | 1 +
82
include/hw/arm/omap.h | 6 +-
65
docs/system/arm/sbsa.rst | 14 +
83
include/hw/arm/smmu-common.h | 8 +-
66
include/exec/memattrs.h | 9 +-
84
include/hw/devices.h | 62 ---
67
include/qemu/compiler.h | 13 +
85
include/hw/display/blizzard.h | 22 ++
68
include/qemu/host-utils.h | 2 +-
86
include/hw/display/tc6393xb.h | 24 ++
69
target/arm/cpu.h | 151 ++++++++---
87
include/hw/input/gamepad.h | 19 +
70
target/arm/internals.h | 27 ++
88
include/hw/input/tsc2xxx.h | 36 ++
71
target/arm/syndrome.h | 10 +
89
include/hw/misc/cbus.h | 32 ++
72
hw/arm/sbsa-ref.c | 33 ++-
90
include/hw/net/lan9118.h | 21 +
73
target/arm/cpu.c | 32 ++-
91
include/hw/net/ne2000-isa.h | 6 +
74
target/arm/helper.c | 162 ++++++++++-
92
include/hw/net/smc91c111.h | 19 +
75
target/arm/ptw.c | 570 +++++++++++++++++++++++++++++++--------
93
include/qemu/typedefs.h | 1 -
76
target/arm/tcg/cpu64.c | 53 ++++
94
target/arm/cpu.h | 95 ++++-
77
target/arm/tcg/tlb_helper.c | 96 ++++++-
95
target/arm/helper.h | 5 +
78
target/arm/tcg/translate-sve.c | 2 +-
96
target/arm/translate.h | 3 +
79
pc-bios/keymaps/meson.build | 2 +-
97
hw/arm/aspeed.c | 13 +-
80
17 files changed, 1034 insertions(+), 166 deletions(-)
98
hw/arm/exynos4_boards.c | 3 +-
99
hw/arm/gumstix.c | 2 +-
100
hw/arm/integratorcp.c | 2 +-
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
139
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
The SMMUNotifierNode struct is not necessary and brings extra
4
complexity so let's remove it. We now directly track the SMMUDevices
5
which have registered IOMMU MR notifiers.
6
7
This is inspired from the same transformation on intel-iommu
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/arm/smmu-common.h | 8 ++------
17
hw/arm/smmu-common.c | 6 +++---
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
24
+++ b/include/hw/arm/smmu-common.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
26
AddressSpace as;
27
uint32_t cfg_cache_hits;
28
uint32_t cfg_cache_misses;
29
+ QLIST_ENTRY(SMMUDevice) next;
30
} SMMUDevice;
31
32
-typedef struct SMMUNotifierNode {
33
- SMMUDevice *sdev;
34
- QLIST_ENTRY(SMMUNotifierNode) next;
35
-} SMMUNotifierNode;
36
-
37
typedef struct SMMUPciBus {
38
PCIBus *bus;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
41
GHashTable *iotlb;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
65
}
66
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
119
}
120
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
In the stripe8() function we use a variable length array; however
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
22
{
23
- uint8_t r[num];
24
- memset(r, 0, sizeof(uint8_t) * num);
25
+ uint8_t r[MAX_NUM_BUSSES];
26
int idx[2] = {0, 0};
27
int bit[2] = {0, 7};
28
int d = dir;
29
30
+ assert(num <= MAX_NUM_BUSSES);
31
+ memset(r, 0, sizeof(uint8_t) * num);
32
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
Normally configure identifies the source path by looking
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
5
1
6
There isn't really an obvious use case for the --source-path
7
option, and in commit 927128222b0a91f56c13a in 2017 we
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
12
The fact that nobody complained suggests that there isn't
13
any use of this option and we aren't testing it either;
14
remove it. This allows us to move the "make $source_path
15
absolute" logic up so that there is no window in the script
16
where $source_path is set but not yet absolute.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
21
---
22
configure | 10 ++--------
23
1 file changed, 2 insertions(+), 8 deletions(-)
24
25
diff --git a/configure b/configure
26
index XXXXXXX..XXXXXXX 100755
27
--- a/configure
28
+++ b/configure
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
30
31
# default parameters
32
source_path=$(dirname "$0")
33
+# make source path absolute
34
+source_path=$(cd "$source_path"; pwd)
35
cpu=""
36
iasl="iasl"
37
interp_prefix="/usr/gnemul/qemu-%M"
38
@@ -XXX,XX +XXX,XX @@ for opt do
39
;;
40
--cxx=*) CXX="$optarg"
41
;;
42
- --source-path=*) source_path="$optarg"
43
- ;;
44
--cpu=*) cpu="$optarg"
45
;;
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
48
LDFLAGS="-g $LDFLAGS"
49
fi
50
51
-# make source path absolute
52
-source_path=$(cd "$source_path"; pwd)
53
-
54
# running configure in the source tree?
55
# we know that's the case if configure is there.
56
if test -f "./configure"; then
57
@@ -XXX,XX +XXX,XX @@ for opt do
58
;;
59
--interp-prefix=*) interp_prefix="$optarg"
60
;;
61
- --source-path=*)
62
- ;;
63
--cross-prefix=*)
64
;;
65
--cc=*)
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
68
69
Advanced options (experts only):
70
- --source-path=PATH path of source code [$source_path]
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
72
--cc=CC use C compiler CC [$cc]
73
--iasl=IASL use ACPI compiler IASL [$iasl]
74
--
75
2.20.1
76
77
diff view generated by jsdifflib
Deleted patch
1
Enforce that for M-profile various FPSCR bits which are RES0 there
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
10
target/arm/vfp_helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
16
+++ b/target/arm/vfp_helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
18
val &= ~FPCR_FZ16;
19
}
20
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
22
+ /*
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
24
+ * and also for the trapped-exception-handling bits IxE.
25
+ */
26
+ val &= 0xf7c0009f;
27
+ }
28
+
29
/*
30
* We don't implement trapped exception handling, so the
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
Deleted patch
1
For M-profile the MVFR* ID registers are memory mapped, in the
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
10
1 file changed, 6 insertions(+)
11
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
+++ b/hw/intc/armv7m_nvic.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
return 0;
18
}
19
return cpu->env.v7m.sfar;
20
+ case 0xf40: /* MVFR0 */
21
+ return cpu->isar.mvfr0;
22
+ case 0xf44: /* MVFR1 */
23
+ return cpu->isar.mvfr1;
24
+ case 0xf48: /* MVFR2 */
25
+ return cpu->isar.mvfr2;
26
default:
27
bad_offset:
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
29
--
30
2.20.1
31
32
diff view generated by jsdifflib
Deleted patch
1
The M-profile floating point support has three associated config
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
Add support for all of these as simple reads-as-written registers.
5
We will hook up actual functionality later.
6
1
7
The main complexity here is handling the FPCCR register, which
8
has a mix of banked and unbanked bits.
9
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
20
---
21
target/arm/cpu.h | 34 ++++++++++++
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
23
target/arm/cpu.c | 5 ++
24
target/arm/machine.c | 16 ++++++
25
4 files changed, 180 insertions(+)
26
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
32
uint32_t scr[M_REG_NUM_BANKS];
33
uint32_t msplim[M_REG_NUM_BANKS];
34
uint32_t psplim[M_REG_NUM_BANKS];
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
39
+ uint32_t nsacr;
40
} v7m;
41
42
/* Information associated with an exception about to be taken:
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
44
*/
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
46
47
+/* v7M FPCCR bits */
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
49
+FIELD(V7M_FPCCR, USER, 1, 1)
50
+FIELD(V7M_FPCCR, S, 2, 1)
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
67
+#define R_V7M_FPCCR_BANKED_MASK \
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
69
+ R_V7M_FPCCR_USER_MASK | \
70
+ R_V7M_FPCCR_THREAD_MASK | \
71
+ R_V7M_FPCCR_MMRDY_MASK | \
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
73
+ R_V7M_FPCCR_UFRDY_MASK | \
74
+ R_V7M_FPCCR_ASPEN_MASK)
75
+
76
/*
77
* System register ID fields.
78
*/
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
84
}
85
case 0xd84: /* CSSELR */
86
return cpu->env.v7m.csselr[attrs.secure];
87
+ case 0xd88: /* CPACR */
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
89
+ return 0;
90
+ }
91
+ return cpu->env.v7m.cpacr[attrs.secure];
92
+ case 0xd8c: /* NSACR */
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
94
+ return 0;
95
+ }
96
+ return cpu->env.v7m.nsacr;
97
/* TODO: Implement debug registers. */
98
case 0xd90: /* MPU_TYPE */
99
/* Unified MPU; if the MPU is not present this value is zero */
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
101
return 0;
102
}
103
return cpu->env.v7m.sfar;
104
+ case 0xf34: /* FPCCR */
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
106
+ return 0;
107
+ }
108
+ if (attrs.secure) {
109
+ return cpu->env.v7m.fpccr[M_REG_S];
110
+ } else {
111
+ /*
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
114
+ * other non-banked bits RAZ.
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
116
+ */
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
119
+ R_V7M_FPCCR_CLRONRET_MASK |
120
+ R_V7M_FPCCR_MONRDY_MASK;
121
+
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
124
+ }
125
+
126
+ value &= mask;
127
+
128
+ value |= cpu->env.v7m.fpccr[M_REG_NS];
129
+ return value;
130
+ }
131
+ case 0xf38: /* FPCAR */
132
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
133
+ return 0;
134
+ }
135
+ return cpu->env.v7m.fpcar[attrs.secure];
136
+ case 0xf3c: /* FPDSCR */
137
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
138
+ return 0;
139
+ }
140
+ return cpu->env.v7m.fpdscr[attrs.secure];
141
case 0xf40: /* MVFR0 */
142
return cpu->isar.mvfr0;
143
case 0xf44: /* MVFR1 */
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
146
}
147
break;
148
+ case 0xd88: /* CPACR */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
152
+ }
153
+ break;
154
+ case 0xd8c: /* NSACR */
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
158
+ }
159
+ break;
160
case 0xd90: /* MPU_TYPE */
161
return; /* RO */
162
case 0xd94: /* MPU_CTRL */
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
164
}
165
break;
166
}
167
+ case 0xf34: /* FPCCR */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
242
}
243
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
248
+ }
249
/* Unlike A/R profile, M profile defines the reset LR value */
250
env->regs[14] = 0xffffffff;
251
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
257
}
258
};
259
260
+static const VMStateDescription vmstate_m_fp = {
261
+ .name = "cpu/m/fp",
262
+ .version_id = 1,
263
+ .minimum_version_id = 1,
264
+ .needed = vfp_needed,
265
+ .fields = (VMStateField[]) {
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
271
+ VMSTATE_END_OF_LIST()
272
+ }
273
+};
274
+
275
static const VMStateDescription vmstate_m = {
276
.name = "cpu/m",
277
.version_id = 4,
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
279
&vmstate_m_scr,
280
&vmstate_m_other_sp,
281
&vmstate_m_v8m,
282
+ &vmstate_m_fp,
283
NULL
284
}
285
};
286
--
287
2.20.1
288
289
diff view generated by jsdifflib
Deleted patch
1
The only "system register" that M-profile floating point exposes
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
10
target/arm/translate.c | 19 +++++++++++++++++--
11
1 file changed, 17 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
18
}
19
}
20
} else { /* !dp */
21
+ bool is_sysreg;
22
+
23
if ((insn & 0x6f) != 0x00)
24
return 1;
25
rn = VFP_SREG_N(insn);
26
+
27
+ is_sysreg = extract32(insn, 21, 1);
28
+
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
30
+ /*
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
33
+ */
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
35
+ return 1;
36
+ }
37
+ }
38
+
39
if (insn & ARM_CP_RW_BIT) {
40
/* vfp->arm */
41
- if (insn & (1 << 21)) {
42
+ if (is_sysreg) {
43
/* system register */
44
rn >>= 1;
45
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
47
}
48
} else {
49
/* arm->vfp */
50
- if (insn & (1 << 21)) {
51
+ if (is_sysreg) {
52
rn >>= 1;
53
/* system register */
54
switch (rn) {
55
--
56
2.20.1
57
58
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
From: Richard Henderson <richard.henderson@linaro.org>
2
start using the cs_base word, but before we do that we can
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
6
2
3
Add the missing field for ID_AA64PFR0, and the predicate.
4
Disable it if EL3 is forced off by the board or command-line.
5
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-2-richard.henderson@linaro.org
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: 20190416125744.27770-18-peter.maydell@linaro.org
10
---
11
---
11
target/arm/cpu.h | 10 ++++++----
12
target/arm/cpu.h | 6 ++++++
12
target/arm/cpu.c | 7 +++++++
13
target/arm/cpu.c | 4 ++++
13
target/arm/helper.c | 6 +++++-
14
2 files changed, 10 insertions(+)
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
15
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
18
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
20
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64PFR0, SEL2, 36, 4)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
21
FIELD(ID_AA64PFR0, MPAM, 40, 4)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
22
FIELD(ID_AA64PFR0, AMU, 44, 4)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
23
FIELD(ID_AA64PFR0, DIT, 48, 4)
25
+/*
24
+FIELD(ID_AA64PFR0, RME, 52, 4)
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
25
FIELD(ID_AA64PFR0, CSV2, 56, 4)
27
+ * checks on the other bits at runtime. This shares the same bits as
26
FIELD(ID_AA64PFR0, CSV3, 60, 4)
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
27
29
+ */
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
29
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
31
/*
30
}
32
* Indicates whether cp register reads and writes by guest code should access
31
33
* the secure or nonsecure bank of banked registers; note that this is not
32
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
33
+{
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
34
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
35
+}
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
36
+
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
37
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
39
- * checks on the other bits at runtime
38
{
40
- */
39
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
42
/* For M profile only, Handler (ie not Thread) mode */
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
44
/* For M profile only, whether we should generate stack-limit checks */
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
40
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
42
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
43
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
44
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
45
cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, COPSDBG, 0);
46
cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
47
ID_AA64PFR0, EL3, 0);
48
+
49
+ /* Disable the realm management extension, which requires EL3. */
50
+ cpu->isar.id_aa64pfr0 = FIELD_DP64(cpu->isar.id_aa64pfr0,
51
+ ID_AA64PFR0, RME, 0);
51
}
52
}
52
53
53
+ /*
54
if (!cpu->has_el2) {
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
56
+ */
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
59
+
60
if (arm_feature(env, ARM_FEATURE_V7) &&
61
!arm_feature(env, ARM_FEATURE_M) &&
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
76
+ }
77
}
78
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/translate.c
83
+++ b/target/arm/translate.c
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
92
+ dc->vec_stride = 0;
93
+ } else {
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
95
+ dc->c15_cpar = 0;
96
+ }
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
99
regime_is_secure(env, dc->mmu_idx);
100
--
55
--
101
2.20.1
56
2.34.1
102
57
103
58
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
From: Richard Henderson <richard.henderson@linaro.org>
2
context preservation is enabled. Before executing any floating-point
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
2
9
Implement this with a new TB flag which tracks whether we
3
Define the missing SCR and HCR bits, allow SCR_NSE and {SCR,HCR}_GPF
10
need to create a new FP context.
4
to be set, and invalidate TLBs when NSE changes.
11
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-3-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
15
---
10
---
16
target/arm/cpu.h | 2 ++
11
target/arm/cpu.h | 5 +++--
17
target/arm/translate.h | 1 +
12
target/arm/helper.c | 10 ++++++++--
18
target/arm/helper.c | 13 +++++++++++++
13
2 files changed, 11 insertions(+), 4 deletions(-)
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
14
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
19
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
20
#define HCR_TERR (1ULL << 36)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
21
#define HCR_TEA (1ULL << 37)
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
22
#define HCR_MIOCNCE (1ULL << 38)
30
+/* For M profile only, set if we must create a new FP context */
23
-/* RES0 bit 39 */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
24
+#define HCR_TME (1ULL << 39)
32
/* For M profile only, set if FPCCR.S does not match current security state */
25
#define HCR_APK (1ULL << 40)
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
26
#define HCR_API (1ULL << 41)
34
/* For M profile only, Handler (ie not Thread) mode */
27
#define HCR_NV (1ULL << 42)
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
28
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
36
index XXXXXXX..XXXXXXX 100644
29
#define HCR_NV2 (1ULL << 45)
37
--- a/target/arm/translate.h
30
#define HCR_FWB (1ULL << 46)
38
+++ b/target/arm/translate.h
31
#define HCR_FIEN (1ULL << 47)
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
32
-/* RES0 bit 48 */
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
33
+#define HCR_GPF (1ULL << 48)
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
34
#define HCR_TID4 (1ULL << 49)
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
35
#define HCR_TICAB (1ULL << 50)
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
36
#define HCR_AMVOFFEN (1ULL << 51)
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
37
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
45
* so that top level loop can generate correct syndrome information.
38
#define SCR_TRNDR (1ULL << 40)
46
*/
39
#define SCR_ENTP2 (1ULL << 41)
40
#define SCR_GPF (1ULL << 48)
41
+#define SCR_NSE (1ULL << 62)
42
43
#define HSTR_TTEE (1 << 16)
44
#define HSTR_TJDBX (1 << 17)
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
47
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
48
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
49
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
50
if (cpu_isar_feature(aa64_fgt, cpu)) {
53
}
51
valid_mask |= SCR_FGTEN;
54
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
77
s->v8m_fpccr_s_wrong = false;
78
}
52
}
79
+
53
+ if (cpu_isar_feature(aa64_rme, cpu)) {
80
+ if (s->v7m_new_fp_ctxt_needed) {
54
+ valid_mask |= SCR_NSE | SCR_GPF;
81
+ /*
55
+ }
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
56
} else {
83
+ * and the FPSCR.
57
valid_mask &= ~(SCR_RW | SCR_ST);
84
+ */
58
if (cpu_isar_feature(aa32_ras, cpu)) {
85
+ TCGv_i32 control, fpscr;
59
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
60
env->cp15.scr_el3 = value;
87
+
61
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
62
/*
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
63
- * If SCR_EL3.NS changes, i.e. arm_is_secure_below_el3, then
90
+ tcg_temp_free_i32(fpscr);
64
+ * If SCR_EL3.{NS,NSE} changes, i.e. change of security state,
91
+ /*
65
* we must invalidate all TLBs below EL3.
92
+ * We don't need to arrange to end the TB, because the only
66
*/
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
67
- if (changed & SCR_NS) {
94
+ * and VECSTRIDE, and those don't exist for M-profile.
68
+ if (changed & (SCR_NS | SCR_NSE)) {
95
+ */
69
tlb_flush_by_mmuidx(env_cpu(env), (ARMMMUIdxBit_E10_0 |
96
+
70
ARMMMUIdxBit_E20_0 |
97
+ if (s->v8m_secure) {
71
ARMMMUIdxBit_E10_1 |
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
72
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
99
+ }
73
if (cpu_isar_feature(aa64_fwb, cpu)) {
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
74
valid_mask |= HCR_FWB;
101
+ tcg_gen_ori_i32(control, control, bits);
75
}
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
76
+ if (cpu_isar_feature(aa64_rme, cpu)) {
103
+ /* Don't need to do this for any further FP insns in this TB */
77
+ valid_mask |= HCR_GPF;
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
78
+ }
106
}
79
}
107
80
108
if (extract32(insn, 28, 4) == 0xf) {
81
if (cpu_isar_feature(any_evt, cpu)) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
110
regime_is_secure(env, dc->mmu_idx);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
113
+ dc->v7m_new_fp_ctxt_needed =
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
117
118
--
82
--
119
2.20.1
83
2.34.1
120
121
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
From: Richard Henderson <richard.henderson@linaro.org>
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
2
9
Implement this by changing the existing flag argument that
3
With RME, SEL2 must also be present to support secure state.
10
tells us whether to ignore faults or not into an enum that
4
The NS bit is RES1 if SEL2 is not present.
11
specifies which of the 3 modes we should handle.
12
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-4-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
16
---
10
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
11
target/arm/helper.c | 3 +++
18
1 file changed, 79 insertions(+), 39 deletions(-)
12
1 file changed, 3 insertions(+)
19
13
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
16
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
17
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
18
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
25
}
26
}
27
28
+/*
29
+ * What kind of stack write are we doing? This affects how exceptions
30
+ * generated during the stacking are treated.
31
+ */
32
+typedef enum StackingMode {
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
39
- ARMMMUIdx mmu_idx, bool ignfault)
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
41
{
42
CPUState *cs = CPU(cpu);
43
CPUARMState *env = &cpu->env;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
19
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
20
if (cpu_isar_feature(aa64_sel2, cpu)) {
82
attrs, &txres);
21
valid_mask |= SCR_EEL2;
83
if (txres != MEMTX_OK) {
22
+ } else if (cpu_isar_feature(aa64_rme, cpu)) {
84
/* BusFault trying to write the data */
23
+ /* With RME and without SEL2, NS is RES1 (R_GSWWH, I_DJJQJ). */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
24
+ value |= SCR_NS;
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
25
}
87
+ if (mode == STACK_LAZYFP) {
26
if (cpu_isar_feature(aa64_mte, cpu)) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
27
valid_mask |= SCR_ATA;
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
111
+ break;
112
+ case STACK_LAZYFP:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
114
+ break;
115
+ case STACK_IGNFAULTS:
116
+ break;
117
}
118
return false;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
121
uint32_t limit;
122
bool want_psp;
123
uint32_t sig;
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
125
126
if (dotailchain) {
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
129
*/
130
sig = v7m_integrity_sig(env, lr);
131
stacked_ok =
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
134
- ignore_faults) &&
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
136
- ignore_faults) &&
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
138
- ignore_faults) &&
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
140
- ignore_faults) &&
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
142
- ignore_faults) &&
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
144
- ignore_faults) &&
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
146
- ignore_faults) &&
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
148
- ignore_faults);
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
158
159
/* Update SP regardless of whether any of the stack accesses failed. */
160
*frame_sp_p = frameptr;
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
162
* if it has higher priority).
163
*/
164
stacked_ok = stacked_ok &&
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
175
+ mmu_idx, STACK_NORMAL) &&
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
177
+ mmu_idx, STACK_NORMAL) &&
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
179
+ mmu_idx, STACK_NORMAL) &&
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
181
+ mmu_idx, STACK_NORMAL) &&
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
183
+ mmu_idx, STACK_NORMAL) &&
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
185
+ mmu_idx, STACK_NORMAL) &&
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
187
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
189
/* FPU is active, try to save its registers */
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
191
faddr += 8; /* skip the slot for the FPSCR */
192
}
193
stacked_ok = stacked_ok &&
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
196
+ v7m_stack_write(cpu, faddr, slo,
197
+ mmu_idx, STACK_NORMAL) &&
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
208
--
28
--
209
2.20.1
29
2.34.1
210
211
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
function it is unconditionally set to match the current
4
security state whenever a floating point instruction is
5
executed.
6
2
7
Implement this by adding a new TB flag which tracks whether
3
This includes GPCCR, GPTBR, MFAR, the TLB flush insns PAALL, PAALLOS,
8
FPCCR.S is different from the current security state, so
4
RPALOS, RPAOS, and the cache flush insns CIPAPA and CIGDPAPA.
9
that we only need to emit the code to update it in the
10
less-common case when it is not already set correctly.
11
5
12
Note that we will add the handling for the other work done
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
by ExecuteFPCheck() in later commits.
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
8
Message-id: 20230620124418.805717-5-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
18
---
10
---
19
target/arm/cpu.h | 2 ++
11
target/arm/cpu.h | 19 ++++++++++
20
target/arm/translate.h | 1 +
12
target/arm/helper.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
21
target/arm/helper.c | 5 +++++
13
2 files changed, 103 insertions(+)
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
24
14
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
28
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
19
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
20
uint64_t fgt_read[2]; /* HFGRTR, HDFGRTR */
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
21
uint64_t fgt_write[2]; /* HFGWTR, HDFGWTR */
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
22
uint64_t fgt_exec[1]; /* HFGITR */
33
+/* For M profile only, set if FPCCR.S does not match current security state */
23
+
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
24
+ /* RME registers */
35
/* For M profile only, Handler (ie not Thread) mode */
25
+ uint64_t gpccr_el3;
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
26
+ uint64_t gptbr_el3;
37
/* For M profile only, whether we should generate stack-limit checks */
27
+ uint64_t mfar_el3;
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
28
} cp15;
39
index XXXXXXX..XXXXXXX 100644
29
40
--- a/target/arm/translate.h
30
struct {
41
+++ b/target/arm/translate.h
31
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
32
uint64_t reset_cbar;
43
bool v7m_handler_mode;
33
uint32_t reset_auxcr;
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
34
bool reset_hivecs;
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
35
+ uint8_t reset_l0gptsz;
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
36
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
37
/*
48
* so that top level loop can generate correct syndrome information.
38
* Intermediate values used during property parsing.
49
*/
39
@@ -XXX,XX +XXX,XX @@ FIELD(MVFR1, SIMDFMAC, 28, 4)
40
FIELD(MVFR2, SIMDMISC, 0, 4)
41
FIELD(MVFR2, FPMISC, 4, 4)
42
43
+FIELD(GPCCR, PPS, 0, 3)
44
+FIELD(GPCCR, IRGN, 8, 2)
45
+FIELD(GPCCR, ORGN, 10, 2)
46
+FIELD(GPCCR, SH, 12, 2)
47
+FIELD(GPCCR, PGS, 14, 2)
48
+FIELD(GPCCR, GPC, 16, 1)
49
+FIELD(GPCCR, GPCP, 17, 1)
50
+FIELD(GPCCR, L0GPTSZ, 20, 4)
51
+
52
+FIELD(MFAR, FPA, 12, 40)
53
+FIELD(MFAR, NSE, 62, 1)
54
+FIELD(MFAR, NS, 63, 1)
55
+
56
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
57
58
/* If adding a feature bit which corresponds to a Linux ELF
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
61
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
62
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
63
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo sme_reginfo[] = {
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
64
.access = PL2_RW, .accessfn = access_esm,
65
.type = ARM_CP_CONST, .resetvalue = 0 },
66
};
67
+
68
+static void tlbi_aa64_paall_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
+ uint64_t value)
70
+{
71
+ CPUState *cs = env_cpu(env);
72
+
73
+ tlb_flush(cs);
74
+}
75
+
76
+static void gpccr_write(CPUARMState *env, const ARMCPRegInfo *ri,
77
+ uint64_t value)
78
+{
79
+ /* L0GPTSZ is RO; other bits not mentioned are RES0. */
80
+ uint64_t rw_mask = R_GPCCR_PPS_MASK | R_GPCCR_IRGN_MASK |
81
+ R_GPCCR_ORGN_MASK | R_GPCCR_SH_MASK | R_GPCCR_PGS_MASK |
82
+ R_GPCCR_GPC_MASK | R_GPCCR_GPCP_MASK;
83
+
84
+ env->cp15.gpccr_el3 = (value & rw_mask) | (env->cp15.gpccr_el3 & ~rw_mask);
85
+}
86
+
87
+static void gpccr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
88
+{
89
+ env->cp15.gpccr_el3 = FIELD_DP64(0, GPCCR, L0GPTSZ,
90
+ env_archcpu(env)->reset_l0gptsz);
91
+}
92
+
93
+static void tlbi_aa64_paallos_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
+ uint64_t value)
95
+{
96
+ CPUState *cs = env_cpu(env);
97
+
98
+ tlb_flush_all_cpus_synced(cs);
99
+}
100
+
101
+static const ARMCPRegInfo rme_reginfo[] = {
102
+ { .name = "GPCCR_EL3", .state = ARM_CP_STATE_AA64,
103
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 6,
104
+ .access = PL3_RW, .writefn = gpccr_write, .resetfn = gpccr_reset,
105
+ .fieldoffset = offsetof(CPUARMState, cp15.gpccr_el3) },
106
+ { .name = "GPTBR_EL3", .state = ARM_CP_STATE_AA64,
107
+ .opc0 = 3, .opc1 = 6, .crn = 2, .crm = 1, .opc2 = 4,
108
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.gptbr_el3) },
109
+ { .name = "MFAR_EL3", .state = ARM_CP_STATE_AA64,
110
+ .opc0 = 3, .opc1 = 6, .crn = 6, .crm = 0, .opc2 = 5,
111
+ .access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mfar_el3) },
112
+ { .name = "TLBI_PAALL", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 7, .opc2 = 4,
114
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
115
+ .writefn = tlbi_aa64_paall_write },
116
+ { .name = "TLBI_PAALLOS", .state = ARM_CP_STATE_AA64,
117
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 1, .opc2 = 4,
118
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
119
+ .writefn = tlbi_aa64_paallos_write },
120
+ /*
121
+ * QEMU does not have a way to invalidate by physical address, thus
122
+ * invalidating a range of physical addresses is accomplished by
123
+ * flushing all tlb entries in the outer sharable domain,
124
+ * just like PAALLOS.
125
+ */
126
+ { .name = "TLBI_RPALOS", .state = ARM_CP_STATE_AA64,
127
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 7,
128
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
129
+ .writefn = tlbi_aa64_paallos_write },
130
+ { .name = "TLBI_RPAOS", .state = ARM_CP_STATE_AA64,
131
+ .opc0 = 1, .opc1 = 6, .crn = 8, .crm = 4, .opc2 = 3,
132
+ .access = PL3_W, .type = ARM_CP_NO_RAW,
133
+ .writefn = tlbi_aa64_paallos_write },
134
+ { .name = "DC_CIPAPA", .state = ARM_CP_STATE_AA64,
135
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 1,
136
+ .access = PL3_W, .type = ARM_CP_NOP },
137
+};
138
+
139
+static const ARMCPRegInfo rme_mte_reginfo[] = {
140
+ { .name = "DC_CIGDPAPA", .state = ARM_CP_STATE_AA64,
141
+ .opc0 = 1, .opc1 = 6, .crn = 7, .crm = 14, .opc2 = 5,
142
+ .access = PL3_W, .type = ARM_CP_NOP },
143
+};
144
#endif /* TARGET_AARCH64 */
145
146
static void define_pmu_regs(ARMCPU *cpu)
147
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
148
if (cpu_isar_feature(aa64_fgt, cpu)) {
149
define_arm_cp_regs(cpu, fgt_reginfo);
56
}
150
}
57
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
61
+ }
62
+
151
+
63
*pflags = flags;
152
+ if (cpu_isar_feature(aa64_rme, cpu)) {
64
*cs_base = 0;
153
+ define_arm_cp_regs(cpu, rme_reginfo);
65
}
154
+ if (cpu_isar_feature(aa64_mte, cpu)) {
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
155
+ define_arm_cp_regs(cpu, rme_mte_reginfo);
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
71
}
72
}
73
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
75
+ /* Handle M-profile lazy FP state mechanics */
76
+
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
78
+ if (s->v8m_fpccr_s_wrong) {
79
+ TCGv_i32 tmp;
80
+
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
82
+ if (s->v8m_secure) {
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
84
+ } else {
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
86
+ }
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
88
+ /* Don't need to do this for any further FP insns in this TB */
89
+ s->v8m_fpccr_s_wrong = false;
90
+ }
156
+ }
91
+ }
157
+ }
92
+
158
#endif
93
if (extract32(insn, 28, 4) == 0xf) {
159
94
/*
160
if (cpu_isar_feature(any_predinv, cpu)) {
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
98
regime_is_secure(env, dc->mmu_idx);
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
101
dc->cp_regs = cpu->cp_regs;
102
dc->features = env->features;
103
104
--
161
--
105
2.20.1
162
2.34.1
106
107
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Introduce both the enumeration and functions to retrieve
4
the current state, and state outside of EL3.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-6-richard.henderson@linaro.org
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: 20190416125744.27770-25-peter.maydell@linaro.org
6
---
10
---
7
target/arm/cpu.h | 2 +
11
target/arm/cpu.h | 89 ++++++++++++++++++++++++++++++++++-----------
8
target/arm/helper.h | 2 +
12
target/arm/helper.c | 60 ++++++++++++++++++++++++++++++
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 127 insertions(+), 22 deletions(-)
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
14
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
17
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_feature(CPUARMState *env, int feature)
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
20
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
21
void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp);
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
22
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
23
-#if !defined(CONFIG_USER_ONLY)
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
24
/*
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
25
+ * ARM v9 security states.
24
26
+ * The ordering of the enumeration corresponds to the low 2 bits
25
#define ARMV7M_EXCP_RESET 1
27
+ * of the GPI value, and (except for Root) the concat of NSE:NS.
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
28
+ */
27
index XXXXXXX..XXXXXXX 100644
29
+
28
--- a/target/arm/helper.h
30
+typedef enum ARMSecuritySpace {
29
+++ b/target/arm/helper.h
31
+ ARMSS_Secure = 0,
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
32
+ ARMSS_NonSecure = 1,
31
33
+ ARMSS_Root = 2,
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
34
+ ARMSS_Realm = 3,
33
35
+} ARMSecuritySpace;
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
36
+
35
+
37
+/* Return true if @space is secure, in the pre-v9 sense. */
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
38
+static inline bool arm_space_is_secure(ARMSecuritySpace space)
37
39
+{
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
40
+ return space == ARMSS_Secure || space == ARMSS_Root;
41
+}
42
+
43
+/* Return the ARMSecuritySpace for @secure, assuming !RME or EL[0-2]. */
44
+static inline ARMSecuritySpace arm_secure_to_space(bool secure)
45
+{
46
+ return secure ? ARMSS_Secure : ARMSS_NonSecure;
47
+}
48
+
49
+#if !defined(CONFIG_USER_ONLY)
50
+/**
51
+ * arm_security_space_below_el3:
52
+ * @env: cpu context
53
+ *
54
+ * Return the security space of exception levels below EL3, following
55
+ * an exception return to those levels. Unlike arm_security_space,
56
+ * this doesn't care about the current EL.
57
+ */
58
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env);
59
+
60
+/**
61
+ * arm_is_secure_below_el3:
62
+ * @env: cpu context
63
+ *
64
* Return true if exception levels below EL3 are in secure state,
65
- * or would be following an exception return to that level.
66
- * Unlike arm_is_secure() (which is always a question about the
67
- * _current_ state of the CPU) this doesn't care about the current
68
- * EL or mode.
69
+ * or would be following an exception return to those levels.
70
*/
71
static inline bool arm_is_secure_below_el3(CPUARMState *env)
72
{
73
- assert(!arm_feature(env, ARM_FEATURE_M));
74
- if (arm_feature(env, ARM_FEATURE_EL3)) {
75
- return !(env->cp15.scr_el3 & SCR_NS);
76
- } else {
77
- /* If EL3 is not supported then the secure state is implementation
78
- * defined, in which case QEMU defaults to non-secure.
79
- */
80
- return false;
81
- }
82
+ ARMSecuritySpace ss = arm_security_space_below_el3(env);
83
+ return ss == ARMSS_Secure;
84
}
85
86
/* Return true if the CPU is AArch64 EL3 or AArch32 Mon */
87
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el3_or_mon(CPUARMState *env)
88
return false;
89
}
90
91
-/* Return true if the processor is in secure state */
92
+/**
93
+ * arm_security_space:
94
+ * @env: cpu context
95
+ *
96
+ * Return the current security space of the cpu.
97
+ */
98
+ARMSecuritySpace arm_security_space(CPUARMState *env);
99
+
100
+/**
101
+ * arm_is_secure:
102
+ * @env: cpu context
103
+ *
104
+ * Return true if the processor is in secure state.
105
+ */
106
static inline bool arm_is_secure(CPUARMState *env)
107
{
108
- if (arm_feature(env, ARM_FEATURE_M)) {
109
- return env->v7m.secure;
110
- }
111
- if (arm_is_el3_or_mon(env)) {
112
- return true;
113
- }
114
- return arm_is_secure_below_el3(env);
115
+ return arm_space_is_secure(arm_security_space(env));
116
}
117
118
/*
119
@@ -XXX,XX +XXX,XX @@ static inline bool arm_is_el2_enabled(CPUARMState *env)
120
}
121
122
#else
123
+static inline ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
124
+{
125
+ return ARMSS_NonSecure;
126
+}
127
+
128
static inline bool arm_is_secure_below_el3(CPUARMState *env)
129
{
130
return false;
131
}
132
133
+static inline ARMSecuritySpace arm_security_space(CPUARMState *env)
134
+{
135
+ return ARMSS_NonSecure;
136
+}
137
+
138
static inline bool arm_is_secure(CPUARMState *env)
139
{
140
return false;
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
141
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
142
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
143
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
144
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
145
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_change_el(CPUARMState *env, int old_el,
44
g_assert_not_reached();
45
}
46
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
48
+{
49
+ /* translate.c should never generate calls here in user-only mode */
50
+ g_assert_not_reached();
51
+}
52
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
54
{
55
/* The TT instructions can be used by unprivileged code, but in
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
57
}
146
}
58
}
147
}
59
148
#endif
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
149
+
61
+{
150
+#ifndef CONFIG_USER_ONLY
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
151
+ARMSecuritySpace arm_security_space(CPUARMState *env)
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
152
+{
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
153
+ if (arm_feature(env, ARM_FEATURE_M)) {
65
+
154
+ return arm_secure_to_space(env->v7m.secure);
66
+ assert(env->v7m.secure);
67
+
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
69
+ return;
70
+ }
71
+
72
+ /* Check access to the coprocessor is permitted */
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
155
+ }
85
+
156
+
86
+ /*
157
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
158
+ * If EL3 is not supported then the secure state is implementation
88
+ * accesses should not set the FSR bits for stacking errors if they
159
+ * defined, in which case QEMU defaults to non-secure.
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
160
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
161
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
162
+ return ARMSS_NonSecure;
95
+ int i;
163
+ }
96
+
164
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
165
+ /* Check for AArch64 EL3 or AArch32 Mon. */
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
166
+ if (is_a64(env)) {
99
+ uint32_t faddr = fptr + 4 * i;
167
+ if (extract32(env->pstate, 2, 2) == 3) {
100
+ uint32_t slo = extract64(dn, 0, 32);
168
+ if (cpu_isar_feature(aa64_rme, env_archcpu(env))) {
101
+ uint32_t shi = extract64(dn, 32, 32);
169
+ return ARMSS_Root;
102
+
170
+ } else {
103
+ if (i >= 16) {
171
+ return ARMSS_Secure;
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
172
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
173
+ }
121
+ } else {
174
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
175
+ if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {
123
+ }
176
+ return ARMSS_Secure;
124
+
177
+ }
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
178
+ }
126
+}
179
+
127
+
180
+ return arm_security_space_below_el3(env);
128
static bool v7m_push_stack(ARMCPU *cpu)
181
+}
129
{
182
+
130
/* Do the "set up stack frame" part of exception entry,
183
+ARMSecuritySpace arm_security_space_below_el3(CPUARMState *env)
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
184
+{
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
185
+ assert(!arm_feature(env, ARM_FEATURE_M));
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
186
+
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
187
+ /*
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
188
+ * If EL3 is not supported then the secure state is implementation
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
189
+ * defined, in which case QEMU defaults to non-secure.
137
};
190
+ */
138
191
+ if (!arm_feature(env, ARM_FEATURE_EL3)) {
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
192
+ return ARMSS_NonSecure;
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
193
+ }
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
194
+
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
195
+ /*
143
break;
196
+ * Note NSE cannot be set without RME, and NSE & !NS is Reserved.
144
+ case EXCP_LSERR:
197
+ * Ignoring NSE when !NS retains consistency without having to
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
198
+ * modify other predicates.
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
199
+ */
147
+ break;
200
+ if (!(env->cp15.scr_el3 & SCR_NS)) {
148
+ case EXCP_UNALIGNED:
201
+ return ARMSS_Secure;
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
202
+ } else if (env->cp15.scr_el3 & SCR_NSE) {
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
203
+ return ARMSS_Realm;
151
+ break;
204
+ } else {
152
case EXCP_SWI:
205
+ return ARMSS_NonSecure;
153
/* The PC already points to the next instruction. */
206
+ }
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
207
+}
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
208
+#endif /* !CONFIG_USER_ONLY */
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
181
--
209
--
182
2.20.1
210
2.34.1
183
184
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This commit finally deletes "hw/devices.h".
3
We will need 2 bits to represent ARMSecurityState.
4
4
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Do not attempt to replace or widen secure, even though it
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
logically overlaps the new field -- there are uses within
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
7
e.g. hw/block/pflash_cfi01.c, which don't know anything
8
specific about ARM.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20230620124418.805717-7-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
include/hw/devices.h | 11 -----------
15
include/exec/memattrs.h | 9 ++++++++-
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
16
1 file changed, 8 insertions(+), 1 deletion(-)
12
hw/arm/gumstix.c | 2 +-
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
21
17
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h
23
deleted file mode 100644
24
index XXXXXXX..XXXXXXX
25
--- a/include/hw/devices.h
26
+++ /dev/null
27
@@ -XXX,XX +XXX,XX @@
28
-#ifndef QEMU_DEVICES_H
29
-#define QEMU_DEVICES_H
30
-
31
-/* Devices that have nowhere better to go. */
32
-
33
-#include "hw/hw.h"
34
-
35
-/* smc91c111.c */
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
37
-
38
-#endif
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
57
+
58
+#include "hw/irq.h"
59
+#include "net/net.h"
60
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
62
+
63
+#endif
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
65
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
20
--- a/include/exec/memattrs.h
67
+++ b/hw/arm/gumstix.c
21
+++ b/include/exec/memattrs.h
68
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct MemTxAttrs {
69
#include "hw/arm/pxa.h"
23
* "didn't specify" if necessary.
70
#include "net/net.h"
24
*/
71
#include "hw/block/flash.h"
25
unsigned int unspecified:1;
72
-#include "hw/devices.h"
26
- /* ARM/AMBA: TrustZone Secure access
73
+#include "hw/net/smc91c111.h"
27
+ /*
74
#include "hw/boards.h"
28
+ * ARM/AMBA: TrustZone Secure access
75
#include "exec/address-spaces.h"
29
* x86: System Management Mode access
76
#include "sysemu/qtest.h"
30
*/
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
31
unsigned int secure:1;
78
index XXXXXXX..XXXXXXX 100644
32
+ /*
79
--- a/hw/arm/integratorcp.c
33
+ * ARM: ArmSecuritySpace. This partially overlaps secure, but it is
80
+++ b/hw/arm/integratorcp.c
34
+ * easier to have both fields to assist code that does not understand
81
@@ -XXX,XX +XXX,XX @@
35
+ * ARMv9 RME, or no specific knowledge of ARM at all (e.g. pflash).
82
#include "qemu-common.h"
36
+ */
83
#include "cpu.h"
37
+ unsigned int space:2;
84
#include "hw/sysbus.h"
38
/* Memory access is usermode (unprivileged) */
85
-#include "hw/devices.h"
39
unsigned int user:1;
86
#include "hw/boards.h"
40
/*
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
140
#include "net/net.h"
141
-#include "hw/devices.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
144
/* For crc32 */
145
#include <zlib.h>
146
--
41
--
147
2.20.1
42
2.34.1
148
149
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
From: Richard Henderson <richard.henderson@linaro.org>
2
been used since commit c1e3781090b9d36c60 in 2015, when we
3
started passing the entire MMU index in the TB flags rather
4
than just a 'privilege level' bit.
5
2
6
This rearrangement is not strictly necessary, but means that
3
It will be helpful to have ARMMMUIdx_Phys_* to be in the same
7
we can put M-profile-only bits next to each other rather
4
relative order as ARMSecuritySpace enumerators. This requires
8
than scattered across the flag word.
5
the adjustment to the nstable check. While there, check for being
6
in secure state rather than rely on clearing the low bit making
7
no change to non-secure state.
9
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-8-richard.henderson@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: 20190416125744.27770-17-peter.maydell@linaro.org
13
---
13
---
14
target/arm/cpu.h | 11 ++++++-----
14
target/arm/cpu.h | 12 ++++++------
15
1 file changed, 6 insertions(+), 5 deletions(-)
15
target/arm/ptw.c | 12 +++++-------
16
2 files changed, 11 insertions(+), 13 deletions(-)
16
17
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
ARMMMUIdx_E2 = 6 | ARM_MMU_IDX_A,
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
ARMMMUIdx_E3 = 7 | ARM_MMU_IDX_A,
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
25
+/*
26
- /* TLBs with 1-1 mapping to the physical address spaces. */
26
+ * Indicates whether cp register reads and writes by guest code should access
27
- ARMMMUIdx_Phys_NS = 8 | ARM_MMU_IDX_A,
27
+ * the secure or nonsecure bank of banked registers; note that this is not
28
- ARMMMUIdx_Phys_S = 9 | ARM_MMU_IDX_A,
28
+ * the same thing as the current security state of the processor!
29
-
29
+ */
30
/*
30
+FIELD(TBFLAG_A32, NS, 6, 1)
31
* Used for second stage of an S12 page table walk, or for descriptor
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
32
* loads during first stage of an S1 page table walk. Note that both
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
* are in use simultaneously for SecureEL2: the security state for
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
* the S2 ptw is selected by the NS bit from the S1 ptw.
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
*/
35
* checks on the other bits at runtime
36
- ARMMMUIdx_Stage2 = 10 | ARM_MMU_IDX_A,
36
*/
37
- ARMMMUIdx_Stage2_S = 11 | ARM_MMU_IDX_A,
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
+ ARMMMUIdx_Stage2_S = 8 | ARM_MMU_IDX_A,
38
-/* Indicates whether cp register reads and writes by guest code should access
39
+ ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
+
40
- * the same thing as the current security state of the processor!
41
+ /* TLBs with 1-1 mapping to the physical address spaces. */
41
- */
42
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
43
/* For M profile only, Handler (ie not Thread) mode */
44
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/*
45
/* For M profile only, whether we should generate stack-limit checks */
46
* These are not allocated TLBs and are used only for AT system
47
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/ptw.c
50
+++ b/target/arm/ptw.c
51
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
52
descaddr |= (address >> (stride * (4 - level))) & indexmask;
53
descaddr &= ~7ULL;
54
nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
55
- if (nstable) {
56
+ if (nstable && ptw->in_secure) {
57
/*
58
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
59
- * Assert that the non-secure idx are even, and relative order.
60
+ * Assert the relative order of the secure/non-secure indexes.
61
*/
62
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Phys_NS & 1) != 0);
63
- QEMU_BUILD_BUG_ON((ARMMMUIdx_Stage2 & 1) != 0);
64
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS + 1 != ARMMMUIdx_Phys_S);
65
- QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2 + 1 != ARMMMUIdx_Stage2_S);
66
- ptw->in_ptw_idx &= ~1;
67
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_S + 1 != ARMMMUIdx_Phys_NS);
68
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
+ ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
}
72
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
46
--
73
--
47
2.20.1
74
2.34.1
48
49
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
From: Richard Henderson <richard.henderson@linaro.org>
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
2
3
With FEAT_RME, there are four physical address spaces.
4
For now, just define the symbols, and mention them in
5
the same spots as the other Phys indexes in ptw.c.
6
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
8
---
12
---
9
target/arm/cpu.h | 14 +++++++++
13
target/arm/cpu.h | 23 +++++++++++++++++++++--
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
14
target/arm/ptw.c | 10 ++++++++--
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
15
2 files changed, 29 insertions(+), 4 deletions(-)
12
3 files changed, 114 insertions(+), 1 deletion(-)
13
16
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
21
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
22
ARMMMUIdx_Stage2 = 9 | ARM_MMU_IDX_A,
20
*/
23
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
24
/* TLBs with 1-1 mapping to the physical address spaces. */
22
+/**
25
- ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
26
- ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
24
+ * @opaque: the NVIC
27
+ ARMMMUIdx_Phys_S = 10 | ARM_MMU_IDX_A,
25
+ * @irq: the exception number to mark pending
28
+ ARMMMUIdx_Phys_NS = 11 | ARM_MMU_IDX_A,
26
+ * @secure: false for non-banked exceptions or for the nonsecure
29
+ ARMMMUIdx_Phys_Root = 12 | ARM_MMU_IDX_A,
27
+ * version of a banked exception, true for the secure version of a banked
30
+ ARMMMUIdx_Phys_Realm = 13 | ARM_MMU_IDX_A,
28
+ * exception.
31
29
+ *
32
/*
30
+ * Return whether an exception is "ready", i.e. whether the exception is
33
* These are not allocated TLBs and are used only for AT system
31
+ * enabled and is configured at a priority which would allow it to
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMASIdx {
32
+ * interrupt the current execution priority. This controls whether the
35
ARMASIdx_TagS = 3,
33
+ * RDY bit for it in the FPCCR is set.
36
} ARMASIdx;
34
+ */
37
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
38
+static inline ARMMMUIdx arm_space_to_phys(ARMSecuritySpace space)
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
44
return ret;
45
}
46
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
48
+{
39
+{
49
+ /*
40
+ /* Assert the relative order of the physical mmu indexes. */
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
41
+ QEMU_BUILD_BUG_ON(ARMSS_Secure != 0);
51
+ * configured at a priority which would allow it to interrupt the
42
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_NS != ARMMMUIdx_Phys_S + ARMSS_NonSecure);
52
+ * current execution priority.
43
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Root != ARMMMUIdx_Phys_S + ARMSS_Root);
53
+ *
44
+ QEMU_BUILD_BUG_ON(ARMMMUIdx_Phys_Realm != ARMMMUIdx_Phys_S + ARMSS_Realm);
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
55
+ * for non-banked exceptions secure is always false; for banked exceptions
56
+ * it indicates which of the exceptions is required.
57
+ */
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
45
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
46
+ return ARMMMUIdx_Phys_S + space;
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
47
+}
80
+
48
+
81
/* callback when external interrupt line is changed */
49
+static inline ARMSecuritySpace arm_phys_to_space(ARMMMUIdx idx)
82
static void set_irq_level(void *opaque, int n, int level)
83
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
94
+{
50
+{
95
+ /*
51
+ assert(idx >= ARMMMUIdx_Phys_S && idx <= ARMMMUIdx_Phys_Realm);
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
52
+ return idx - ARMMMUIdx_Phys_S;
97
+ * that we will need later in order to do lazy FP reg stacking.
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
123
+
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
125
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
53
+}
156
+
54
+
157
static bool v7m_push_stack(ARMCPU *cpu)
55
static inline bool arm_v7m_csselr_razwi(ARMCPU *cpu)
158
{
56
{
159
/* Do the "set up stack frame" part of exception entry,
57
/* If all the CLIDR.Ctypem bits are 0 there are no caches, and
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
58
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
161
}
59
index XXXXXXX..XXXXXXX 100644
162
} else {
60
--- a/target/arm/ptw.c
163
/* Lazy stacking enabled, save necessary info to stack later */
61
+++ b/target/arm/ptw.c
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
62
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
63
case ARMMMUIdx_E3:
166
}
64
break;
167
}
65
168
}
66
- case ARMMMUIdx_Phys_NS:
67
case ARMMMUIdx_Phys_S:
68
+ case ARMMMUIdx_Phys_NS:
69
+ case ARMMMUIdx_Phys_Root:
70
+ case ARMMMUIdx_Phys_Realm:
71
/* No translation for physical address spaces. */
72
return true;
73
74
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
75
switch (mmu_idx) {
76
case ARMMMUIdx_Stage2:
77
case ARMMMUIdx_Stage2_S:
78
- case ARMMMUIdx_Phys_NS:
79
case ARMMMUIdx_Phys_S:
80
+ case ARMMMUIdx_Phys_NS:
81
+ case ARMMMUIdx_Phys_Root:
82
+ case ARMMMUIdx_Phys_Realm:
83
break;
84
85
default:
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
87
switch (mmu_idx) {
88
case ARMMMUIdx_Phys_S:
89
case ARMMMUIdx_Phys_NS:
90
+ case ARMMMUIdx_Phys_Root:
91
+ case ARMMMUIdx_Phys_Realm:
92
/* Checking Phys early avoids special casing later vs regime_el. */
93
return get_phys_addr_disabled(env, address, access_type, mmu_idx,
94
is_secure, result, fi);
169
--
95
--
170
2.20.1
96
2.34.1
171
97
172
98
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
This was added in 7e98e21c098 as part of a reorg in which
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
one of the argument had been legally NULL, and this caught
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
5
actual instances. Now that the reorg is complete, this
6
serves little purpose.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20230620124418.805717-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
include/hw/net/lan9118.h | 2 ++
14
target/arm/ptw.c | 6 ++----
9
hw/arm/exynos4_boards.c | 3 ++-
15
1 file changed, 2 insertions(+), 4 deletions(-)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
13
16
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
17
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
19
--- a/target/arm/ptw.c
17
+++ b/include/hw/net/lan9118.h
20
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
#include "hw/irq.h"
22
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
20
#include "net/net.h"
23
uint64_t address,
21
24
MMUAccessType access_type, bool s1_is_el0,
22
+#define TYPE_LAN9118 "lan9118"
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
23
+
26
- __attribute__((nonnull));
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
27
+ GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
25
28
26
#endif
29
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
30
target_ulong address,
28
index XXXXXXX..XXXXXXX 100644
31
MMUAccessType access_type,
29
--- a/hw/arm/exynos4_boards.c
32
GetPhysAddrResult *result,
30
+++ b/hw/arm/exynos4_boards.c
33
- ARMMMUFaultInfo *fi)
31
@@ -XXX,XX +XXX,XX @@
34
- __attribute__((nonnull));
32
#include "hw/arm/arm.h"
35
+ ARMMMUFaultInfo *fi);
33
#include "exec/address-spaces.h"
36
34
#include "hw/arm/exynos4210.h"
37
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
35
+#include "hw/net/lan9118.h"
38
static const uint8_t pamax_map[] = {
36
#include "hw/boards.h"
37
38
#undef DEBUG
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
40
/* This should be a 9215 but the 9118 is close enough */
41
if (nd_table[0].used) {
42
qemu_check_nic_model(&nd_table[0], "lan9118");
43
- dev = qdev_create(NULL, "lan9118");
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
45
qdev_set_nic_properties(dev, &nd_table[0]);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
47
qdev_init_nofail(dev);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
51
+++ b/hw/arm/mps2-tz.c
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/arm/armsse.h"
54
#include "hw/dma/pl080.h"
55
#include "hw/ssi/pl022.h"
56
+#include "hw/net/lan9118.h"
57
#include "net/net.h"
58
#include "hw/core/split-irq.h"
59
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
61
* except that it doesn't support the checksum-offload feature.
62
*/
63
qemu_check_nic_model(nd, "lan9118");
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
66
qdev_set_nic_properties(mms->lan9118, nd);
67
qdev_init_nofail(mms->lan9118);
68
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
72
+++ b/hw/net/lan9118.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
74
}
75
};
76
77
-#define TYPE_LAN9118 "lan9118"
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
79
80
typedef struct {
81
--
39
--
82
2.20.1
40
2.34.1
83
41
84
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Add input and output space members to S1Translate. Set and adjust
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
them in S1_ptw_translate, and the various points at which we drop
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
secure state. Initialize the space in get_phys_addr; for now leave
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
get_phys_addr_with_secure considering only secure vs non-secure spaces.
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
12
---
10
hw/arm/aspeed.c | 13 +++++++++----
13
target/arm/ptw.c | 86 +++++++++++++++++++++++++++++++++++++++---------
11
1 file changed, 9 insertions(+), 4 deletions(-)
14
1 file changed, 71 insertions(+), 15 deletions(-)
12
15
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
18
--- a/target/arm/ptw.c
16
+++ b/hw/arm/aspeed.c
19
+++ b/target/arm/ptw.c
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
18
#include "hw/arm/aspeed_soc.h"
21
typedef struct S1Translate {
19
#include "hw/boards.h"
22
ARMMMUIdx in_mmu_idx;
20
#include "hw/i2c/smbus_eeprom.h"
23
ARMMMUIdx in_ptw_idx;
21
+#include "hw/misc/pca9552.h"
24
+ ARMSecuritySpace in_space;
22
+#include "hw/misc/tmp105.h"
25
bool in_secure;
23
#include "qemu/log.h"
26
bool in_debug;
24
#include "sysemu/block-backend.h"
27
bool out_secure;
25
#include "hw/loader.h"
28
bool out_rw;
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
29
bool out_be;
27
eeprom_buf);
30
+ ARMSecuritySpace out_space;
28
31
hwaddr out_virt;
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
32
hwaddr out_phys;
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
33
void *out_host;
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
34
@@ -XXX,XX +XXX,XX @@ static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
32
+ TYPE_TMP105, 0x4d);
35
static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
33
36
hwaddr addr, ARMMMUFaultInfo *fi)
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
37
{
35
* plugged on the I2C bus header */
38
+ ARMSecuritySpace space = ptw->in_space;
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
39
bool is_secure = ptw->in_secure;
37
AspeedSoCState *soc = &bmc->soc;
40
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
41
ARMMMUIdx s2_mmu_idx = ptw->in_ptw_idx;
39
42
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
43
.in_mmu_idx = s2_mmu_idx,
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
44
.in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
42
+ 0x60);
45
.in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
43
46
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
47
+ : space == ARMSS_Realm ? ARMSS_Realm
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
48
+ : ARMSS_NonSecure),
46
49
.in_debug = true,
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
50
};
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
51
GetPhysAddrResult s2 = { };
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
52
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
50
+ 0x4a);
53
ptw->out_phys = s2.f.phys_addr;
51
54
pte_attrs = s2.cacheattrs.attrs;
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
55
ptw->out_secure = s2.f.attrs.secure;
53
* good enough */
56
+ ptw->out_space = s2.f.attrs.space;
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
57
} else {
55
58
/* Regime is physical. */
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
59
ptw->out_phys = addr;
57
eeprom_buf);
60
pte_attrs = 0;
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
61
ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
62
+ ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
60
0x60);
63
+ : space == ARMSS_Realm ? ARMSS_Realm
64
+ : ARMSS_NonSecure);
65
}
66
ptw->out_host = NULL;
67
ptw->out_rw = false;
68
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
69
ptw->out_rw = full->prot & PAGE_WRITE;
70
pte_attrs = full->pte_attrs;
71
ptw->out_secure = full->attrs.secure;
72
+ ptw->out_space = full->attrs.space;
73
#else
74
g_assert_not_reached();
75
#endif
76
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUARMState *env, S1Translate *ptw,
77
}
78
} else {
79
/* Page tables are in MMIO. */
80
- MemTxAttrs attrs = { .secure = ptw->out_secure };
81
+ MemTxAttrs attrs = {
82
+ .secure = ptw->out_secure,
83
+ .space = ptw->out_space,
84
+ };
85
AddressSpace *as = arm_addressspace(cs, attrs);
86
MemTxResult result = MEMTX_OK;
87
88
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUARMState *env, S1Translate *ptw,
89
#endif
90
} else {
91
/* Page tables are in MMIO. */
92
- MemTxAttrs attrs = { .secure = ptw->out_secure };
93
+ MemTxAttrs attrs = {
94
+ .secure = ptw->out_secure,
95
+ .space = ptw->out_space,
96
+ };
97
AddressSpace *as = arm_addressspace(cs, attrs);
98
MemTxResult result = MEMTX_OK;
99
100
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, S1Translate *ptw,
101
* regime, because the attribute will already be non-secure.
102
*/
103
result->f.attrs.secure = false;
104
+ result->f.attrs.space = ARMSS_NonSecure;
105
}
106
result->f.phys_addr = phys_addr;
107
return false;
108
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
109
* regime, because the attribute will already be non-secure.
110
*/
111
result->f.attrs.secure = false;
112
+ result->f.attrs.space = ARMSS_NonSecure;
113
}
114
115
if (regime_is_stage2(mmu_idx)) {
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
117
*/
118
if (sattrs.ns) {
119
result->f.attrs.secure = false;
120
+ result->f.attrs.space = ARMSS_NonSecure;
121
} else if (!secure) {
122
/*
123
* NS access to S memory must fault.
124
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
125
bool is_secure = ptw->in_secure;
126
bool ret, ipa_secure;
127
ARMCacheAttrs cacheattrs1;
128
+ ARMSecuritySpace ipa_space;
129
bool is_el0;
130
uint64_t hcr;
131
132
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
133
134
ipa = result->f.phys_addr;
135
ipa_secure = result->f.attrs.secure;
136
+ ipa_space = result->f.attrs.space;
137
138
is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
139
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
140
ptw->in_secure = ipa_secure;
141
+ ptw->in_space = ipa_space;
142
ptw->in_ptw_idx = ptw_idx_for_stage_2(env, ptw->in_mmu_idx);
143
144
/*
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
146
ARMMMUIdx s1_mmu_idx;
147
148
/*
149
- * The page table entries may downgrade secure to non-secure, but
150
- * cannot upgrade an non-secure translation regime's attributes
151
- * to secure.
152
+ * The page table entries may downgrade Secure to NonSecure, but
153
+ * cannot upgrade a NonSecure translation regime's attributes
154
+ * to Secure or Realm.
155
*/
156
result->f.attrs.secure = is_secure;
157
+ result->f.attrs.space = ptw->in_space;
158
159
switch (mmu_idx) {
160
case ARMMMUIdx_Phys_S:
161
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
162
163
default:
164
/* Single stage uses physical for ptw. */
165
- ptw->in_ptw_idx = is_secure ? ARMMMUIdx_Phys_S : ARMMMUIdx_Phys_NS;
166
+ ptw->in_ptw_idx = arm_space_to_phys(ptw->in_space);
167
break;
168
}
169
170
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
171
S1Translate ptw = {
172
.in_mmu_idx = mmu_idx,
173
.in_secure = is_secure,
174
+ .in_space = arm_secure_to_space(is_secure),
175
};
176
return get_phys_addr_with_struct(env, &ptw, address, access_type,
177
result, fi);
178
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
179
MMUAccessType access_type, ARMMMUIdx mmu_idx,
180
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
181
{
182
- bool is_secure;
183
+ S1Translate ptw = {
184
+ .in_mmu_idx = mmu_idx,
185
+ };
186
+ ARMSecuritySpace ss;
187
188
switch (mmu_idx) {
189
case ARMMMUIdx_E10_0:
190
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
191
case ARMMMUIdx_Stage1_E1:
192
case ARMMMUIdx_Stage1_E1_PAN:
193
case ARMMMUIdx_E2:
194
- is_secure = arm_is_secure_below_el3(env);
195
+ ss = arm_security_space_below_el3(env);
196
break;
197
case ARMMMUIdx_Stage2:
198
+ /*
199
+ * For Secure EL2, we need this index to be NonSecure;
200
+ * otherwise this will already be NonSecure or Realm.
201
+ */
202
+ ss = arm_security_space_below_el3(env);
203
+ if (ss == ARMSS_Secure) {
204
+ ss = ARMSS_NonSecure;
205
+ }
206
+ break;
207
case ARMMMUIdx_Phys_NS:
208
case ARMMMUIdx_MPrivNegPri:
209
case ARMMMUIdx_MUserNegPri:
210
case ARMMMUIdx_MPriv:
211
case ARMMMUIdx_MUser:
212
- is_secure = false;
213
+ ss = ARMSS_NonSecure;
214
break;
215
- case ARMMMUIdx_E3:
216
case ARMMMUIdx_Stage2_S:
217
case ARMMMUIdx_Phys_S:
218
case ARMMMUIdx_MSPrivNegPri:
219
case ARMMMUIdx_MSUserNegPri:
220
case ARMMMUIdx_MSPriv:
221
case ARMMMUIdx_MSUser:
222
- is_secure = true;
223
+ ss = ARMSS_Secure;
224
+ break;
225
+ case ARMMMUIdx_E3:
226
+ if (arm_feature(env, ARM_FEATURE_AARCH64) &&
227
+ cpu_isar_feature(aa64_rme, env_archcpu(env))) {
228
+ ss = ARMSS_Root;
229
+ } else {
230
+ ss = ARMSS_Secure;
231
+ }
232
+ break;
233
+ case ARMMMUIdx_Phys_Root:
234
+ ss = ARMSS_Root;
235
+ break;
236
+ case ARMMMUIdx_Phys_Realm:
237
+ ss = ARMSS_Realm;
238
break;
239
default:
240
g_assert_not_reached();
241
}
242
- return get_phys_addr_with_secure(env, address, access_type, mmu_idx,
243
- is_secure, result, fi);
244
+
245
+ ptw.in_space = ss;
246
+ ptw.in_secure = arm_space_is_secure(ss);
247
+ return get_phys_addr_with_struct(env, &ptw, address, access_type,
248
+ result, fi);
61
}
249
}
62
250
251
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
252
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
253
{
254
ARMCPU *cpu = ARM_CPU(cs);
255
CPUARMState *env = &cpu->env;
256
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
257
+ ARMSecuritySpace ss = arm_security_space(env);
258
S1Translate ptw = {
259
- .in_mmu_idx = arm_mmu_idx(env),
260
- .in_secure = arm_is_secure(env),
261
+ .in_mmu_idx = mmu_idx,
262
+ .in_space = ss,
263
+ .in_secure = arm_space_is_secure(ss),
264
.in_debug = true,
265
};
266
GetPhysAddrResult res = {};
63
--
267
--
64
2.20.1
268
2.34.1
65
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Test in_space instead of in_secure so that we don't
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
switch out of Root space.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-12-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
11
target/arm/ptw.c | 28 ++++++++++++++--------------
10
1 file changed, 6 insertions(+)
12
1 file changed, 14 insertions(+), 14 deletions(-)
11
13
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
16
--- a/target/arm/ptw.c
15
+++ b/include/hw/net/ne2000-isa.h
17
+++ b/target/arm/ptw.c
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
19
{
18
* See the COPYING file in the top-level directory.
20
ARMCPU *cpu = env_archcpu(env);
19
*/
21
ARMMMUIdx mmu_idx = ptw->in_mmu_idx;
22
- bool is_secure = ptw->in_secure;
23
int32_t level;
24
ARMVAParameters param;
25
uint64_t ttbr;
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
27
uint64_t descaddrmask;
28
bool aarch64 = arm_el_is_aa64(env, el);
29
uint64_t descriptor, new_descriptor;
30
- bool nstable;
31
32
/* TODO: This code does not support shareability levels. */
33
if (aarch64) {
34
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
35
descaddrmask = MAKE_64BIT_MASK(0, 40);
36
}
37
descaddrmask &= ~indexmask_grainsize;
38
-
39
- /*
40
- * Secure stage 1 accesses start with the page table in secure memory and
41
- * can be downgraded to non-secure at any step. Non-secure accesses
42
- * remain non-secure. We implement this by just ORing in the NSTable/NS
43
- * bits at each step.
44
- * Stage 2 never gets this kind of downgrade.
45
- */
46
- tableattrs = is_secure ? 0 : (1 << 4);
47
+ tableattrs = 0;
48
49
next_level:
50
descaddr |= (address >> (stride * (4 - level))) & indexmask;
51
descaddr &= ~7ULL;
52
- nstable = !regime_is_stage2(mmu_idx) && extract32(tableattrs, 4, 1);
53
- if (nstable && ptw->in_secure) {
20
+
54
+
21
+#ifndef HW_NET_NE2K_ISA_H
55
+ /*
22
+#define HW_NET_NE2K_ISA_H
56
+ * Process the NSTable bit from the previous level. This changes
57
+ * the table address space and the output space from Secure to
58
+ * NonSecure. With RME, the EL3 translation regime does not change
59
+ * from Root to NonSecure.
60
+ */
61
+ if (ptw->in_space == ARMSS_Secure
62
+ && !regime_is_stage2(mmu_idx)
63
+ && extract32(tableattrs, 4, 1)) {
64
/*
65
* Stage2_S -> Stage2 or Phys_S -> Phys_NS
66
* Assert the relative order of the secure/non-secure indexes.
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
68
QEMU_BUILD_BUG_ON(ARMMMUIdx_Stage2_S + 1 != ARMMMUIdx_Stage2);
69
ptw->in_ptw_idx += 1;
70
ptw->in_secure = false;
71
+ ptw->in_space = ARMSS_NonSecure;
72
}
23
+
73
+
24
#include "hw/hw.h"
74
if (!S1_ptw_translate(env, ptw, descaddr, fi)) {
25
#include "hw/qdev.h"
75
goto do_fault;
26
#include "hw/isa/isa.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
76
}
29
return d;
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
30
}
78
*/
31
+
79
attrs = new_descriptor & (MAKE_64BIT_MASK(2, 10) | MAKE_64BIT_MASK(50, 14));
32
+#endif
80
if (!regime_is_stage2(mmu_idx)) {
81
- attrs |= nstable << 5; /* NS */
82
+ attrs |= !ptw->in_secure << 5; /* NS */
83
if (!param.hpd) {
84
attrs |= extract64(tableattrs, 0, 2) << 53; /* XN, PXN */
85
/*
33
--
86
--
34
2.20.1
87
2.34.1
35
36
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
From: Richard Henderson <richard.henderson@linaro.org>
2
bit to gate floating point; so always set the VFPEN TB flag.
3
2
4
M-profile also has CPACR and NSACR similar to A-profile;
3
With Realm security state, bit 55 of a block or page descriptor during
5
they behave slightly differently:
4
the stage2 walk becomes the NS bit; during the stage1 walk the bit 5
6
* the CPACR is banked between Secure and Non-Secure
5
NS bit is RES0. With Root security state, bit 11 of the block or page
7
* if the NSACR forces a trap then this is taken to
6
descriptor during the stage1 walk becomes the NSE bit.
8
the Secure state, not the Non-Secure state
9
7
10
Honour the CPACR and NSACR settings. The NSACR handling
8
Rather than collecting an NS bit and applying it later, compute the
11
requires us to borrow the exception.target_el field
9
output pa space from the input pa space and unconditionally assign.
12
(usually meaningless for M profile) to distinguish the
10
This means that we no longer need to adjust the output space earlier
13
NOCP UsageFault taken to Secure state from the more
11
for the NSTable bit.
14
usual fault taken to the current security state.
15
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20230620124418.805717-13-richard.henderson@linaro.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
19
---
17
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
18
target/arm/ptw.c | 89 +++++++++++++++++++++++++++++++++++++++---------
21
target/arm/translate.c | 10 ++++++--
19
1 file changed, 73 insertions(+), 16 deletions(-)
22
2 files changed, 60 insertions(+), 5 deletions(-)
23
20
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
23
--- a/target/arm/ptw.c
27
+++ b/target/arm/helper.c
24
+++ b/target/arm/ptw.c
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
25
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
29
return target_el;
26
* @mmu_idx: MMU index indicating required translation regime
30
}
27
* @is_aa64: TRUE if AArch64
31
28
* @ap: The 2-bit simple AP (AP[2:1])
32
+/*
29
- * @ns: NS (non-secure) bit
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
30
* @xn: XN (execute-never) bit
34
+ * security state and privilege level.
31
* @pxn: PXN (privileged execute-never) bit
35
+ */
32
+ * @in_pa: The original input pa space
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
33
+ * @out_pa: The output pa space, modified by NSTable, NS, and NSE
37
+{
34
*/
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
35
static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
39
+ case 0:
36
- int ap, int ns, int xn, int pxn)
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
37
+ int ap, int xn, int pxn,
41
+ return false;
38
+ ARMSecuritySpace in_pa, ARMSecuritySpace out_pa)
42
+ case 1:
39
{
43
+ return is_priv;
40
ARMCPU *cpu = env_archcpu(env);
44
+ case 3:
41
bool is_user = regime_is_user(env, mmu_idx);
45
+ return true;
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
46
+ default:
43
}
47
+ g_assert_not_reached();
44
}
48
+ }
45
49
+}
46
- if (ns && arm_is_secure(env) && (env->cp15.scr_el3 & SCR_SIF)) {
47
+ if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
48
+ (env->cp15.scr_el3 & SCR_SIF)) {
49
return prot_rw;
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
53
int32_t stride;
54
int addrsize, inputsize, outputsize;
55
uint64_t tcr = regime_tcr(env, mmu_idx);
56
- int ap, ns, xn, pxn;
57
+ int ap, xn, pxn;
58
uint32_t el = regime_el(env, mmu_idx);
59
uint64_t descaddrmask;
60
bool aarch64 = arm_el_is_aa64(env, el);
61
uint64_t descriptor, new_descriptor;
62
+ ARMSecuritySpace out_space;
63
64
/* TODO: This code does not support shareability levels. */
65
if (aarch64) {
66
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
67
}
68
69
ap = extract32(attrs, 6, 2);
70
+ out_space = ptw->in_space;
71
if (regime_is_stage2(mmu_idx)) {
72
- ns = mmu_idx == ARMMMUIdx_Stage2;
73
+ /*
74
+ * R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
75
+ * The bit remains ignored for other security states.
76
+ */
77
+ if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
78
+ out_space = ARMSS_NonSecure;
79
+ }
80
xn = extract64(attrs, 53, 2);
81
result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
82
} else {
83
- ns = extract32(attrs, 5, 1);
84
+ int nse, ns = extract32(attrs, 5, 1);
85
+ switch (out_space) {
86
+ case ARMSS_Root:
87
+ /*
88
+ * R_GVZML: Bit 11 becomes the NSE field in the EL3 regime.
89
+ * R_XTYPW: NSE and NS together select the output pa space.
90
+ */
91
+ nse = extract32(attrs, 11, 1);
92
+ out_space = (nse << 1) | ns;
93
+ if (out_space == ARMSS_Secure &&
94
+ !cpu_isar_feature(aa64_sel2, cpu)) {
95
+ out_space = ARMSS_NonSecure;
96
+ }
97
+ break;
98
+ case ARMSS_Secure:
99
+ if (ns) {
100
+ out_space = ARMSS_NonSecure;
101
+ }
102
+ break;
103
+ case ARMSS_Realm:
104
+ switch (mmu_idx) {
105
+ case ARMMMUIdx_Stage1_E0:
106
+ case ARMMMUIdx_Stage1_E1:
107
+ case ARMMMUIdx_Stage1_E1_PAN:
108
+ /* I_CZPRF: For Realm EL1&0 stage1, NS bit is RES0. */
109
+ break;
110
+ case ARMMMUIdx_E2:
111
+ case ARMMMUIdx_E20_0:
112
+ case ARMMMUIdx_E20_2:
113
+ case ARMMMUIdx_E20_2_PAN:
114
+ /*
115
+ * R_LYKFZ, R_WGRZN: For Realm EL2 and EL2&1,
116
+ * NS changes the output to non-secure space.
117
+ */
118
+ if (ns) {
119
+ out_space = ARMSS_NonSecure;
120
+ }
121
+ break;
122
+ default:
123
+ g_assert_not_reached();
124
+ }
125
+ break;
126
+ case ARMSS_NonSecure:
127
+ /* R_QRMFF: For NonSecure state, the NS bit is RES0. */
128
+ break;
129
+ default:
130
+ g_assert_not_reached();
131
+ }
132
xn = extract64(attrs, 54, 1);
133
pxn = extract64(attrs, 53, 1);
134
- result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
50
+
135
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
52
ARMMMUIdx mmu_idx, bool ignfault)
53
{
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
56
break;
57
case EXCP_NOCP:
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
60
+ {
61
+ /*
136
+ /*
62
+ * NOCP might be directed to something other than the current
137
+ * Note that we modified ptw->in_space earlier for NSTable, but
63
+ * security state if this fault is because of NSACR; we indicate
138
+ * result->f.attrs retains a copy of the original security space.
64
+ * the target security state using exception.target_el.
65
+ */
139
+ */
66
+ int target_secstate;
140
+ result->f.prot = get_S1prot(env, mmu_idx, aarch64, ap, xn, pxn,
67
+
141
+ result->f.attrs.space, out_space);
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
142
}
83
143
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
144
if (!(result->f.prot & (1 << access_type))) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
145
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
89
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
96
+
97
+ return 0;
98
+ }
99
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
102
* 1 : trap only EL0 accesses
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
107
- || arm_el_is_aa64(env, 1)) {
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
146
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
147
}
132
148
149
- if (ns) {
150
- /*
151
- * The NS bit will (as required by the architecture) have no effect if
152
- * the CPU doesn't support TZ or this is a non-secure translation
153
- * regime, because the attribute will already be non-secure.
154
- */
155
- result->f.attrs.secure = false;
156
- result->f.attrs.space = ARMSS_NonSecure;
157
- }
158
+ result->f.attrs.space = out_space;
159
+ result->f.attrs.secure = arm_space_is_secure(out_space);
160
161
if (regime_is_stage2(mmu_idx)) {
162
result->cacheattrs.is_s2_format = true;
133
--
163
--
134
2.20.1
164
2.34.1
135
136
diff view generated by jsdifflib
Deleted patch
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
6
1
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
16
1 file changed, 22 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
24
/* Coprocessor. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
26
- /* We don't currently implement M profile FP support,
27
- * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
Deleted patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
1
4
(On a no-FPU system the bit will always be zero, so we don't need
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
", executing it\n", env->regs[15]);
21
env->regs[14] &= ~1;
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
switch_v7m_security_state(env, true);
24
xpsr_write(env, 0, XPSR_IT);
25
env->regs[15] += 4;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
Deleted patch
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
12
1 file changed, 49 insertions(+), 8 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
19
return xpsr_read(env) & mask;
20
break;
21
case 20: /* CONTROL */
22
- return env->v7m.control[env->v7m.secure];
23
+ {
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
25
+ if (!env->v7m.secure) {
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
28
+ }
29
+ return value;
30
+ }
31
case 0x94: /* CONTROL_NS */
32
/* We have to handle this here because unprivileged Secure code
33
* can read the NS CONTROL register.
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
35
if (!env->v7m.secure) {
36
return 0;
37
}
38
- return env->v7m.control[M_REG_NS];
39
+ return env->v7m.control[M_REG_NS] |
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
41
}
42
43
if (el == 0) {
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
45
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
47
uint32_t reg = extract32(maskreg, 0, 8);
48
+ int cur_el = arm_current_el(env);
49
50
- if (arm_current_el(env) == 0 && reg > 7) {
51
- /* only xPSR sub-fields may be written by unprivileged */
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
53
+ /*
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
55
+ * unprivileged code
56
+ */
57
return;
58
}
59
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
63
}
64
+ /*
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
66
+ * RES0 if the FPU is not present, and is stored in the S bank
67
+ */
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
69
+ extract32(env->v7m.nsacr, 10, 1)) {
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
72
+ }
73
return;
74
case 0x98: /* SP_NS */
75
{
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
78
break;
79
case 20: /* CONTROL */
80
- /* Writing to the SPSEL bit only has an effect if we are in
81
+ /*
82
+ * Writing to the SPSEL bit only has an effect if we are in
83
* thread mode; other bits can be updated by any privileged code.
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
85
* env->v7m.control, so we only need update the others.
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
87
* mode; for v8M the write is permitted but will have no effect.
88
+ * All these bits are writes-ignored from non-privileged code,
89
+ * except for SFPA.
90
*/
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
92
- !arm_v7m_is_handler_mode(env)) {
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
94
+ !arm_v7m_is_handler_mode(env))) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
96
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
101
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
103
+ /*
104
+ * SFPA is RAZ/WI from NS or if no FPU.
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
106
+ * Both are stored in the S bank.
107
+ */
108
+ if (env->v7m.secure) {
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
111
+ }
112
+ if (cur_el > 0 &&
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
114
+ extract32(env->v7m.nsacr, 10, 1))) {
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
117
+ }
118
+ }
119
break;
120
default:
121
bad_reg:
122
--
123
2.20.1
124
125
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
From: Richard Henderson <richard.henderson@linaro.org>
2
of the v8M stack limit simply returns early if it does so. This
3
is OK for the current integer-only code, but won't work for the
4
floating point handling we're about to add. We need to continue
5
executing the rest of the function so that we check for other
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
9
2
3
While Root and Realm may read and write data from other spaces,
4
neither may execute from other pa spaces.
5
6
This happens for Stage1 EL3, EL2, EL2&0, and Stage2 EL1&0.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620124418.805717-14-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
13
---
12
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
13
target/arm/ptw.c | 52 ++++++++++++++++++++++++++++++++++++++++++------
15
1 file changed, 18 insertions(+), 5 deletions(-)
14
1 file changed, 46 insertions(+), 6 deletions(-)
16
15
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
18
--- a/target/arm/ptw.c
20
+++ b/target/arm/helper.c
19
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
20
@@ -XXX,XX +XXX,XX @@ do_fault:
22
* should ignore further stack faults trying to process
21
* @xn: XN (execute-never) bits
23
* that derived exception.)
22
* @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
24
*/
23
*/
25
- bool stacked_ok;
24
-static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
26
+ bool stacked_ok = true, limitviol = false;
25
+static int get_S2prot_noexecute(int s2ap)
27
CPUARMState *env = &cpu->env;
26
{
28
uint32_t xpsr = xpsr_read(env);
27
int prot = 0;
29
uint32_t frameptr = env->regs[13];
28
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
30
if (s2ap & 2) {
32
env->v7m.secure);
31
prot |= PAGE_WRITE;
33
env->regs[13] = limit;
32
}
34
- return true;
33
+ return prot;
35
+ /*
34
+}
36
+ * We won't try to perform any further memory accesses but
35
+
37
+ * we must continue through the following code to check for
36
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
38
+ * permission faults during FPU state preservation, and we
37
+{
39
+ * must update FPCCR if lazy stacking is enabled.
38
+ int prot = get_S2prot_noexecute(s2ap);
40
+ */
39
41
+ limitviol = true;
40
if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
42
+ stacked_ok = false;
41
switch (xn) {
42
@@ -XXX,XX +XXX,XX @@ static int get_S1prot(CPUARMState *env, ARMMMUIdx mmu_idx, bool is_aa64,
43
}
43
}
44
}
44
}
45
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
46
- if (out_pa == ARMSS_NonSecure && in_pa == ARMSS_Secure &&
47
* (which may be taken in preference to the one we started with
47
- (env->cp15.scr_el3 & SCR_SIF)) {
48
* if it has higher priority).
48
- return prot_rw;
49
*/
49
+ if (in_pa != out_pa) {
50
- stacked_ok =
50
+ switch (in_pa) {
51
+ stacked_ok = stacked_ok &&
51
+ case ARMSS_Root:
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
52
+ /*
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
53
+ * R_ZWRVD: permission fault for insn fetched from non-Root,
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
54
+ * I_WWBFB: SIF has no effect in EL3.
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
55
+ */
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
56
+ return prot_rw;
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
57
+ case ARMSS_Realm:
58
58
+ /*
59
- /* Update SP regardless of whether any of the stack accesses failed. */
59
+ * R_PKTDS: permission fault for insn fetched from non-Realm,
60
- env->regs[13] = frameptr;
60
+ * for Realm EL2 or EL2&0. The corresponding fault for EL1&0
61
+ /*
61
+ * happens during any stage2 translation.
62
+ * If we broke a stack limit then SP was already updated earlier;
62
+ */
63
+ * otherwise we update SP regardless of whether any of the stack
63
+ switch (mmu_idx) {
64
+ * accesses failed or we took some other kind of fault.
64
+ case ARMMMUIdx_E2:
65
+ */
65
+ case ARMMMUIdx_E20_0:
66
+ if (!limitviol) {
66
+ case ARMMMUIdx_E20_2:
67
+ env->regs[13] = frameptr;
67
+ case ARMMMUIdx_E20_2_PAN:
68
+ }
68
+ return prot_rw;
69
69
+ default:
70
return !stacked_ok;
70
+ break;
71
}
71
+ }
72
+ break;
73
+ case ARMSS_Secure:
74
+ if (env->cp15.scr_el3 & SCR_SIF) {
75
+ return prot_rw;
76
+ }
77
+ break;
78
+ default:
79
+ /* Input NonSecure must have output NonSecure. */
80
+ g_assert_not_reached();
81
+ }
82
}
83
84
/* TODO have_wxn should be replaced with
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
86
/*
87
* R_GYNXY: For stage2 in Realm security state, bit 55 is NS.
88
* The bit remains ignored for other security states.
89
+ * R_YMCSL: Executing an insn fetched from non-Realm causes
90
+ * a stage2 permission fault.
91
*/
92
if (out_space == ARMSS_Realm && extract64(attrs, 55, 1)) {
93
out_space = ARMSS_NonSecure;
94
+ result->f.prot = get_S2prot_noexecute(ap);
95
+ } else {
96
+ xn = extract64(attrs, 53, 2);
97
+ result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
98
}
99
- xn = extract64(attrs, 53, 2);
100
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
101
} else {
102
int nse, ns = extract32(attrs, 5, 1);
103
switch (out_space) {
72
--
104
--
73
2.20.1
105
2.34.1
74
75
diff view generated by jsdifflib
Deleted patch
1
Handle floating point registers in exception entry.
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
4
1
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
12
1 file changed, 95 insertions(+), 3 deletions(-)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
switch_v7m_security_state(env, targets_secure);
20
write_v7m_control_spsel(env, 0);
21
arm_clear_exclusive(env);
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
+ env->v7m.control[M_REG_S] &=
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
/* Clear IT bits */
26
env->condexec_bits = 0;
27
env->regs[14] = lr;
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
uint32_t xpsr = xpsr_read(env);
30
uint32_t frameptr = env->regs[13];
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
+ uint32_t framesize;
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
+
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
+ (env->v7m.secure || nsacr_cp10)) {
37
+ if (env->v7m.secure &&
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
+ framesize = 0xa8;
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
51
}
52
53
- frameptr -= 0x20;
54
+ xpsr &= ~XPSR_SFPA;
55
+ if (env->v7m.secure &&
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
+ xpsr |= XPSR_SFPA;
58
+ }
59
+
60
+ frameptr -= framesize;
61
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
+
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
90
+
91
+ if (stacked_ok && !cpacr_pass) {
92
+ /*
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ * check can never fail as we have already handled that.
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
105
+
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
132
+ }
133
+ }
134
+
135
/*
136
* If we broke a stack limit then SP was already updated earlier;
137
* otherwise we update SP regardless of whether any of the stack
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
140
if (arm_feature(env, ARM_FEATURE_V8)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
142
- R_V7M_EXCRET_DCRS_MASK |
143
- R_V7M_EXCRET_FTYPE_MASK;
144
+ R_V7M_EXCRET_DCRS_MASK;
145
/* The S bit indicates whether we should return to Secure
146
* or NonSecure (ie our current state).
147
* The ES bit indicates whether we're taking this exception
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
149
if (env->v7m.secure) {
150
lr |= R_V7M_EXCRET_S_MASK;
151
}
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
154
+ }
155
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
157
R_V7M_EXCRET_S_MASK |
158
--
159
2.20.1
160
161
diff view generated by jsdifflib
Deleted patch
1
For v8M floating point support, transitions from Secure
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 4 ++++
11
1 file changed, 4 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
18
/* translate.c should have made BXNS UNDEF unless we're secure */
19
assert(env->v7m.secure);
20
21
+ if (!(dest & 1)) {
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
+ }
24
switch_v7m_security_state(env, dest & 1);
25
env->thumb = 1;
26
env->regs[15] = dest & ~1;
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
28
*/
29
write_v7m_exception(env, 1);
30
}
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
32
switch_v7m_security_state(env, 0);
33
env->thumb = 1;
34
env->regs[15] = dest;
35
--
36
2.20.1
37
38
diff view generated by jsdifflib
Deleted patch
1
The TailChain() pseudocode specifies that a tail chaining
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
5
1
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
19
targets_secure ? "secure" : "nonsecure", exc);
20
21
+ if (dotailchain) {
22
+ /* Sanitize LR FType and PREFIX bits */
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
25
+ }
26
+ lr = deposit32(lr, 24, 8, 0xff);
27
+ }
28
+
29
if (arm_feature(env, ARM_FEATURE_V8)) {
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
31
(lr & R_V7M_EXCRET_S_MASK)) {
32
--
33
2.20.1
34
35
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Do not provide a fast-path for physical addresses,
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
as those will need to be validated for GPC.
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 3 ---
11
target/arm/ptw.c | 44 +++++++++++++++++---------------------------
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
12
1 file changed, 17 insertions(+), 27 deletions(-)
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
17
13
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
16
--- a/target/arm/ptw.c
21
+++ b/include/hw/devices.h
17
+++ b/target/arm/ptw.c
22
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
23
/* smc91c111.c */
19
* From gdbstub, do not use softmmu so that we don't modify the
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
20
* state of the cpu at all, including softmmu tlb contents.
25
21
*/
26
-/* lan9118.c */
22
- if (regime_is_stage2(s2_mmu_idx)) {
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
23
- S1Translate s2ptw = {
28
-
24
- .in_mmu_idx = s2_mmu_idx,
29
#endif
25
- .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
26
- .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
31
new file mode 100644
27
- .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
32
index XXXXXXX..XXXXXXX
28
- : space == ARMSS_Realm ? ARMSS_Realm
33
--- /dev/null
29
- : ARMSS_NonSecure),
34
+++ b/include/hw/net/lan9118.h
30
- .in_debug = true,
35
@@ -XXX,XX +XXX,XX @@
31
- };
36
+/*
32
- GetPhysAddrResult s2 = { };
37
+ * SMSC LAN9118 Ethernet interface emulation
33
+ S1Translate s2ptw = {
38
+ *
34
+ .in_mmu_idx = s2_mmu_idx,
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
35
+ .in_ptw_idx = ptw_idx_for_stage_2(env, s2_mmu_idx),
40
+ * Written by Paul Brook
36
+ .in_secure = s2_mmu_idx == ARMMMUIdx_Stage2_S,
41
+ *
37
+ .in_space = (s2_mmu_idx == ARMMMUIdx_Stage2_S ? ARMSS_Secure
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
38
+ : space == ARMSS_Realm ? ARMSS_Realm
43
+ * See the COPYING file in the top-level directory.
39
+ : ARMSS_NonSecure),
44
+ */
40
+ .in_debug = true,
45
+
41
+ };
46
+#ifndef HW_NET_LAN9118_H
42
+ GetPhysAddrResult s2 = { };
47
+#define HW_NET_LAN9118_H
43
48
+
44
- if (get_phys_addr_lpae(env, &s2ptw, addr, MMU_DATA_LOAD,
49
+#include "hw/irq.h"
45
- false, &s2, fi)) {
50
+#include "net/net.h"
46
- goto fail;
51
+
47
- }
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
48
- ptw->out_phys = s2.f.phys_addr;
53
+
49
- pte_attrs = s2.cacheattrs.attrs;
54
+#endif
50
- ptw->out_secure = s2.f.attrs.secure;
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
51
- ptw->out_space = s2.f.attrs.space;
56
index XXXXXXX..XXXXXXX 100644
52
- } else {
57
--- a/hw/arm/kzm.c
53
- /* Regime is physical. */
58
+++ b/hw/arm/kzm.c
54
- ptw->out_phys = addr;
59
@@ -XXX,XX +XXX,XX @@
55
- pte_attrs = 0;
60
#include "qemu/error-report.h"
56
- ptw->out_secure = s2_mmu_idx == ARMMMUIdx_Phys_S;
61
#include "exec/address-spaces.h"
57
- ptw->out_space = (s2_mmu_idx == ARMMMUIdx_Phys_S ? ARMSS_Secure
62
#include "net/net.h"
58
- : space == ARMSS_Realm ? ARMSS_Realm
63
-#include "hw/devices.h"
59
- : ARMSS_NonSecure);
64
+#include "hw/net/lan9118.h"
60
+ if (get_phys_addr_with_struct(env, &s2ptw, addr,
65
#include "hw/char/serial.h"
61
+ MMU_DATA_LOAD, &s2, fi)) {
66
#include "sysemu/qtest.h"
62
+ goto fail;
67
63
}
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
64
+ ptw->out_phys = s2.f.phys_addr;
69
index XXXXXXX..XXXXXXX 100644
65
+ pte_attrs = s2.cacheattrs.attrs;
70
--- a/hw/arm/mps2.c
66
ptw->out_host = NULL;
71
+++ b/hw/arm/mps2.c
67
ptw->out_rw = false;
72
@@ -XXX,XX +XXX,XX @@
68
+ ptw->out_secure = s2.f.attrs.secure;
73
#include "hw/timer/cmsdk-apb-timer.h"
69
+ ptw->out_space = s2.f.attrs.space;
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
70
} else {
75
#include "hw/misc/mps2-scc.h"
71
#ifdef CONFIG_TCG
76
-#include "hw/devices.h"
72
CPUTLBEntryFull *full;
77
+#include "hw/net/lan9118.h"
78
#include "net/net.h"
79
80
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/realview.c
84
+++ b/hw/arm/realview.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "hw/arm/arm.h"
87
#include "hw/arm/primecell.h"
88
#include "hw/devices.h"
89
+#include "hw/net/lan9118.h"
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
119
--
73
--
120
2.20.1
74
2.34.1
121
122
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
Instead of passing this to get_phys_addr_lpae, stash it
4
need to expose it via "qemu/typedefs.h".
4
in the S1Translate structure.
5
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/arm/omap.h | 6 +-----
12
target/arm/ptw.c | 27 ++++++++++++---------------
12
include/hw/devices.h | 15 ---------------
13
1 file changed, 12 insertions(+), 15 deletions(-)
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
14
include/qemu/typedefs.h | 1 -
15
hw/arm/nseries.c | 2 +-
16
hw/arm/palm.c | 2 +-
17
hw/input/tsc2005.c | 2 +-
18
hw/input/tsc210x.c | 4 ++--
19
MAINTAINERS | 2 ++
20
9 files changed, 44 insertions(+), 26 deletions(-)
21
create mode 100644 include/hw/input/tsc2xxx.h
22
14
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
17
--- a/target/arm/ptw.c
26
+++ b/include/hw/arm/omap.h
18
+++ b/target/arm/ptw.c
27
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
28
#include "exec/memory.h"
20
ARMSecuritySpace in_space;
29
# define hw_omap_h        "omap.h"
21
bool in_secure;
30
#include "hw/irq.h"
22
bool in_debug;
31
+#include "hw/input/tsc2xxx.h"
23
+ /*
32
#include "target/arm/cpu-qom.h"
24
+ * If this is stage 2 of a stage 1+2 page table walk, then this must
33
#include "qemu/log.h"
25
+ * be true if stage 1 is an EL0 access; otherwise this is ignored.
34
26
+ * Stage 2 is indicated by in_mmu_idx set to ARMMMUIdx_Stage2{,_S}.
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
27
+ */
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
28
+ bool in_s1_is_el0;
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
29
bool out_secure;
38
30
bool out_rw;
39
-struct uWireSlave {
31
bool out_be;
40
- uint16_t (*receive)(void *opaque);
32
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
41
- void (*send)(void *opaque, uint16_t data);
33
} S1Translate;
42
- void *opaque;
34
43
-};
35
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
44
struct omap_uwire_s;
36
- uint64_t address,
45
void omap_uwire_attach(struct omap_uwire_s *s,
37
- MMUAccessType access_type, bool s1_is_el0,
46
uWireSlave *slave, int chipselect);
38
+ uint64_t address, MMUAccessType access_type,
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
39
GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
48
index XXXXXXX..XXXXXXX 100644
40
49
--- a/include/hw/devices.h
41
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
50
+++ b/include/hw/devices.h
42
@@ -XXX,XX +XXX,XX @@ static int check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, uint64_t tcr,
51
@@ -XXX,XX +XXX,XX @@
43
* @ptw: Current and next stage parameters for the walk.
52
/* Devices that have nowhere better to go. */
44
* @address: virtual address to get physical address for
53
45
* @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
54
#include "hw/hw.h"
46
- * @s1_is_el0: if @ptw->in_mmu_idx is ARMMMUIdx_Stage2
55
-#include "ui/console.h"
47
- * (so this is a stage 2 page table walk),
56
48
- * must be true if this is stage 2 of a stage 1+2
57
/* smc91c111.c */
49
- * walk for an EL0 access. If @mmu_idx is anything else,
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
50
- * @s1_is_el0 is ignored.
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
51
* @result: set on translation success,
60
/* lan9118.c */
52
* @fi: set to fault info if the translation fails
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
*/
62
54
static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
63
-/* tsc210x.c */
55
uint64_t address,
64
-uWireSlave *tsc2102_init(qemu_irq pint);
56
- MMUAccessType access_type, bool s1_is_el0,
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
57
+ MMUAccessType access_type,
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
58
GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
59
{
68
-void tsc210x_set_transform(uWireSlave *chip,
60
ARMCPU *cpu = env_archcpu(env);
69
- MouseTransformInfo *info);
61
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
62
result->f.prot = get_S2prot_noexecute(ap);
71
-
63
} else {
72
-/* tsc2005.c */
64
xn = extract64(attrs, 53, 2);
73
-void *tsc2005_init(qemu_irq pintdav);
65
- result->f.prot = get_S2prot(env, ap, xn, s1_is_el0);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
66
+ result->f.prot = get_S2prot(env, ap, xn, ptw->in_s1_is_el0);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
67
}
76
-
68
} else {
77
#endif
69
int nse, ns = extract32(attrs, 5, 1);
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
79
new file mode 100644
71
bool ret, ipa_secure;
80
index XXXXXXX..XXXXXXX
72
ARMCacheAttrs cacheattrs1;
81
--- /dev/null
73
ARMSecuritySpace ipa_space;
82
+++ b/include/hw/input/tsc2xxx.h
74
- bool is_el0;
83
@@ -XXX,XX +XXX,XX @@
75
uint64_t hcr;
84
+/*
76
85
+ * TI touchscreen controller
77
ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
86
+ *
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
87
+ * Copyright (c) 2006 Andrzej Zaborowski
79
ipa_secure = result->f.attrs.secure;
88
+ * Copyright (C) 2008 Nokia Corporation
80
ipa_space = result->f.attrs.space;
89
+ *
81
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
82
- is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
91
+ * See the COPYING file in the top-level directory.
83
+ ptw->in_s1_is_el0 = ptw->in_mmu_idx == ARMMMUIdx_Stage1_E0;
92
+ */
84
ptw->in_mmu_idx = ipa_secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
93
+
85
ptw->in_secure = ipa_secure;
94
+#ifndef HW_INPUT_TSC2XXX_H
86
ptw->in_space = ipa_space;
95
+#define HW_INPUT_TSC2XXX_H
87
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
96
+
88
ret = get_phys_addr_pmsav8(env, ipa, access_type,
97
+#include "hw/irq.h"
89
ptw->in_mmu_idx, is_secure, result, fi);
98
+#include "ui/console.h"
90
} else {
99
+
91
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
100
+typedef struct uWireSlave {
92
- is_el0, result, fi);
101
+ uint16_t (*receive)(void *opaque);
93
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
102
+ void (*send)(void *opaque, uint16_t data);
94
}
103
+ void *opaque;
95
fi->s2addr = ipa;
104
+} uWireSlave;
96
105
+
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
106
+/* tsc210x.c */
98
}
107
+uWireSlave *tsc2102_init(qemu_irq pint);
99
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
100
if (regime_using_lpae_format(env, mmu_idx)) {
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
101
- return get_phys_addr_lpae(env, ptw, address, access_type, false,
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
102
- result, fi);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
103
+ return get_phys_addr_lpae(env, ptw, address, access_type, result, fi);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
104
} else if (arm_feature(env, ARM_FEATURE_V7) ||
113
+
105
regime_sctlr(env, mmu_idx) & SCTLR_XP) {
114
+/* tsc2005.c */
106
return get_phys_addr_v6(env, ptw, address, access_type, result, fi);
115
+void *tsc2005_init(qemu_irq pintdav);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
118
+
119
+#endif
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/include/qemu/typedefs.h
123
+++ b/include/qemu/typedefs.h
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
125
typedef struct Range Range;
126
typedef struct SHPCDevice SHPCDevice;
127
typedef struct SSIBus SSIBus;
128
-typedef struct uWireSlave uWireSlave;
129
typedef struct VirtIODevice VirtIODevice;
130
typedef struct Visitor Visitor;
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/nseries.c
135
+++ b/hw/arm/nseries.c
136
@@ -XXX,XX +XXX,XX @@
137
#include "ui/console.h"
138
#include "hw/boards.h"
139
#include "hw/i2c/i2c.h"
140
-#include "hw/devices.h"
141
#include "hw/display/blizzard.h"
142
+#include "hw/input/tsc2xxx.h"
143
#include "hw/misc/cbus.h"
144
#include "hw/misc/tmp105.h"
145
#include "hw/block/flash.h"
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/palm.c
149
+++ b/hw/arm/palm.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "hw/arm/omap.h"
152
#include "hw/boards.h"
153
#include "hw/arm/arm.h"
154
-#include "hw/devices.h"
155
+#include "hw/input/tsc2xxx.h"
156
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/hw/input/tsc2005.c
162
+++ b/hw/input/tsc2005.c
163
@@ -XXX,XX +XXX,XX @@
164
#include "hw/hw.h"
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
107
--
208
2.20.1
108
2.34.1
209
109
210
110
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
This fixes a bug in which we failed to initialize
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
the result attributes properly after the memset.
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
include/hw/devices.h | 3 ---
12
target/arm/ptw.c | 11 +----------
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
13
1 file changed, 1 insertion(+), 10 deletions(-)
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
14
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
17
--- a/target/arm/ptw.c
19
+++ b/include/hw/devices.h
18
+++ b/target/arm/ptw.c
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
19
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
20
void *out_host;
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
21
} S1Translate;
23
22
24
-/* stellaris_input.c */
23
-static bool get_phys_addr_lpae(CPUARMState *env, S1Translate *ptw,
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
- uint64_t address, MMUAccessType access_type,
25
- GetPhysAddrResult *result, ARMMMUFaultInfo *fi);
26
-
26
-
27
#endif
27
static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
28
target_ulong address,
29
new file mode 100644
29
MMUAccessType access_type,
30
index XXXXXXX..XXXXXXX
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
31
--- /dev/null
31
cacheattrs1 = result->cacheattrs;
32
+++ b/include/hw/input/gamepad.h
32
memset(result, 0, sizeof(*result));
33
@@ -XXX,XX +XXX,XX @@
33
34
+/*
34
- if (arm_feature(env, ARM_FEATURE_PMSA)) {
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
35
- ret = get_phys_addr_pmsav8(env, ipa, access_type,
36
+ *
36
- ptw->in_mmu_idx, is_secure, result, fi);
37
+ * Copyright (c) 2007 CodeSourcery.
37
- } else {
38
+ * Written by Paul Brook
38
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, result, fi);
39
+ *
39
- }
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
40
+ ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
41
+ * See the COPYING file in the top-level directory.
41
fi->s2addr = ipa;
42
+ */
42
43
+
43
/* Combine the S1 and S2 perms. */
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
92
S: Maintained
93
F: hw/*/stellaris*
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
98
--
44
--
99
2.20.1
45
2.34.1
100
46
101
47
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
The function takes the fields as filled in by
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
the Arm ARM pseudocode for TakeGPCException.
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-18-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/nseries.c | 3 ++-
11
target/arm/syndrome.h | 10 ++++++++++
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
1 file changed, 10 insertions(+)
11
13
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
16
--- a/target/arm/syndrome.h
15
+++ b/hw/arm/nseries.c
17
+++ b/target/arm/syndrome.h
16
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
17
#include "hw/boards.h"
19
EC_SVEACCESSTRAP = 0x19,
18
#include "hw/i2c/i2c.h"
20
EC_ERETTRAP = 0x1a,
19
#include "hw/devices.h"
21
EC_SMETRAP = 0x1d,
20
+#include "hw/misc/tmp105.h"
22
+ EC_GPC = 0x1e,
21
#include "hw/block/flash.h"
23
EC_INSNABORT = 0x20,
22
#include "hw/hw.h"
24
EC_INSNABORT_SAME_EL = 0x21,
23
#include "hw/bt.h"
25
EC_PCALIGNMENT = 0x22,
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
26
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_bxjtrap(int cv, int cond, int rm)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
27
(cv << 24) | (cond << 20) | rm;
26
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
31
}
28
}
32
29
30
+static inline uint32_t syn_gpc(int s2ptw, int ind, int gpcsc,
31
+ int cm, int s1ptw, int wnr, int fsc)
32
+{
33
+ /* TODO: FEAT_NV2 adds VNCR */
34
+ return (EC_GPC << ARM_EL_EC_SHIFT) | ARM_EL_IL | (s2ptw << 21)
35
+ | (ind << 20) | (gpcsc << 14) | (cm << 8) | (s1ptw << 7)
36
+ | (wnr << 6) | fsc;
37
+}
38
+
39
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
40
{
41
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
33
--
42
--
34
2.20.1
43
2.34.1
35
36
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
From: Richard Henderson <richard.henderson@linaro.org>
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
2
3
Handle GPC Fault types in arm_deliver_fault, reporting as
4
either a GPC exception at EL3, or falling through to insn
5
or data aborts at various exception levels.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20230620124418.805717-19-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
11
---
11
---
12
target/arm/cpu.h | 3 ++
12
target/arm/cpu.h | 1 +
13
target/arm/helper.h | 2 +
13
target/arm/internals.h | 27 +++++++++++
14
target/arm/translate.h | 1 +
14
target/arm/helper.c | 5 ++
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
15
target/arm/tcg/tlb_helper.c | 96 +++++++++++++++++++++++++++++++++++--
16
target/arm/translate.c | 22 ++++++++
16
4 files changed, 126 insertions(+), 3 deletions(-)
17
5 files changed, 140 insertions(+)
18
17
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
23
#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
24
#define EXCP_DIVBYZERO 23 /* v7M DIVBYZERO UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
25
#define EXCP_VSERR 24
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
26
+#define EXCP_GPC 25 /* v9 Granule Protection Check Fault */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
27
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
28
30
#define ARMV7M_EXCP_RESET 1
29
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
30
diff --git a/target/arm/internals.h b/target/arm/internals.h
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
31
index XXXXXXX..XXXXXXX 100644
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
32
--- a/target/arm/internals.h
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
33
+++ b/target/arm/internals.h
35
+/* For M profile only, set if FPCCR.LSPACT is set */
34
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
35
ARMFault_ICacheMaint,
37
/* For M profile only, set if we must create a new FP context */
36
ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
37
ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
39
/* For M profile only, set if FPCCR.S does not match current security state */
38
+ ARMFault_GPCFOnWalk,
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
39
+ ARMFault_GPCFOnOutput,
41
index XXXXXXX..XXXXXXX 100644
40
} ARMFaultType;
42
--- a/target/arm/helper.h
41
43
+++ b/target/arm/helper.h
42
+typedef enum ARMGPCF {
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
43
+ GPCF_None,
45
44
+ GPCF_AddressSize,
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
45
+ GPCF_Walk,
47
46
+ GPCF_EABT,
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
47
+ GPCF_Fail,
49
+
48
+} ARMGPCF;
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
49
+
51
50
/**
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
51
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
52
* @type: Type of fault
54
index XXXXXXX..XXXXXXX 100644
53
+ * @gpcf: Subtype of ARMFault_GPCFOn{Walk,Output}.
55
--- a/target/arm/translate.h
54
* @level: Table walk level (for translation, access flag and permission faults)
56
+++ b/target/arm/translate.h
55
* @domain: Domain of the fault address (for non-LPAE CPUs only)
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
56
* @s2addr: Address that caused a fault at stage 2
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
57
+ * @paddr: physical address that caused a fault for gpc
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
58
+ * @paddr_space: physical address space that caused a fault for gpc
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
59
* @stage2: True if we faulted at stage 2
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
60
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
61
* @s1ns: True if we faulted on a non-secure IPA while in secure state
63
* so that top level loop can generate correct syndrome information.
62
@@ -XXX,XX +XXX,XX @@ typedef enum ARMFaultType {
64
*/
63
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
64
struct ARMMMUFaultInfo {
65
ARMFaultType type;
66
+ ARMGPCF gpcf;
67
target_ulong s2addr;
68
+ target_ulong paddr;
69
+ ARMSecuritySpace paddr_space;
70
int level;
71
int domain;
72
bool stage2;
73
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
74
case ARMFault_Exclusive:
75
fsc = 0x35;
76
break;
77
+ case ARMFault_GPCFOnWalk:
78
+ assert(fi->level >= -1 && fi->level <= 3);
79
+ if (fi->level < 0) {
80
+ fsc = 0b100011;
81
+ } else {
82
+ fsc = 0b100100 | fi->level;
83
+ }
84
+ break;
85
+ case ARMFault_GPCFOnOutput:
86
+ fsc = 0b101000;
87
+ break;
88
default:
89
/* Other faults can't occur in a context that requires a
90
* long-format status code.
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
91
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
92
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
93
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
94
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
95
@@ -XXX,XX +XXX,XX @@ void arm_log_exception(CPUState *cs)
70
g_assert_not_reached();
96
[EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
97
[EXCP_DIVBYZERO] = "v7M DIVBYZERO UsageFault",
98
[EXCP_VSERR] = "Virtual SERR",
99
+ [EXCP_GPC] = "Granule Protection Check",
100
};
101
102
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
103
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
104
}
105
106
switch (cs->exception_index) {
107
+ case EXCP_GPC:
108
+ qemu_log_mask(CPU_LOG_INT, "...with MFAR 0x%" PRIx64 "\n",
109
+ env->cp15.mfar_el3);
110
+ /* fall through */
111
case EXCP_PREFETCH_ABORT:
112
case EXCP_DATA_ABORT:
113
/*
114
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/tcg/tlb_helper.c
117
+++ b/target/arm/tcg/tlb_helper.c
118
@@ -XXX,XX +XXX,XX @@ static uint32_t compute_fsr_fsc(CPUARMState *env, ARMMMUFaultInfo *fi,
119
return fsr;
71
}
120
}
72
121
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
122
+static bool report_as_gpc_exception(ARMCPU *cpu, int current_el,
123
+ ARMMMUFaultInfo *fi)
74
+{
124
+{
75
+ /* translate.c should never generate calls here in user-only mode */
125
+ bool ret;
76
+ g_assert_not_reached();
126
+
127
+ switch (fi->gpcf) {
128
+ case GPCF_None:
129
+ return false;
130
+ case GPCF_AddressSize:
131
+ case GPCF_Walk:
132
+ case GPCF_EABT:
133
+ /* R_PYTGX: GPT faults are reported as GPC. */
134
+ ret = true;
135
+ break;
136
+ case GPCF_Fail:
137
+ /*
138
+ * R_BLYPM: A GPF at EL3 is reported as insn or data abort.
139
+ * R_VBZMW, R_LXHQR: A GPF at EL[0-2] is reported as a GPC
140
+ * if SCR_EL3.GPF is set, otherwise an insn or data abort.
141
+ */
142
+ ret = (cpu->env.cp15.scr_el3 & SCR_GPF) && current_el != 3;
143
+ break;
144
+ default:
145
+ g_assert_not_reached();
146
+ }
147
+
148
+ assert(cpu_isar_feature(aa64_rme, cpu));
149
+ assert(fi->type == ARMFault_GPCFOnWalk ||
150
+ fi->type == ARMFault_GPCFOnOutput);
151
+ if (fi->gpcf == GPCF_AddressSize) {
152
+ assert(fi->level == 0);
153
+ } else {
154
+ assert(fi->level >= 0 && fi->level <= 1);
155
+ }
156
+
157
+ return ret;
77
+}
158
+}
78
+
159
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
160
+static unsigned encode_gpcsc(ARMMMUFaultInfo *fi)
161
+{
162
+ static uint8_t const gpcsc[] = {
163
+ [GPCF_AddressSize] = 0b000000,
164
+ [GPCF_Walk] = 0b000100,
165
+ [GPCF_Fail] = 0b001100,
166
+ [GPCF_EABT] = 0b010100,
167
+ };
168
+
169
+ /* Note that we've validated fi->gpcf and fi->level above. */
170
+ return gpcsc[fi->gpcf] | fi->level;
171
+}
172
+
173
static G_NORETURN
174
void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
175
MMUAccessType access_type,
176
int mmu_idx, ARMMMUFaultInfo *fi)
80
{
177
{
81
/* The TT instructions can be used by unprivileged code, but in
178
CPUARMState *env = &cpu->env;
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
179
- int target_el;
83
return false;
180
+ int target_el = exception_target_el(env);
84
}
181
+ int current_el = arm_current_el(env);
85
182
bool same_el;
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
183
uint32_t syn, exc, fsr, fsc;
87
+{
184
88
+ /*
185
- target_el = exception_target_el(env);
89
+ * Preserve FP state (because LSPACT was set and we are about
186
+ if (report_as_gpc_exception(cpu, current_el, fi)) {
90
+ * to execute an FP instruction). This corresponds to the
187
+ target_el = 3;
91
+ * PreserveFPState() pseudocode.
188
+
92
+ * We may throw an exception if the stacking fails.
189
+ fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
93
+ */
190
+
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
191
+ syn = syn_gpc(fi->stage2 && fi->type == ARMFault_GPCFOnWalk,
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
192
+ access_type == MMU_INST_FETCH,
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
193
+ encode_gpcsc(fi), 0, fi->s1ptw,
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
194
+ access_type == MMU_DATA_STORE, fsc);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
195
+
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
196
+ env->cp15.mfar_el3 = fi->paddr;
100
+ bool stacked_ok = true;
197
+ switch (fi->paddr_space) {
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
198
+ case ARMSS_Secure:
102
+ bool take_exception;
199
+ break;
103
+
200
+ case ARMSS_NonSecure:
104
+ /* Take the iothread lock as we are going to touch the NVIC */
201
+ env->cp15.mfar_el3 |= R_MFAR_NS_MASK;
105
+ qemu_mutex_lock_iothread();
202
+ break;
106
+
203
+ case ARMSS_Root:
107
+ /* Check the background context had access to the FPU */
204
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK;
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
205
+ break;
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
206
+ case ARMSS_Realm:
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
207
+ env->cp15.mfar_el3 |= R_MFAR_NSE_MASK | R_MFAR_NS_MASK;
111
+ stacked_ok = false;
208
+ break;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
209
+ default:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
210
+ g_assert_not_reached();
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
211
+ }
137
+
212
+
138
+ stacked_ok = stacked_ok &&
213
+ exc = EXCP_GPC;
139
+ v7m_stack_write(cpu, fpcar + 0x40,
214
+ goto do_raise;
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
215
+ }
141
+ }
216
+
142
+
217
+ /* If SCR_EL3.GPF is unset, GPF may still be routed to EL2. */
143
+ /*
218
+ if (fi->gpcf == GPCF_Fail && target_el < 2) {
144
+ * We definitely pended an exception, but it's possible that it
219
+ if (arm_hcr_el2_eff(env) & HCR_GPF) {
145
+ * might not be able to be taken now. If its priority permits us
220
+ target_el = 2;
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
221
+ }
169
+ vfp_set_fpscr(env, 0);
222
+ }
170
+ }
223
+
171
+ /*
224
if (fi->stage2) {
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
225
target_el = 2;
173
+ * unchanged.
226
env->cp15.hpfar_el2 = extract64(fi->s2addr, 12, 47) << 4;
174
+ */
227
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
175
+}
228
env->cp15.hpfar_el2 |= HPFAR_NS;
176
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
178
* This may change the current stack pointer between Main and Process
179
* stack pointers if it is done for the CONTROL register for the current
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
229
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
230
}
204
231
- same_el = (arm_current_el(env) == target_el);
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
232
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
233
+ same_el = current_el == target_el;
207
+
234
fsr = compute_fsr_fsc(env, fi, target_el, mmu_idx, &fsc);
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
235
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
236
if (access_type == MMU_INST_FETCH) {
210
+ }
237
@@ -XXX,XX +XXX,XX @@ void arm_deliver_fault(ARMCPU *cpu, vaddr addr,
211
+ }
238
exc = EXCP_DATA_ABORT;
212
+
239
}
213
*pflags = flags;
240
214
*cs_base = 0;
241
+ do_raise:
215
}
242
env->exception.vaddress = addr;
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
243
env->exception.fsr = fsr;
217
index XXXXXXX..XXXXXXX 100644
244
raise_exception(env, exc, syn, target_el);
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
245
--
257
2.20.1
246
2.34.1
258
259
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
From: Richard Henderson <richard.henderson@linaro.org>
2
check is different if floating point is present.
3
2
3
Place the check at the end of get_phys_addr_with_struct,
4
so that we check all physical results.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20230620124418.805717-20-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
10
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
11
target/arm/ptw.c | 249 +++++++++++++++++++++++++++++++++++++++++++----
9
1 file changed, 19 insertions(+), 3 deletions(-)
12
1 file changed, 232 insertions(+), 17 deletions(-)
10
13
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
16
--- a/target/arm/ptw.c
14
+++ b/target/arm/helper.c
17
+++ b/target/arm/ptw.c
15
@@ -XXX,XX +XXX,XX @@ load_fail:
18
@@ -XXX,XX +XXX,XX @@ typedef struct S1Translate {
19
void *out_host;
20
} S1Translate;
21
22
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
23
- target_ulong address,
24
- MMUAccessType access_type,
25
- GetPhysAddrResult *result,
26
- ARMMMUFaultInfo *fi);
27
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
28
+ target_ulong address,
29
+ MMUAccessType access_type,
30
+ GetPhysAddrResult *result,
31
+ ARMMMUFaultInfo *fi);
32
+
33
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
34
+ target_ulong address,
35
+ MMUAccessType access_type,
36
+ GetPhysAddrResult *result,
37
+ ARMMMUFaultInfo *fi);
38
39
/* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
40
static const uint8_t pamax_map[] = {
41
@@ -XXX,XX +XXX,XX @@ static bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx,
42
return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0;
43
}
44
45
+static bool granule_protection_check(CPUARMState *env, uint64_t paddress,
46
+ ARMSecuritySpace pspace,
47
+ ARMMMUFaultInfo *fi)
48
+{
49
+ MemTxAttrs attrs = {
50
+ .secure = true,
51
+ .space = ARMSS_Root,
52
+ };
53
+ ARMCPU *cpu = env_archcpu(env);
54
+ uint64_t gpccr = env->cp15.gpccr_el3;
55
+ unsigned pps, pgs, l0gptsz, level = 0;
56
+ uint64_t tableaddr, pps_mask, align, entry, index;
57
+ AddressSpace *as;
58
+ MemTxResult result;
59
+ int gpi;
60
+
61
+ if (!FIELD_EX64(gpccr, GPCCR, GPC)) {
62
+ return true;
63
+ }
64
+
65
+ /*
66
+ * GPC Priority 1 (R_GMGRR):
67
+ * R_JWCSM: If the configuration of GPCCR_EL3 is invalid,
68
+ * the access fails as GPT walk fault at level 0.
69
+ */
70
+
71
+ /*
72
+ * Configuration of PPS to a value exceeding the implemented
73
+ * physical address size is invalid.
74
+ */
75
+ pps = FIELD_EX64(gpccr, GPCCR, PPS);
76
+ if (pps > FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE)) {
77
+ goto fault_walk;
78
+ }
79
+ pps = pamax_map[pps];
80
+ pps_mask = MAKE_64BIT_MASK(0, pps);
81
+
82
+ switch (FIELD_EX64(gpccr, GPCCR, SH)) {
83
+ case 0b10: /* outer shareable */
84
+ break;
85
+ case 0b00: /* non-shareable */
86
+ case 0b11: /* inner shareable */
87
+ /* Inner and Outer non-cacheable requires Outer shareable. */
88
+ if (FIELD_EX64(gpccr, GPCCR, ORGN) == 0 &&
89
+ FIELD_EX64(gpccr, GPCCR, IRGN) == 0) {
90
+ goto fault_walk;
91
+ }
92
+ break;
93
+ default: /* reserved */
94
+ goto fault_walk;
95
+ }
96
+
97
+ switch (FIELD_EX64(gpccr, GPCCR, PGS)) {
98
+ case 0b00: /* 4KB */
99
+ pgs = 12;
100
+ break;
101
+ case 0b01: /* 64KB */
102
+ pgs = 16;
103
+ break;
104
+ case 0b10: /* 16KB */
105
+ pgs = 14;
106
+ break;
107
+ default: /* reserved */
108
+ goto fault_walk;
109
+ }
110
+
111
+ /* Note this field is read-only and fixed at reset. */
112
+ l0gptsz = 30 + FIELD_EX64(gpccr, GPCCR, L0GPTSZ);
113
+
114
+ /*
115
+ * GPC Priority 2: Secure, Realm or Root address exceeds PPS.
116
+ * R_CPDSB: A NonSecure physical address input exceeding PPS
117
+ * does not experience any fault.
118
+ */
119
+ if (paddress & ~pps_mask) {
120
+ if (pspace == ARMSS_NonSecure) {
121
+ return true;
122
+ }
123
+ goto fault_size;
124
+ }
125
+
126
+ /* GPC Priority 3: the base address of GPTBR_EL3 exceeds PPS. */
127
+ tableaddr = env->cp15.gptbr_el3 << 12;
128
+ if (tableaddr & ~pps_mask) {
129
+ goto fault_size;
130
+ }
131
+
132
+ /*
133
+ * BADDR is aligned per a function of PPS and L0GPTSZ.
134
+ * These bits of GPTBR_EL3 are RES0, but are not a configuration error,
135
+ * unlike the RES0 bits of the GPT entries (R_XNKFZ).
136
+ */
137
+ align = MAX(pps - l0gptsz + 3, 12);
138
+ align = MAKE_64BIT_MASK(0, align);
139
+ tableaddr &= ~align;
140
+
141
+ as = arm_addressspace(env_cpu(env), attrs);
142
+
143
+ /* Level 0 lookup. */
144
+ index = extract64(paddress, l0gptsz, pps - l0gptsz);
145
+ tableaddr += index * 8;
146
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
147
+ if (result != MEMTX_OK) {
148
+ goto fault_eabt;
149
+ }
150
+
151
+ switch (extract32(entry, 0, 4)) {
152
+ case 1: /* block descriptor */
153
+ if (entry >> 8) {
154
+ goto fault_walk; /* RES0 bits not 0 */
155
+ }
156
+ gpi = extract32(entry, 4, 4);
157
+ goto found;
158
+ case 3: /* table descriptor */
159
+ tableaddr = entry & ~0xf;
160
+ align = MAX(l0gptsz - pgs - 1, 12);
161
+ align = MAKE_64BIT_MASK(0, align);
162
+ if (tableaddr & (~pps_mask | align)) {
163
+ goto fault_walk; /* RES0 bits not 0 */
164
+ }
165
+ break;
166
+ default: /* invalid */
167
+ goto fault_walk;
168
+ }
169
+
170
+ /* Level 1 lookup */
171
+ level = 1;
172
+ index = extract64(paddress, pgs + 4, l0gptsz - pgs - 4);
173
+ tableaddr += index * 8;
174
+ entry = address_space_ldq_le(as, tableaddr, attrs, &result);
175
+ if (result != MEMTX_OK) {
176
+ goto fault_eabt;
177
+ }
178
+
179
+ switch (extract32(entry, 0, 4)) {
180
+ case 1: /* contiguous descriptor */
181
+ if (entry >> 10) {
182
+ goto fault_walk; /* RES0 bits not 0 */
183
+ }
184
+ /*
185
+ * Because the softmmu tlb only works on units of TARGET_PAGE_SIZE,
186
+ * and because we cannot invalidate by pa, and thus will always
187
+ * flush entire tlbs, we don't actually care about the range here
188
+ * and can simply extract the GPI as the result.
189
+ */
190
+ if (extract32(entry, 8, 2) == 0) {
191
+ goto fault_walk; /* reserved contig */
192
+ }
193
+ gpi = extract32(entry, 4, 4);
194
+ break;
195
+ default:
196
+ index = extract64(paddress, pgs, 4);
197
+ gpi = extract64(entry, index * 4, 4);
198
+ break;
199
+ }
200
+
201
+ found:
202
+ switch (gpi) {
203
+ case 0b0000: /* no access */
204
+ break;
205
+ case 0b1111: /* all access */
206
+ return true;
207
+ case 0b1000:
208
+ case 0b1001:
209
+ case 0b1010:
210
+ case 0b1011:
211
+ if (pspace == (gpi & 3)) {
212
+ return true;
213
+ }
214
+ break;
215
+ default:
216
+ goto fault_walk; /* reserved */
217
+ }
218
+
219
+ fi->gpcf = GPCF_Fail;
220
+ goto fault_common;
221
+ fault_eabt:
222
+ fi->gpcf = GPCF_EABT;
223
+ goto fault_common;
224
+ fault_size:
225
+ fi->gpcf = GPCF_AddressSize;
226
+ goto fault_common;
227
+ fault_walk:
228
+ fi->gpcf = GPCF_Walk;
229
+ fault_common:
230
+ fi->level = level;
231
+ fi->paddr = paddress;
232
+ fi->paddr_space = pspace;
233
+ return false;
234
+}
235
+
236
static bool S2_attrs_are_device(uint64_t hcr, uint8_t attrs)
237
{
238
/*
239
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
240
};
241
GetPhysAddrResult s2 = { };
242
243
- if (get_phys_addr_with_struct(env, &s2ptw, addr,
244
- MMU_DATA_LOAD, &s2, fi)) {
245
+ if (get_phys_addr_gpc(env, &s2ptw, addr, MMU_DATA_LOAD, &s2, fi)) {
246
goto fail;
247
}
248
+
249
ptw->out_phys = s2.f.phys_addr;
250
pte_attrs = s2.cacheattrs.attrs;
251
ptw->out_host = NULL;
252
@@ -XXX,XX +XXX,XX @@ static bool S1_ptw_translate(CPUARMState *env, S1Translate *ptw,
253
254
fail:
255
assert(fi->type != ARMFault_None);
256
+ if (fi->type == ARMFault_GPCFOnOutput) {
257
+ fi->type = ARMFault_GPCFOnWalk;
258
+ }
259
fi->s2addr = addr;
260
fi->stage2 = true;
261
fi->s1ptw = true;
262
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
263
ARMMMUFaultInfo *fi)
264
{
265
uint8_t memattr = 0x00; /* Device nGnRnE */
266
- uint8_t shareability = 0; /* non-sharable */
267
+ uint8_t shareability = 0; /* non-shareable */
268
int r_el;
269
270
switch (mmu_idx) {
271
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_disabled(CPUARMState *env, target_ulong address,
272
} else {
273
memattr = 0x44; /* Normal, NC, No */
274
}
275
- shareability = 2; /* outer sharable */
276
+ shareability = 2; /* outer shareable */
277
}
278
result->cacheattrs.is_s2_format = false;
279
break;
280
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
281
ARMSecuritySpace ipa_space;
282
uint64_t hcr;
283
284
- ret = get_phys_addr_with_struct(env, ptw, address, access_type, result, fi);
285
+ ret = get_phys_addr_nogpc(env, ptw, address, access_type, result, fi);
286
287
/* If S1 fails, return early. */
288
if (ret) {
289
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
290
cacheattrs1 = result->cacheattrs;
291
memset(result, 0, sizeof(*result));
292
293
- ret = get_phys_addr_with_struct(env, ptw, ipa, access_type, result, fi);
294
+ ret = get_phys_addr_nogpc(env, ptw, ipa, access_type, result, fi);
295
fi->s2addr = ipa;
296
297
/* Combine the S1 and S2 perms. */
298
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
16
return false;
299
return false;
17
}
300
}
18
301
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
302
-static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
303
+static bool get_phys_addr_nogpc(CPUARMState *env, S1Translate *ptw,
304
target_ulong address,
305
MMUAccessType access_type,
306
GetPhysAddrResult *result,
307
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_with_struct(CPUARMState *env, S1Translate *ptw,
308
}
309
}
310
311
+static bool get_phys_addr_gpc(CPUARMState *env, S1Translate *ptw,
312
+ target_ulong address,
313
+ MMUAccessType access_type,
314
+ GetPhysAddrResult *result,
315
+ ARMMMUFaultInfo *fi)
20
+{
316
+{
21
+ /*
317
+ if (get_phys_addr_nogpc(env, ptw, address, access_type, result, fi)) {
22
+ * Return the integrity signature value for the callee-saves
318
+ return true;
23
+ * stack frame section. @lr is the exception return payload/LR value
319
+ }
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
320
+ if (!granule_protection_check(env, result->f.phys_addr,
25
+ */
321
+ result->f.attrs.space, fi)) {
26
+ uint32_t sig = 0xfefa125a;
322
+ fi->type = ARMFault_GPCFOnOutput;
27
+
323
+ return true;
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
324
+ }
29
+ sig |= 1;
325
+ return false;
30
+ }
31
+ return sig;
32
+}
326
+}
33
+
327
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
328
bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
35
bool ignore_faults)
329
MMUAccessType access_type, ARMMMUIdx mmu_idx,
36
{
330
bool is_secure, GetPhysAddrResult *result,
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
331
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr_with_secure(CPUARMState *env, target_ulong address,
38
bool stacked_ok;
332
.in_secure = is_secure,
39
uint32_t limit;
333
.in_space = arm_secure_to_space(is_secure),
40
bool want_psp;
334
};
41
+ uint32_t sig;
335
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
42
336
- result, fi);
43
if (dotailchain) {
337
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
338
}
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
339
46
/* Write as much of the stack frame as we can. A write failure may
340
bool get_phys_addr(CPUARMState *env, target_ulong address,
47
* cause us to pend a derived exception.
341
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
48
*/
342
49
+ sig = v7m_integrity_sig(env, lr);
343
ptw.in_space = ss;
50
stacked_ok =
344
ptw.in_secure = arm_space_is_secure(ss);
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
345
- return get_phys_addr_with_struct(env, &ptw, address, access_type,
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
346
- result, fi);
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
347
+ return get_phys_addr_gpc(env, &ptw, address, access_type, result, fi);
54
ignore_faults) &&
348
}
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
349
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
350
hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
57
if (return_to_secure &&
351
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
352
ARMMMUFaultInfo fi = {};
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
353
bool ret;
60
- uint32_t expected_sig = 0xfefa125b;
354
61
uint32_t actual_sig;
355
- ret = get_phys_addr_with_struct(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
62
356
+ ret = get_phys_addr_gpc(env, &ptw, addr, MMU_DATA_LOAD, &res, &fi);
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
357
*attrs = res.f.attrs;
64
358
65
- if (pop_ok && expected_sig != actual_sig) {
359
if (ret) {
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
67
/* Take a SecureFault on the current stack */
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
70
--
360
--
71
2.20.1
361
2.34.1
72
73
diff view generated by jsdifflib
Deleted patch
1
Handle floating point registers in exception return.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
8
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
10
1 file changed, 141 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
17
bool rettobase = false;
18
bool exc_secure = false;
19
bool return_to_secure;
20
+ bool ftype;
21
+ bool restore_s16_s31;
22
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
* addresses don't have magic behaviour. However for the v8M
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
excret);
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
34
+ "if FPU not present\n",
35
+ excret);
36
+ ftype = true;
37
+ }
38
+
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
41
* we pick which FAULTMASK to clear.
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
43
*/
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
45
46
+ /*
47
+ * Clear scratch FP values left in caller saved registers; this
48
+ * must happen before any kind of tail chaining.
49
+ */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
56
+ "stackframe: error during lazy state deactivation\n");
57
+ v7m_exception_taken(cpu, excret, true, false);
58
+ return;
59
+ } else {
60
+ /* Clear s0..s15 and FPSCR */
61
+ int i;
62
+
63
+ for (i = 0; i < 16; i += 2) {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
65
+ }
66
+ vfp_set_fpscr(env, 0);
67
+ }
68
+ }
69
+
70
if (sfault) {
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
74
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
196
2.20.1
197
198
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add an x-rme cpu property to enable FEAT_RME.
4
Add an x-l0gptsz property to set GPCCR_EL3.L0GPTSZ,
5
for testing various possible configurations.
6
7
We're not currently completely sure whether FEAT_RME will
8
be OK to enable purely as a CPU-level property, or if it will
9
need board co-operation, so we're making these experimental
10
x- properties, so that the people developing the system
11
level software for RME can try to start using this and let
12
us know how it goes. The command line syntax for enabling
13
this will change in future, without backwards-compatibility.
14
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20230620124418.805717-21-richard.henderson@linaro.org
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
6
---
19
---
7
target/arm/helper.h | 1 +
20
target/arm/tcg/cpu64.c | 53 ++++++++++++++++++++++++++++++++++++++++++
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 53 insertions(+)
9
target/arm/translate.c | 2 +-
10
3 files changed, 56 insertions(+), 1 deletion(-)
11
22
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
23
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
13
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
25
--- a/target/arm/tcg/cpu64.c
15
+++ b/target/arm/helper.h
26
+++ b/target/arm/tcg/cpu64.c
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
27
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
28
cpu->sve_max_vq = max_vq;
18
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
29
g_assert_not_reached();
30
}
29
}
31
30
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
31
+static bool cpu_arm_get_rme(Object *obj, Error **errp)
33
+{
32
+{
34
+ /* translate.c should never generate calls here in user-only mode */
33
+ ARMCPU *cpu = ARM_CPU(obj);
35
+ g_assert_not_reached();
34
+ return cpu_isar_feature(aa64_rme, cpu);
36
+}
35
+}
37
+
36
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
37
+static void cpu_arm_set_rme(Object *obj, bool value, Error **errp)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
38
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
39
+ ARMCPU *cpu = ARM_CPU(obj);
48
+ assert(env->v7m.secure);
40
+ uint64_t t;
49
+
41
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
42
+ t = cpu->isar.id_aa64pfr0;
43
+ t = FIELD_DP64(t, ID_AA64PFR0, RME, value);
44
+ cpu->isar.id_aa64pfr0 = t;
45
+}
46
+
47
+static void cpu_max_set_l0gptsz(Object *obj, Visitor *v, const char *name,
48
+ void *opaque, Error **errp)
49
+{
50
+ ARMCPU *cpu = ARM_CPU(obj);
51
+ uint32_t value;
52
+
53
+ if (!visit_type_uint32(v, name, &value, errp)) {
51
+ return;
54
+ return;
52
+ }
55
+ }
53
+
56
+
54
+ /* Check access to the coprocessor is permitted */
57
+ /* Encode the value for the GPCCR_EL3 field. */
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
58
+ switch (value) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
59
+ case 30:
60
+ case 34:
61
+ case 36:
62
+ case 39:
63
+ cpu->reset_l0gptsz = value - 30;
64
+ break;
65
+ default:
66
+ error_setg(errp, "invalid value for l0gptsz");
67
+ error_append_hint(errp, "valid values are 30, 34, 36, 39\n");
68
+ break;
57
+ }
69
+ }
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
60
+ /* State in FP is still valid */
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
91
+}
70
+}
92
+
71
+
93
static bool v7m_push_stack(ARMCPU *cpu)
72
+static void cpu_max_get_l0gptsz(Object *obj, Visitor *v, const char *name,
94
{
73
+ void *opaque, Error **errp)
95
/* Do the "set up stack frame" part of exception entry,
74
+{
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
+ ARMCPU *cpu = ARM_CPU(obj);
97
index XXXXXXX..XXXXXXX 100644
76
+ uint32_t value = cpu->reset_l0gptsz + 30;
98
--- a/target/arm/translate.c
77
+
99
+++ b/target/arm/translate.c
78
+ visit_type_uint32(v, name, &value, errp);
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
79
+}
101
TCGv_i32 fptr = load_reg(s, rn);
80
+
102
81
static Property arm_cpu_lpa2_property =
103
if (extract32(insn, 20, 1)) {
82
DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
104
- /* VLLDM */
83
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
84
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
106
} else {
85
aarch64_add_sme_properties(obj);
107
gen_helper_v7m_vlstm(cpu_env, fptr);
86
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
108
}
87
cpu_max_set_sve_max_vq, NULL, NULL);
88
+ object_property_add_bool(obj, "x-rme", cpu_arm_get_rme, cpu_arm_set_rme);
89
+ object_property_add(obj, "x-l0gptsz", "uint32", cpu_max_get_l0gptsz,
90
+ cpu_max_set_l0gptsz, NULL, NULL);
91
qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
92
}
93
109
--
94
--
110
2.20.1
95
2.34.1
111
112
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20230622143046.1578160-1-richard.henderson@linaro.org
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
6
[PMM: fixed typo; note experimental status in emulation.rst too]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
8
---
9
include/hw/devices.h | 14 --------------
9
docs/system/arm/cpu-features.rst | 23 +++++++++++++++++++++++
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
10
docs/system/arm/emulation.rst | 1 +
11
hw/arm/nseries.c | 1 +
11
2 files changed, 24 insertions(+)
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
12
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
13
diff --git a/docs/system/arm/cpu-features.rst b/docs/system/arm/cpu-features.rst
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
15
--- a/docs/system/arm/cpu-features.rst
20
+++ b/include/hw/devices.h
16
+++ b/docs/system/arm/cpu-features.rst
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
17
@@ -XXX,XX +XXX,XX @@ As with ``sve-default-vector-length``, if the default length is larger
22
/* stellaris_input.c */
18
than the maximum vector length enabled, the actual vector length will
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
19
be reduced. If this property is set to ``-1`` then the default vector
24
20
length is set to the maximum possible length.
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
49
+ * Based on reverse-engineering of a linux driver.
50
+ *
51
+ * Copyright (C) 2008 Nokia Corporation
52
+ * Written by Andrzej Zaborowski
53
+ *
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
56
+ */
57
+
21
+
58
+#ifndef HW_MISC_CBUS_H
22
+RME CPU Properties
59
+#define HW_MISC_CBUS_H
23
+==================
60
+
24
+
61
+#include "hw/irq.h"
25
+The status of RME support with QEMU is experimental. At this time we
26
+only support RME within the CPU proper, not within the SMMU or GIC.
27
+The feature is enabled by the CPU property ``x-rme``, with the ``x-``
28
+prefix present as a reminder of the experimental status, and defaults off.
62
+
29
+
63
+typedef struct {
30
+The method for enabling RME will change in some future QEMU release
64
+ qemu_irq clk;
31
+without notice or backward compatibility.
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
32
+
69
+CBus *cbus_init(qemu_irq dat_out);
33
+RME Level 0 GPT Size Property
70
+void cbus_attach(CBus *bus, void *slave_opaque);
34
+-----------------------------
71
+
35
+
72
+void *retu_init(qemu_irq irq, int vilma);
36
+To aid firmware developers in testing different possible CPU
73
+void *tahvo_init(qemu_irq irq, int betty);
37
+configurations, ``x-l0gptsz=S`` may be used to specify the value
38
+to encode into ``GPCCR_EL3.L0GPTSZ``, a read-only field that
39
+specifies the size of the Level 0 Granule Protection Table.
40
+Legal values for ``S`` are 30, 34, 36, and 39; the default is 30.
74
+
41
+
75
+void retu_key_event(void *retu, int state);
42
+As with ``x-rme``, the ``x-l0gptsz`` property may be renamed or
76
+
43
+removed in some future QEMU release.
77
+#endif
44
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
46
--- a/docs/system/arm/emulation.rst
81
+++ b/hw/arm/nseries.c
47
+++ b/docs/system/arm/emulation.rst
82
@@ -XXX,XX +XXX,XX @@
48
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
83
#include "hw/i2c/i2c.h"
49
- FEAT_RAS (Reliability, availability, and serviceability)
84
#include "hw/devices.h"
50
- FEAT_RASv1p1 (RAS Extension v1.1)
85
#include "hw/display/blizzard.h"
51
- FEAT_RDM (Advanced SIMD rounding double multiply accumulate instructions)
86
+#include "hw/misc/cbus.h"
52
+- FEAT_RME (Realm Management Extension) (NB: support status in QEMU is experimental)
87
#include "hw/misc/tmp105.h"
53
- FEAT_RNG (Random number generator)
88
#include "hw/block/flash.h"
54
- FEAT_S2FWB (Stage 2 forced Write-Back)
89
#include "hw/hw.h"
55
- FEAT_SB (Speculation Barrier)
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/misc/cbus.c
93
+++ b/hw/misc/cbus.c
94
@@ -XXX,XX +XXX,XX @@
95
#include "qemu/osdep.h"
96
#include "hw/hw.h"
97
#include "hw/irq.h"
98
-#include "hw/devices.h"
99
+#include "hw/misc/cbus.h"
100
#include "sysemu/sysemu.h"
101
102
//#define DEBUG
103
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
112
113
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
115
--
56
--
116
2.20.1
57
2.34.1
117
58
118
59
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
We use __builtin_subcll() to do a 64-bit subtract with borrow-in and
2
for v7M, where the caller specifies all of the security
2
borrow-out when the host compiler supports it. Unfortunately some
3
state, privilege level and whether the execution priority
3
versions of Apple Clang have a bug in their implementation of this
4
is negative, and reimplement the existing
4
intrinsic which means it returns the wrong value. The effect is that
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
5
a QEMU built with the affected compiler will hang when emulating x86
6
or m68k float80 division.
6
7
7
We are going to need this for the lazy-FP-stacking code.
8
The upstream LLVM issue is:
9
https://github.com/llvm/llvm-project/issues/55253
8
10
11
The commit that introduced the bug apparently never made it into an
12
upstream LLVM release without the subsequent fix
13
https://github.com/llvm/llvm-project/commit/fffb6e6afdbaba563189c1f715058ed401fbc88d
14
but unfortunately it did make it into Apple Clang 14.0, as shipped
15
in Xcode 14.3 (14.2 is reported to be OK). The Apple bug number is
16
FB12210478.
17
18
Add ifdefs to avoid use of __builtin_subcll() on Apple Clang version
19
14 or greater. There is not currently a version of Apple Clang which
20
has the bug fix -- when one appears we should be able to add an upper
21
bound to the ifdef condition so we can start using the builtin again.
22
We make the lower bound a conservative "any Apple clang with major
23
version 14 or greater" because the consequences of incorrectly
24
disabling the builtin when it would work are pretty small and the
25
consequences of not disabling it when we should are pretty bad.
26
27
Many thanks to those users who both reported this bug and also
28
did a lot of work in identifying the root cause; in particular
29
to Daniel Bertalan and osy.
30
31
Cc: qemu-stable@nongnu.org
32
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1631
33
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1659
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
35
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
36
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
37
Tested-by: Daniel Bertalan <dani@danielbertalan.dev>
38
Tested-by: Tested-By: Solra Bizna <solra@bizna.name>
39
Message-id: 20230622130823.1631719-1-peter.maydell@linaro.org
12
---
40
---
13
target/arm/cpu.h | 7 +++++++
41
include/qemu/compiler.h | 13 +++++++++++++
14
target/arm/helper.c | 14 +++++++++++---
42
include/qemu/host-utils.h | 2 +-
15
2 files changed, 18 insertions(+), 3 deletions(-)
43
2 files changed, 14 insertions(+), 1 deletion(-)
16
44
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
45
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
18
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
47
--- a/include/qemu/compiler.h
20
+++ b/target/arm/cpu.h
48
+++ b/include/qemu/compiler.h
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
49
@@ -XXX,XX +XXX,XX @@
22
}
50
#define QEMU_DISABLE_CFI
23
}
51
#endif
24
52
25
+/*
53
+/*
26
+ * Return the MMU index for a v7M CPU with all relevant information
54
+ * Apple clang version 14 has a bug in its __builtin_subcll(); define
27
+ * manually specified.
55
+ * BUILTIN_SUBCLL_BROKEN for the offending versions so we can avoid it.
56
+ * When a version of Apple clang which has this bug fixed is released
57
+ * we can add an upper bound to this check.
58
+ * See https://gitlab.com/qemu-project/qemu/-/issues/1631
59
+ * and https://gitlab.com/qemu-project/qemu/-/issues/1659 for details.
60
+ * The bug never made it into any upstream LLVM releases, only Apple ones.
28
+ */
61
+ */
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
62
+#if defined(__apple_build_version__) && __clang_major__ >= 14
30
+ bool secstate, bool priv, bool negpri);
63
+#define BUILTIN_SUBCLL_BROKEN
64
+#endif
31
+
65
+
32
/* Return the MMU index for a v7M CPU in the specified security and
66
#endif /* COMPILER_H */
33
* privilege state.
67
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/qemu/host-utils.h
70
+++ b/include/qemu/host-utils.h
71
@@ -XXX,XX +XXX,XX @@ static inline uint64_t uadd64_carry(uint64_t x, uint64_t y, bool *pcarry)
34
*/
72
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
73
static inline uint64_t usub64_borrow(uint64_t x, uint64_t y, bool *pborrow)
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
40
return 0;
41
}
42
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
74
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
75
-#if __has_builtin(__builtin_subcll)
49
76
+#if __has_builtin(__builtin_subcll) && !defined(BUILTIN_SUBCLL_BROKEN)
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
77
unsigned long long b = *pborrow;
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
78
x = __builtin_subcll(x, y, b, &b);
52
}
79
*pborrow = b & 1;
53
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
55
+ if (negpri) {
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
57
}
58
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
60
return mmu_idx;
61
}
62
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
64
+ bool secstate, bool priv)
65
+{
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
67
+
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
69
+}
70
+
71
/* Return the MMU index for a v7M CPU in the specified security state */
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
73
{
74
--
80
--
75
2.20.1
81
2.34.1
76
82
77
83
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
One cannot test for feature aa32_simd_r32 without first
4
testing if AArch32 mode is supported at all. This leads to
5
6
qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither
7
8
for Apple M1 cpus.
9
10
We already have a check for ARMv8-A never setting vfp-d32 true,
11
so restructure the code so that AArch64 avoids the test entirely.
12
13
Reported-by: Mads Ynddal <mads@ynddal.dk>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Tested-by: Mads Ynddal <m.ynddal@samsung.com>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Cédric Le Goater <clg@kaod.org>
19
Reviewed-by: Mads Ynddal <m.ynddal@samsung.com>
20
Message-id: 20230619140216.402530-1-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
6
---
22
---
7
target/arm/cpu.c | 8 ++++++++
23
target/arm/cpu.c | 28 +++++++++++++++-------------
8
1 file changed, 8 insertions(+)
24
1 file changed, 15 insertions(+), 13 deletions(-)
9
25
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
26
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
28
--- a/target/arm/cpu.c
13
+++ b/target/arm/cpu.c
29
+++ b/target/arm/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
30
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
15
set_feature(&cpu->env, ARM_FEATURE_M);
31
* KVM does not currently allow us to lie to the guest about its
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
32
* ID/feature registers, so the guest always sees what the host has.
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
33
*/
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
34
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
19
cpu->midr = 0x410fc240; /* r0p0 */
35
- ? cpu_isar_feature(aa64_fp_simd, cpu)
20
cpu->pmsav7_dregion = 8;
36
- : cpu_isar_feature(aa32_vfp, cpu)) {
21
+ cpu->isar.mvfr0 = 0x10110021;
37
- cpu->has_vfp = true;
22
+ cpu->isar.mvfr1 = 0x11000011;
38
- if (!kvm_enabled()) {
23
+ cpu->isar.mvfr2 = 0x00000000;
39
- qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
24
cpu->id_pfr0 = 0x00000030;
40
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
25
cpu->id_pfr1 = 0x00000200;
41
+ if (cpu_isar_feature(aa64_fp_simd, cpu)) {
26
cpu->id_dfr0 = 0x00100000;
42
+ cpu->has_vfp = true;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
43
+ cpu->has_vfp_d32 = true;
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
44
+ if (tcg_enabled() || qtest_enabled()) {
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
45
+ qdev_property_add_static(DEVICE(obj),
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
46
+ &arm_cpu_has_vfp_property);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
47
+ }
32
cpu->midr = 0x410fd213; /* r0p3 */
48
}
33
cpu->pmsav7_dregion = 16;
49
- }
34
cpu->sau_sregion = 8;
50
-
35
+ cpu->isar.mvfr0 = 0x10110021;
51
- if (cpu->has_vfp && cpu_isar_feature(aa32_simd_r32, cpu)) {
36
+ cpu->isar.mvfr1 = 0x11000011;
52
- cpu->has_vfp_d32 = true;
37
+ cpu->isar.mvfr2 = 0x00000040;
53
- if (!kvm_enabled()) {
38
cpu->id_pfr0 = 0x00000030;
54
+ } else if (cpu_isar_feature(aa32_vfp, cpu)) {
39
cpu->id_pfr1 = 0x00000210;
55
+ cpu->has_vfp = true;
40
cpu->id_dfr0 = 0x00200000;
56
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
57
+ cpu->has_vfp_d32 = true;
58
/*
59
* The permitted values of the SIMDReg bits [3:0] on
60
* Armv8-A are either 0b0000 and 0b0010. On such CPUs,
61
* make sure that has_vfp_d32 can not be set to false.
62
*/
63
- if (!(arm_feature(&cpu->env, ARM_FEATURE_V8) &&
64
- !arm_feature(&cpu->env, ARM_FEATURE_M))) {
65
+ if ((tcg_enabled() || qtest_enabled())
66
+ && !(arm_feature(&cpu->env, ARM_FEATURE_V8)
67
+ && !arm_feature(&cpu->env, ARM_FEATURE_M))) {
68
qdev_property_add_static(DEVICE(obj),
69
&arm_cpu_has_vfp_d32_property);
70
}
41
--
71
--
42
2.20.1
72
2.34.1
43
73
44
74
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Shashi Mallela <shashi.mallela@linaro.org>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Create ITS as part of SBSA platform GIC initialization.
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
6
4
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
5
GIC ITS information is in DeviceTree so TF-A can pass it to EDK2.
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
7
Bumping platform version to 0.2 as this is important hardware change.
8
9
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
10
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
11
Message-id: 20230619170913.517373-2-marcin.juszkiewicz@linaro.org
12
Co-authored-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
13
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
16
---
13
include/hw/devices.h | 3 ---
17
docs/system/arm/sbsa.rst | 14 ++++++++++++++
14
hw/display/tc6393xb.c | 16 ----------------
18
hw/arm/sbsa-ref.c | 33 ++++++++++++++++++++++++++++++---
15
2 files changed, 19 deletions(-)
19
2 files changed, 44 insertions(+), 3 deletions(-)
16
20
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
21
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
23
--- a/docs/system/arm/sbsa.rst
20
+++ b/include/hw/devices.h
24
+++ b/docs/system/arm/sbsa.rst
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
25
@@ -XXX,XX +XXX,XX @@ to be a complete compliant DT. It currently reports:
22
typedef struct TC6393xbState TC6393xbState;
26
- platform version
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- GIC addresses
24
uint32_t base, qemu_irq irq);
28
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
29
+Platform version
26
- qemu_irq handler);
30
+''''''''''''''''
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
31
+
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
32
The platform version is only for informing platform firmware about
29
33
what kind of ``sbsa-ref`` board it is running on. It is neither
30
#endif
34
a QEMU versioned machine type nor a reflection of the level of the
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ SBSA/SystemReady SR support provided.
36
The ``machine-version-major`` value is updated when changes breaking
37
fw compatibility are introduced. The ``machine-version-minor`` value
38
is updated when features are added that don't break fw compatibility.
39
+
40
+Platform version changes:
41
+
42
+0.0
43
+ Devicetree holds information about CPUs, memory and platform version.
44
+
45
+0.1
46
+ GIC information is present in devicetree.
47
+
48
+0.2
49
+ GIC ITS information is present in devicetree.
50
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
32
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
52
--- a/hw/arm/sbsa-ref.c
34
+++ b/hw/display/tc6393xb.c
53
+++ b/hw/arm/sbsa-ref.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
54
@@ -XXX,XX +XXX,XX @@ enum {
36
blanked : 1;
55
SBSA_CPUPERIPHS,
37
};
56
SBSA_GIC_DIST,
38
57
SBSA_GIC_REDIST,
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
58
+ SBSA_GIC_ITS,
40
-{
59
SBSA_SECURE_EC,
41
- return s->gpio_in;
60
SBSA_GWDT_WS0,
42
-}
61
SBSA_GWDT_REFRESH,
43
-
62
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sbsa_ref_memmap[] = {
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
63
[SBSA_CPUPERIPHS] = { 0x40000000, 0x00040000 },
64
[SBSA_GIC_DIST] = { 0x40060000, 0x00010000 },
65
[SBSA_GIC_REDIST] = { 0x40080000, 0x04000000 },
66
+ [SBSA_GIC_ITS] = { 0x44081000, 0x00020000 },
67
[SBSA_SECURE_EC] = { 0x50000000, 0x00001000 },
68
[SBSA_GWDT_REFRESH] = { 0x50010000, 0x00001000 },
69
[SBSA_GWDT_CONTROL] = { 0x50011000, 0x00001000 },
70
@@ -XXX,XX +XXX,XX @@ static void sbsa_fdt_add_gic_node(SBSAMachineState *sms)
71
2, sbsa_ref_memmap[SBSA_GIC_REDIST].base,
72
2, sbsa_ref_memmap[SBSA_GIC_REDIST].size);
73
74
+ nodename = g_strdup_printf("/intc/its");
75
+ qemu_fdt_add_subnode(sms->fdt, nodename);
76
+ qemu_fdt_setprop_sized_cells(sms->fdt, nodename, "reg",
77
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].base,
78
+ 2, sbsa_ref_memmap[SBSA_GIC_ITS].size);
79
+
80
g_free(nodename);
81
}
82
+
83
/*
84
* Firmware on this machine only uses ACPI table to load OS, these limited
85
* device tree nodes are just to let firmware know the info which varies from
86
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SBSAMachineState *sms)
87
* fw compatibility.
88
*/
89
qemu_fdt_setprop_cell(fdt, "/", "machine-version-major", 0);
90
- qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 1);
91
+ qemu_fdt_setprop_cell(fdt, "/", "machine-version-minor", 2);
92
93
if (ms->numa_state->have_numa_distance) {
94
int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
95
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
96
memory_region_add_subregion(secure_sysmem, base, secram);
97
}
98
99
-static void create_gic(SBSAMachineState *sms)
100
+static void create_its(SBSAMachineState *sms)
101
+{
102
+ const char *itsclass = its_class_name();
103
+ DeviceState *dev;
104
+
105
+ dev = qdev_new(itsclass);
106
+
107
+ object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(sms->gic),
108
+ &error_abort);
109
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, sbsa_ref_memmap[SBSA_GIC_ITS].base);
111
+}
112
+
113
+static void create_gic(SBSAMachineState *sms, MemoryRegion *mem)
45
{
114
{
46
// TC6393xbState *s = opaque;
115
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
116
SysBusDevice *gicbusdev;
48
// FIXME: how does the chip reflect the GPIO input level change?
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
118
qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
119
qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
120
121
+ object_property_set_link(OBJECT(sms->gic), "sysmem",
122
+ OBJECT(mem), &error_fatal);
123
+ qdev_prop_set_bit(sms->gic, "has-lpi", true);
124
+
125
gicbusdev = SYS_BUS_DEVICE(sms->gic);
126
sysbus_realize_and_unref(gicbusdev, &error_fatal);
127
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
128
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms)
129
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
130
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
131
}
132
+ create_its(sms);
49
}
133
}
50
134
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
135
static void create_uart(const SBSAMachineState *sms, int uart,
52
- qemu_irq handler)
136
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
53
-{
137
54
- if (line >= TC6393XB_GPIOS) {
138
create_secure_ram(sms, secure_sysmem);
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
139
56
- return;
140
- create_gic(sms);
57
- }
141
+ create_gic(sms, sysmem);
58
-
142
59
- s->handler[line] = handler;
143
create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
60
-}
144
create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
65
--
145
--
66
2.20.1
146
2.34.1
67
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
Brown bag time: store instead of load results in uninitialized temp.
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1704
7
Reported-by: Mark Rutland <mark.rutland@arm.com>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20230620134659.817559-1-richard.henderson@linaro.org
11
Fixes: e6dd5e782be ("target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r")
12
Tested-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
16
---
12
hw/dma/Makefile.objs | 2 +-
17
target/arm/tcg/translate-sve.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
14
19
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
20
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
16
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
22
--- a/target/arm/tcg/translate-sve.c
18
+++ b/hw/dma/Makefile.objs
23
+++ b/target/arm/tcg/translate-sve.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
24
@@ -XXX,XX +XXX,XX @@ void gen_sve_str(DisasContext *s, TCGv_ptr base, int vofs,
20
25
/* Predicate register stores can be any multiple of 2. */
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
26
if (len_remain >= 8) {
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
27
t0 = tcg_temp_new_i64();
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
28
- tcg_gen_st_i64(t0, base, vofs + len_align);
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
29
+ tcg_gen_ld_i64(t0, base, vofs + len_align);
30
tcg_gen_qemu_st_i64(t0, clean_addr, midx, MO_LEUQ | MO_ATOM_NONE);
31
len_remain -= 8;
32
len_align += 8;
25
--
33
--
26
2.20.1
34
2.34.1
27
35
28
36
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
The xkb official name for the Arabic keyboard layout is 'ara'.
2
of doing the lazy stacking of FP registers, the handling of
2
However xkb has for at least the past 15 years also permitted it to
3
possible escalation to HardFault is treated differently to the normal
3
be named via the legacy synonym 'ar'. In xkeyboard-config 2.39 this
4
approach: it works based on the saved information about exception
4
synoynm was removed, which breaks compilation of QEMU:
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
5
10
This corresponds to the pseudocode TakePreserveFPException().
6
FAILED: pc-bios/keymaps/ar
7
/home/fred/qemu-git/src/qemu/build-full/qemu-keymap -f pc-bios/keymaps/ar -l ar
8
xkbcommon: ERROR: Couldn't find file "symbols/ar" in include paths
9
xkbcommon: ERROR: 1 include paths searched:
10
xkbcommon: ERROR:     /usr/share/X11/xkb
11
xkbcommon: ERROR: 3 include paths could not be added:
12
xkbcommon: ERROR:     /home/fred/.config/xkb
13
xkbcommon: ERROR:     /home/fred/.xkb
14
xkbcommon: ERROR:     /etc/xkb
15
xkbcommon: ERROR: Abandoning symbols file "(unnamed)"
16
xkbcommon: ERROR: Failed to compile xkb_symbols
17
xkbcommon: ERROR: Failed to compile keymap
11
18
19
The upstream xkeyboard-config change removing the compat
20
mapping is:
21
https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/-/commit/470ad2cd8fea84d7210377161d86b31999bb5ea6
22
23
Make QEMU always ask for the 'ara' xkb layout, which should work on
24
both older and newer xkeyboard-config. We leave the QEMU name for
25
this keyboard layout as 'ar'; it is not the only one where our name
26
for it deviates from the xkb standard name.
27
28
Cc: qemu-stable@nongnu.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
32
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
33
Message-id: 20230620162024.1132013-1-peter.maydell@linaro.org
34
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1709
15
---
35
---
16
target/arm/cpu.h | 12 ++++++
36
pc-bios/keymaps/meson.build | 2 +-
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
37
1 file changed, 1 insertion(+), 1 deletion(-)
18
2 files changed, 108 insertions(+)
19
38
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
39
diff --git a/pc-bios/keymaps/meson.build b/pc-bios/keymaps/meson.build
21
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
41
--- a/pc-bios/keymaps/meson.build
23
+++ b/target/arm/cpu.h
42
+++ b/pc-bios/keymaps/meson.build
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
43
@@ -XXX,XX +XXX,XX @@
25
* a different exception).
44
keymaps = {
26
*/
45
- 'ar': '-l ar',
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
46
+ 'ar': '-l ara',
28
+/**
47
'bepo': '-l fr -v dvorak',
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
48
'cz': '-l cz',
30
+ * @opaque: the NVIC
49
'da': '-l dk',
31
+ * @irq: the exception number to mark pending
32
+ * @secure: false for non-banked exceptions or for the nonsecure
33
+ * version of a banked exception, true for the secure version of a banked
34
+ * exception.
35
+ *
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
37
+ * generated in the course of lazy stacking of FP registers.
38
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
50
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
52
+{
53
+ /*
54
+ * Pend an exception during lazy FP stacking. This differs
55
+ * from the usual exception pending because the logic for
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
59
+ NVICState *s = (NVICState *)opaque;
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
71
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
73
+ assert(!secure || banked);
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
78
+
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
85
+ break;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
101
+
102
+ if (escalate) {
103
+ /*
104
+ * Escalate to HardFault: faults that initially targeted Secure
105
+ * continue to do so, even if HF normally targets NonSecure.
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
116
+
117
+ if (!vec->enabled ||
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
120
+ /*
121
+ * We want to escalate to HardFault but the context the
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
130
+ if (escalate) {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
132
+ }
133
+ if (!vec->pending) {
134
+ vec->pending = 1;
135
+ /*
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
144
+ }
145
+}
146
+
147
/* Make pending IRQ active. */
148
void armv7m_nvic_acknowledge_irq(void *opaque)
149
{
150
--
50
--
151
2.20.1
51
2.34.1
152
52
153
53
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
include/hw/devices.h | 6 ------
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
10
hw/arm/tosa.c | 2 +-
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
19
+++ b/include/hw/devices.h
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Toshiba TC6393XB I/O Controller.
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
40
+ * Toshiba e-Series PDAs.
41
+ *
42
+ * Copyright (c) 2007 Hervé Poussineau
43
+ *
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
49
+#define HW_DISPLAY_TC6393XB_H
50
+
51
+#include "exec/memory.h"
52
+#include "hw/irq.h"
53
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
64
+++ b/hw/arm/tosa.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/hw.h"
67
#include "hw/arm/pxa.h"
68
#include "hw/arm/arm.h"
69
-#include "hw/devices.h"
70
#include "hw/arm/sharpsl.h"
71
#include "hw/pcmcia.h"
72
#include "hw/boards.h"
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
84
#include "hw/hw.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/tc6393xb.h"
87
#include "hw/block/flash.h"
88
#include "ui/console.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
102
--
103
2.20.1
104
105
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Add an entries the Blizzard device in MAINTAINERS.
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/devices.h | 7 -------
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
13
hw/arm/nseries.c | 1 +
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
22
+++ b/include/hw/devices.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
45
+ *
46
+ * Copyright (C) 2008 Nokia Corporation
47
+ * Written by Andrzej Zaborowski
48
+ *
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
50
+ * See the COPYING file in the top-level directory.
51
+ */
52
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
54
+#define HW_DISPLAY_BLIZZARD_H
55
+
56
+#include "hw/irq.h"
57
+
58
+void *s1d13745_init(qemu_irq gpio_int);
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
68
+++ b/hw/arm/nseries.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "hw/boards.h"
71
#include "hw/i2c/i2c.h"
72
#include "hw/devices.h"
73
+#include "hw/display/blizzard.h"
74
#include "hw/misc/tmp105.h"
75
#include "hw/block/flash.h"
76
#include "hw/hw.h"
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/blizzard.c
80
+++ b/hw/display/blizzard.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/osdep.h"
83
#include "qemu-common.h"
84
#include "ui/console.h"
85
-#include "hw/devices.h"
86
+#include "hw/display/blizzard.h"
87
#include "ui/pixel_ops.h"
88
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
108
2.20.1
109
110
diff view generated by jsdifflib