1
target-arm queue: Eric's SMMUv3 patchset, and an array
1
First pullreq for arm of the 4.1 series, since I'm back from
2
of minor bugfixes and improvements from various others.
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
3
6
4
thanks
7
thanks
5
-- PMM
8
-- PMM
6
9
7
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
8
11
9
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into staging (2018-05-04 14:42:46 +0100)
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
10
13
11
are available in the Git repository at:
14
are available in the Git repository at:
12
15
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180504
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
14
17
15
for you to fetch changes up to 5680740c92993e9b3f3e011f2a2c394070e33f56:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
16
19
17
hw/arm/virt: Introduce the iommu option (2018-05-04 18:05:52 +0100)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
18
21
19
----------------------------------------------------------------
22
----------------------------------------------------------------
20
target-arm queue:
23
target-arm queue:
21
* Emulate the SMMUv3 (IOMMU); one will be created in the 'virt' board
24
* remove "bag of random stuff" hw/devices.h header
22
if the commandline includes "-machine iommu=smmuv3"
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
23
* target/arm: Implement v8M VLLDM and VLSTM
26
* hw/dma: Compile the bcm2835_dma device as common object
24
* hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
27
* configure: Remove --source-path option
25
* Some fixes to silence Coverity false-positives
28
* hw/ssi/xilinx_spips: Avoid variable length array
26
* arm: boot: set boot_info starting from first_cpu
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
27
(fixes a technical bug not visible in practice)
28
* hw/net/smc91c111: Convert away from old_mmio
29
* hw/usb/tusb6010: Convert away from old_mmio
30
* hw/char/cmsdk-apb-uart.c: Accept more input after character read
31
* target/arm: Make MPUIR write-ignored on OMAP, StrongARM
32
* hw/arm/virt: Add linux,pci-domain property
33
30
34
----------------------------------------------------------------
31
----------------------------------------------------------------
35
Eric Auger (11):
32
Eric Auger (1):
36
hw/arm/smmu-common: smmu base device and datatypes
33
hw/arm/smmuv3: Remove SMMUNotifierNode
37
hw/arm/smmu-common: IOMMU memory region and address space setup
38
hw/arm/smmu-common: VMSAv8-64 page table walk
39
hw/arm/smmuv3: Wired IRQ and GERROR helpers
40
hw/arm/smmuv3: Queue helpers
41
hw/arm/smmuv3: Implement MMIO write operations
42
hw/arm/smmuv3: Event queue recording helper
43
hw/arm/smmuv3: Implement translate callback
44
hw/arm/smmuv3: Abort on vfio or vhost case
45
target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route
46
hw/arm/virt: Introduce the iommu option
47
34
48
Igor Mammedov (1):
35
Peter Maydell (28):
49
arm: boot: set boot_info starting from first_cpu
36
hw/ssi/xilinx_spips: Avoid variable length array
37
configure: Remove --source-path option
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
40
target/arm: Implement dummy versions of M-profile FP-related registers
41
target/arm: Disable most VFP sysregs for M-profile
42
target/arm: Honour M-profile FP enable bits
43
target/arm: Decode FP instructions for M profile
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
46
target/arm/helper: don't return early for STKOF faults during stacking
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
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
50
64
51
Jan Kiszka (1):
65
Philippe Mathieu-Daudé (13):
52
hw/arm/virt: Add linux,pci-domain property
66
hw/dma: Compile the bcm2835_dma device as common object
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
53
79
54
Mathew Maidment (1):
80
configure | 10 +-
55
target/arm: Correct MPUIR privilege level in register_cp_regs_for_features() conditional case
81
hw/dma/Makefile.objs | 2 +-
82
include/hw/arm/omap.h | 6 +-
83
include/hw/arm/smmu-common.h | 8 +-
84
include/hw/devices.h | 62 ---
85
include/hw/display/blizzard.h | 22 ++
86
include/hw/display/tc6393xb.h | 24 ++
87
include/hw/input/gamepad.h | 19 +
88
include/hw/input/tsc2xxx.h | 36 ++
89
include/hw/misc/cbus.h | 32 ++
90
include/hw/net/lan9118.h | 21 +
91
include/hw/net/ne2000-isa.h | 6 +
92
include/hw/net/smc91c111.h | 19 +
93
include/qemu/typedefs.h | 1 -
94
target/arm/cpu.h | 95 ++++-
95
target/arm/helper.h | 5 +
96
target/arm/translate.h | 3 +
97
hw/arm/aspeed.c | 13 +-
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
56
139
57
Patrick Oppenlander (1):
58
hw/char/cmsdk-apb-uart.c: Accept more input after character read
59
60
Peter Maydell (3):
61
hw/usb/tusb6010: Convert away from old_mmio
62
hw/net/smc91c111: Convert away from old_mmio
63
target/arm: Implement v8M VLLDM and VLSTM
64
65
Prem Mallappa (3):
66
hw/arm/smmuv3: Skeleton
67
hw/arm/virt: Add SMMUv3 to the virt board
68
hw/arm/virt-acpi-build: Add smmuv3 node in IORT table
69
70
Richard Henderson (2):
71
target/arm: Tidy conditions in handle_vec_simd_shri
72
target/arm: Tidy condition in disas_simd_two_reg_misc
73
74
Thomas Huth (1):
75
hw/arm: Don't fail qtest due to missing SD card in -nodefaults mode
76
77
hw/arm/Makefile.objs | 1 +
78
hw/arm/smmu-internal.h | 99 +++
79
hw/arm/smmuv3-internal.h | 621 ++++++++++++++++++
80
include/hw/acpi/acpi-defs.h | 15 +
81
include/hw/arm/smmu-common.h | 145 +++++
82
include/hw/arm/smmuv3.h | 87 +++
83
include/hw/arm/virt.h | 10 +
84
hw/arm/boot.c | 2 +-
85
hw/arm/omap1.c | 8 +-
86
hw/arm/omap2.c | 8 +-
87
hw/arm/pxa2xx.c | 15 +-
88
hw/arm/smmu-common.c | 372 +++++++++++
89
hw/arm/smmuv3.c | 1191 +++++++++++++++++++++++++++++++++++
90
hw/arm/virt-acpi-build.c | 55 +-
91
hw/arm/virt.c | 101 ++-
92
hw/char/cmsdk-apb-uart.c | 1 +
93
hw/net/smc91c111.c | 54 +-
94
hw/usb/tusb6010.c | 40 +-
95
target/arm/helper.c | 2 +-
96
target/arm/kvm.c | 38 +-
97
target/arm/translate-a64.c | 12 +-
98
target/arm/translate.c | 17 +-
99
default-configs/aarch64-softmmu.mak | 1 +
100
hw/arm/trace-events | 37 ++
101
target/arm/trace-events | 3 +
102
25 files changed, 2868 insertions(+), 67 deletions(-)
103
create mode 100644 hw/arm/smmu-internal.h
104
create mode 100644 hw/arm/smmuv3-internal.h
105
create mode 100644 include/hw/arm/smmu-common.h
106
create mode 100644 include/hw/arm/smmuv3.h
107
create mode 100644 hw/arm/smmu-common.c
108
create mode 100644 hw/arm/smmuv3.c
109
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
We set up the infrastructure to enumerate all the PCI devices
3
The SMMUNotifierNode struct is not necessary and brings extra
4
attached to the SMMU and create an associated IOMMU memory
4
complexity so let's remove it. We now directly track the SMMUDevices
5
region and address space.
5
which have registered IOMMU MR notifiers.
6
6
7
Those info are stored in SMMUDevice objects. The devices are
7
This is inspired from the same transformation on intel-iommu
8
grouped according to the PCIBus they belong to. A hash table
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
indexed by the PCIBus pointer is used. Also an array indexed by
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
the bus number allows to find the list of SMMUDevices.
11
10
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
15
Message-id: 1524665762-31355-3-git-send-email-eric.auger@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
15
---
18
include/hw/arm/smmu-common.h | 8 +++++
16
include/hw/arm/smmu-common.h | 8 ++------
19
hw/arm/smmu-common.c | 69 ++++++++++++++++++++++++++++++++++++
17
hw/arm/smmu-common.c | 6 +++---
20
hw/arm/trace-events | 3 ++
18
hw/arm/smmuv3.c | 28 +++++++---------------------
21
3 files changed, 80 insertions(+)
19
3 files changed, 12 insertions(+), 30 deletions(-)
22
20
23
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
24
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/smmu-common.h
23
--- a/include/hw/arm/smmu-common.h
26
+++ b/include/hw/arm/smmu-common.h
24
+++ b/include/hw/arm/smmu-common.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
28
#define ARM_SMMU_GET_CLASS(obj) \
26
AddressSpace as;
29
OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
27
uint32_t cfg_cache_hits;
30
28
uint32_t cfg_cache_misses;
31
+/* Return the SMMUPciBus handle associated to a PCI bus number */
29
+ QLIST_ENTRY(SMMUDevice) next;
32
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num);
30
} SMMUDevice;
33
+
31
34
+/* Return the stream ID of an SMMU device */
32
-typedef struct SMMUNotifierNode {
35
+static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
33
- SMMUDevice *sdev;
36
+{
34
- QLIST_ENTRY(SMMUNotifierNode) next;
37
+ return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
35
-} SMMUNotifierNode;
38
+}
36
-
39
#endif /* HW_ARM_SMMU_COMMON */
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;
40
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
41
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/arm/smmu-common.c
51
--- a/hw/arm/smmu-common.c
43
+++ b/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
44
@@ -XXX,XX +XXX,XX @@
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
45
#include "qemu/error-report.h"
54
/* Unmap all notifiers of all mr's */
46
#include "hw/arm/smmu-common.h"
55
void smmu_inv_notifiers_all(SMMUState *s)
47
56
{
48
+/**
57
- SMMUNotifierNode *node;
49
+ * The bus number is used for lookup when SID based invalidation occurs.
50
+ * In that case we lazily populate the SMMUPciBus array from the bus hash
51
+ * table. At the time the SMMUPciBus is created (smmu_find_add_as), the bus
52
+ * numbers may not be always initialized yet.
53
+ */
54
+SMMUPciBus *smmu_find_smmu_pcibus(SMMUState *s, uint8_t bus_num)
55
+{
56
+ SMMUPciBus *smmu_pci_bus = s->smmu_pcibus_by_bus_num[bus_num];
57
+
58
+ if (!smmu_pci_bus) {
59
+ GHashTableIter iter;
60
+
61
+ g_hash_table_iter_init(&iter, s->smmu_pcibus_by_busptr);
62
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&smmu_pci_bus)) {
63
+ if (pci_bus_num(smmu_pci_bus->bus) == bus_num) {
64
+ s->smmu_pcibus_by_bus_num[bus_num] = smmu_pci_bus;
65
+ return smmu_pci_bus;
66
+ }
67
+ }
68
+ }
69
+ return smmu_pci_bus;
70
+}
71
+
72
+static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
73
+{
74
+ SMMUState *s = opaque;
75
+ SMMUPciBus *sbus = g_hash_table_lookup(s->smmu_pcibus_by_busptr, bus);
76
+ SMMUDevice *sdev;
58
+ SMMUDevice *sdev;
77
+
59
78
+ if (!sbus) {
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
+ sbus = g_malloc0(sizeof(SMMUPciBus) +
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
80
+ sizeof(SMMUDevice *) * SMMU_PCI_DEVFN_MAX);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ sbus->bus = bus;
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
82
+ g_hash_table_insert(s->smmu_pcibus_by_busptr, bus, sbus);
64
}
83
+ }
65
}
84
+
66
85
+ sdev = sbus->pbdev[devfn];
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
86
+ if (!sdev) {
68
index XXXXXXX..XXXXXXX 100644
87
+ char *name = g_strdup_printf("%s-%d-%d",
69
--- a/hw/arm/smmuv3.c
88
+ s->mrtypename,
70
+++ b/hw/arm/smmuv3.c
89
+ pci_bus_num(bus), devfn);
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
90
+ sdev = sbus->pbdev[devfn] = g_new0(SMMUDevice, 1);
72
/* invalidate an asid/iova tuple in all mr's */
91
+
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
92
+ sdev->smmu = s;
93
+ sdev->bus = bus;
94
+ sdev->devfn = devfn;
95
+
96
+ memory_region_init_iommu(&sdev->iommu, sizeof(sdev->iommu),
97
+ s->mrtypename,
98
+ OBJECT(s), name, 1ULL << SMMU_MAX_VA_BITS);
99
+ address_space_init(&sdev->as,
100
+ MEMORY_REGION(&sdev->iommu), name);
101
+ trace_smmu_add_mr(name);
102
+ g_free(name);
103
+ }
104
+
105
+ return &sdev->as;
106
+}
107
+
108
static void smmu_base_realize(DeviceState *dev, Error **errp)
109
{
74
{
110
+ SMMUState *s = ARM_SMMU(dev);
75
- SMMUNotifierNode *node;
111
SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
76
+ SMMUDevice *sdev;
112
Error *local_err = NULL;
77
113
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
114
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
115
error_propagate(errp, local_err);
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
116
return;
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);
117
}
118
}
118
+
119
+ s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
120
+
121
+ if (s->primary_bus) {
122
+ pci_setup_iommu(s->primary_bus, smmu_find_add_as, s);
123
+ } else {
124
+ error_setg(errp, "SMMU is not attached to any PCI bus!");
125
+ }
126
}
119
}
127
120
128
static void smmu_base_reset(DeviceState *dev)
129
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/arm/trace-events
132
+++ b/hw/arm/trace-events
133
@@ -XXX,XX +XXX,XX @@
134
135
# hw/arm/virt-acpi-build.c
136
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
137
+
138
+# hw/arm/smmu-common.c
139
+smmu_add_mr(const char *name) "%s"
140
\ No newline at end of file
141
--
121
--
142
2.17.0
122
2.20.1
143
123
144
124
diff view generated by jsdifflib
New 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.
1
4
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
New 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.
1
5
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
New 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.
1
5
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
New 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.)
1
4
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
New patch
1
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
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
New 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.
1
5
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
From: Eric Auger <eric.auger@redhat.com>
1
Like AArch64, M-profile floating point has no FPEXC enable
2
bit to gate floating point; so always set the VFPEN TB flag.
2
3
3
ARM virt machine now exposes a new "iommu" option.
4
M-profile also has CPACR and NSACR similar to A-profile;
4
The SMMUv3 IOMMU is instantiated using -machine virt,iommu=smmuv3.
5
they behave slightly differently:
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
5
9
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Honour the CPACR and NSACR settings. The NSACR handling
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
requires us to borrow the exception.target_el field
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
(usually meaningless for M profile) to distinguish the
9
Message-id: 1524665762-31355-15-git-send-email-eric.auger@redhat.com
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
10
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
11
---
19
---
12
hw/arm/virt.c | 36 ++++++++++++++++++++++++++++++++++++
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
13
1 file changed, 36 insertions(+)
21
target/arm/translate.c | 10 ++++++--
22
2 files changed, 60 insertions(+), 5 deletions(-)
14
23
15
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/virt.c
26
--- a/target/arm/helper.c
18
+++ b/hw/arm/virt.c
27
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void virt_set_gic_version(Object *obj, const char *value, Error **errp)
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
20
}
29
return target_el;
21
}
30
}
22
31
23
+static char *virt_get_iommu(Object *obj, Error **errp)
32
+/*
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
34
+ * security state and privilege level.
35
+ */
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
24
+{
37
+{
25
+ VirtMachineState *vms = VIRT_MACHINE(obj);
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
26
+
39
+ case 0:
27
+ switch (vms->iommu) {
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
28
+ case VIRT_IOMMU_NONE:
41
+ return false;
29
+ return g_strdup("none");
42
+ case 1:
30
+ case VIRT_IOMMU_SMMUV3:
43
+ return is_priv;
31
+ return g_strdup("smmuv3");
44
+ case 3:
45
+ return true;
32
+ default:
46
+ default:
33
+ g_assert_not_reached();
47
+ g_assert_not_reached();
34
+ }
48
+ }
35
+}
49
+}
36
+
50
+
37
+static void virt_set_iommu(Object *obj, const char *value, Error **errp)
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
38
+{
52
ARMMMUIdx mmu_idx, bool ignfault)
39
+ VirtMachineState *vms = VIRT_MACHINE(obj);
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
+ /*
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
40
+
67
+
41
+ if (!strcmp(value, "smmuv3")) {
68
+ if (env->exception.target_el == 3) {
42
+ vms->iommu = VIRT_IOMMU_SMMUV3;
69
+ target_secstate = M_REG_S;
43
+ } else if (!strcmp(value, "none")) {
70
+ } else {
44
+ vms->iommu = VIRT_IOMMU_NONE;
71
+ target_secstate = env->v7m.secure;
45
+ } else {
72
+ }
46
+ error_setg(errp, "Invalid iommu value");
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
47
+ error_append_hint(errp, "Valid values are none, smmuv3.\n");
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
48
+ }
76
+ }
49
+}
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
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
50
+
89
+
51
static CpuInstanceProperties
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
52
virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
53
{
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
54
@@ -XXX,XX +XXX,XX @@ static void virt_2_12_instance_init(Object *obj)
93
+ return 3;
55
NULL);
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
}
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;
56
}
131
}
57
132
58
+ /* Default disallows iommu instantiation */
59
+ vms->iommu = VIRT_IOMMU_NONE;
60
+ object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu, NULL);
61
+ object_property_set_description(obj, "iommu",
62
+ "Set the IOMMU type. "
63
+ "Valid values are none and smmuv3",
64
+ NULL);
65
+
66
vms->memmap = a15memmap;
67
vms->irqmap = a15irqmap;
68
}
69
--
133
--
70
2.17.0
134
2.20.1
71
135
72
136
diff view generated by jsdifflib
1
For v8M the instructions VLLDM and VLSTM support lazy saving
1
Correct the decode of the M-profile "coprocessor and
2
and restoring of the secure floating-point registers. Even
2
floating-point instructions" space:
3
if the floating point extension is not implemented, these
3
* op0 == 0b11 is always unallocated
4
instructions must act as NOPs in Secure state, so they can
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
be used as part of the secure-to-nonsecure call sequence.
5
are floating point and go to disas_vfp_insn()
6
6
7
Fixes: https://bugs.launchpad.net/qemu/+bug/1768295
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
Cc: qemu-stable@nongnu.org
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180503105730.5958-1-peter.maydell@linaro.org
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
12
---
14
---
13
target/arm/translate.c | 17 ++++++++++++++++-
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
14
1 file changed, 16 insertions(+), 1 deletion(-)
16
1 file changed, 22 insertions(+), 4 deletions(-)
15
17
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.c
20
--- a/target/arm/translate.c
19
+++ b/target/arm/translate.c
21
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
21
/* Coprocessor. */
24
/* Coprocessor. */
22
if (arm_dc_feature(s, ARM_FEATURE_M)) {
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
23
/* We don't currently implement M profile FP support,
26
- /* We don't currently implement M profile FP support,
24
- * so this entire space should give a NOCP fault.
27
- * so this entire space should give a NOCP fault, with
25
+ * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
26
+ * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
27
+ * 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.
28
*/
43
*/
29
+ if (arm_dc_feature(s, ARM_FEATURE_V8) &&
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
30
+ (insn & 0xffa00f00) == 0xec200a00) {
45
(insn & 0xffa00f00) == 0xec200a00) {
31
+ /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
32
+ * - VLLDM, VLSTM
47
/* Just NOP since FP support is not implemented */
33
+ * We choose to UNDEF if the RAZ bits are non-zero.
48
break;
34
+ */
49
}
35
+ if (!s->v8m_secure || (insn & 0x0040f0ff)) {
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)) {
36
+ goto illegal_op;
54
+ goto illegal_op;
37
+ }
55
+ }
38
+ /* Just NOP since FP support is not implemented */
39
+ break;
56
+ break;
40
+ }
57
+ }
41
+ /* All other insns: NOCP */
58
+
59
/* All other insns: NOCP */
42
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
43
default_exception_el(s));
61
default_exception_el(s));
44
break;
45
--
62
--
46
2.17.0
63
2.20.1
47
64
48
65
diff view generated by jsdifflib
1
From: Patrick Oppenlander <patrick.oppenlander@gmail.com>
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
2
3
3
The character frontend needs to be notified that the uart receive buffer
4
(On a no-FPU system the bit will always be zero, so we don't need
4
is empty and ready to handle another character.
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
5
6
6
Previously, the uart only worked correctly when receiving one character
7
at a time.
8
9
Signed-off-by: Patrick Oppenlander <patrick.oppenlander@gmail.com>
10
Message-id: CAEg67GkRTw=cXei3o9hvpxG_L4zSrNzR0bFyAgny+sSEUb_kPw@mail.gmail.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
13
---
10
---
14
hw/char/cmsdk-apb-uart.c | 1 +
11
target/arm/helper.c | 1 +
15
1 file changed, 1 insertion(+)
12
1 file changed, 1 insertion(+)
16
13
17
diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/char/cmsdk-apb-uart.c
16
--- a/target/arm/helper.c
20
+++ b/hw/char/cmsdk-apb-uart.c
17
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t uart_read(void *opaque, hwaddr offset, unsigned size)
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
22
r = s->rxbuf;
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
23
s->state &= ~R_STATE_RXFULL_MASK;
20
", executing it\n", env->regs[15]);
24
cmsdk_apb_uart_update(s);
21
env->regs[14] &= ~1;
25
+ qemu_chr_fe_accept_input(&s->chr);
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
26
break;
23
switch_v7m_security_state(env, true);
27
case A_STATE:
24
xpsr_write(env, 0, XPSR_IT);
28
r = s->state;
25
env->regs[15] += 4;
29
--
26
--
30
2.17.0
27
2.20.1
31
28
32
29
diff view generated by jsdifflib
New 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.
1
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-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
New patch
1
Currently the code in v7m_push_stack() which detects a violation
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.
1
9
10
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
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
15
1 file changed, 18 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
22
* should ignore further stack faults trying to process
23
* that derived exception.)
24
*/
25
- bool stacked_ok;
26
+ bool stacked_ok = true, limitviol = false;
27
CPUARMState *env = &cpu->env;
28
uint32_t xpsr = xpsr_read(env);
29
uint32_t frameptr = env->regs[13];
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
32
env->v7m.secure);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
47
* (which may be taken in preference to the one we started with
48
* if it has higher priority).
49
*/
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
New 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().
1
4
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
1
From: Eric Auger <eric.auger@redhat.com>
1
Implement the code which updates the FPCCR register on an
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.
2
5
3
We introduce helpers to read/write into the command and event
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
circular queues.
7
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
8
---
9
target/arm/cpu.h | 14 +++++++++
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
12
3 files changed, 114 insertions(+), 1 deletion(-)
5
13
6
smmuv3_write_eventq and smmuv3_cmq_consume will become static
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
in subsequent patches.
8
9
Invalidation commands are not yet dealt with. We do not cache
10
data that need to be invalidated. This will change with vhost
11
integration.
12
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 1524665762-31355-7-git-send-email-eric.auger@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/arm/smmuv3-internal.h | 163 +++++++++++++++++++++++++++++++++++++++
20
hw/arm/smmuv3.c | 136 ++++++++++++++++++++++++++++++++
21
hw/arm/trace-events | 5 ++
22
3 files changed, 304 insertions(+)
23
24
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/smmuv3-internal.h
16
--- a/target/arm/cpu.h
27
+++ b/hw/arm/smmuv3-internal.h
17
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
29
void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
30
void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
20
*/
31
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
32
+/* Queue Handling */
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
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
+{
49
+ /*
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
51
+ * configured at a priority which would allow it to interrupt the
52
+ * current execution priority.
53
+ *
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);
33
+
62
+
34
+#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
35
+#define WRAP_MASK(q) (1 << (q)->log2size)
64
+ assert(!secure || banked);
36
+#define INDEX_MASK(q) (((1 << (q)->log2size)) - 1)
37
+#define WRAP_INDEX_MASK(q) ((1 << ((q)->log2size + 1)) - 1)
38
+
65
+
39
+#define Q_CONS(q) ((q)->cons & INDEX_MASK(q))
66
+ /*
40
+#define Q_PROD(q) ((q)->prod & INDEX_MASK(q))
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
+ }
41
+
74
+
42
+#define Q_CONS_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_CONS(q))
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
43
+#define Q_PROD_ENTRY(q) (Q_BASE(q) + (q)->entry_size * Q_PROD(q))
44
+
76
+
45
+#define Q_CONS_WRAP(q) (((q)->cons & WRAP_MASK(q)) >> (q)->log2size)
77
+ return vec->enabled &&
46
+#define Q_PROD_WRAP(q) (((q)->prod & WRAP_MASK(q)) >> (q)->log2size)
78
+ exc_group_prio(s, vec->prio, secure) < running;
47
+
48
+static inline bool smmuv3_q_full(SMMUQueue *q)
49
+{
50
+ return ((q->cons ^ q->prod) & WRAP_INDEX_MASK(q)) == WRAP_MASK(q);
51
+}
79
+}
52
+
80
+
53
+static inline bool smmuv3_q_empty(SMMUQueue *q)
81
/* callback when external interrupt line is changed */
54
+{
82
static void set_irq_level(void *opaque, int n, int level)
55
+ return (q->cons & WRAP_INDEX_MASK(q)) == (q->prod & WRAP_INDEX_MASK(q));
83
{
56
+}
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
57
+
85
index XXXXXXX..XXXXXXX 100644
58
+static inline void queue_prod_incr(SMMUQueue *q)
86
--- a/target/arm/helper.c
59
+{
87
+++ b/target/arm/helper.c
60
+ q->prod = (q->prod + 1) & WRAP_INDEX_MASK(q);
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
61
+}
89
env->thumb = addr & 1;
62
+
90
}
63
+static inline void queue_cons_incr(SMMUQueue *q)
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
64
+{
94
+{
65
+ /*
95
+ /*
66
+ * We have to use deposit for the CONS registers to preserve
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
67
+ * the ERR field in the high bits.
97
+ * that we will need later in order to do lazy FP reg stacking.
68
+ */
98
+ */
69
+ q->cons = deposit32(q->cons, 0, q->log2size + 1, q->cons + 1);
99
+ bool is_secure = env->v7m.secure;
70
+}
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;
71
+
111
+
72
+static inline bool smmuv3_cmdq_enabled(SMMUv3State *s)
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
73
+{
74
+ return FIELD_EX32(s->cr[0], CR0, CMDQEN);
75
+}
76
+
113
+
77
+static inline bool smmuv3_eventq_enabled(SMMUv3State *s)
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
78
+{
115
+ bool splimviol;
79
+ return FIELD_EX32(s->cr[0], CR0, EVENTQEN);
116
+ uint32_t splim = v7m_sp_limit(env);
80
+}
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
81
+
119
+
82
+static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
120
+ splimviol = !ign && frameptr < splim;
83
+{
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
84
+ s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
122
+ }
85
+}
86
+
123
+
87
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
88
+
125
+
89
+/* Commands */
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
90
+
127
+
91
+typedef enum SMMUCommandType {
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
92
+ SMMU_CMD_NONE = 0x00,
93
+ SMMU_CMD_PREFETCH_CONFIG ,
94
+ SMMU_CMD_PREFETCH_ADDR,
95
+ SMMU_CMD_CFGI_STE,
96
+ SMMU_CMD_CFGI_STE_RANGE,
97
+ SMMU_CMD_CFGI_CD,
98
+ SMMU_CMD_CFGI_CD_ALL,
99
+ SMMU_CMD_CFGI_ALL,
100
+ SMMU_CMD_TLBI_NH_ALL = 0x10,
101
+ SMMU_CMD_TLBI_NH_ASID,
102
+ SMMU_CMD_TLBI_NH_VA,
103
+ SMMU_CMD_TLBI_NH_VAA,
104
+ SMMU_CMD_TLBI_EL3_ALL = 0x18,
105
+ SMMU_CMD_TLBI_EL3_VA = 0x1a,
106
+ SMMU_CMD_TLBI_EL2_ALL = 0x20,
107
+ SMMU_CMD_TLBI_EL2_ASID,
108
+ SMMU_CMD_TLBI_EL2_VA,
109
+ SMMU_CMD_TLBI_EL2_VAA,
110
+ SMMU_CMD_TLBI_S12_VMALL = 0x28,
111
+ SMMU_CMD_TLBI_S2_IPA = 0x2a,
112
+ SMMU_CMD_TLBI_NSNH_ALL = 0x30,
113
+ SMMU_CMD_ATC_INV = 0x40,
114
+ SMMU_CMD_PRI_RESP,
115
+ SMMU_CMD_RESUME = 0x44,
116
+ SMMU_CMD_STALL_TERM,
117
+ SMMU_CMD_SYNC,
118
+} SMMUCommandType;
119
+
129
+
120
+static const char *cmd_stringify[] = {
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
121
+ [SMMU_CMD_PREFETCH_CONFIG] = "SMMU_CMD_PREFETCH_CONFIG",
131
+ !arm_v7m_is_handler_mode(env));
122
+ [SMMU_CMD_PREFETCH_ADDR] = "SMMU_CMD_PREFETCH_ADDR",
123
+ [SMMU_CMD_CFGI_STE] = "SMMU_CMD_CFGI_STE",
124
+ [SMMU_CMD_CFGI_STE_RANGE] = "SMMU_CMD_CFGI_STE_RANGE",
125
+ [SMMU_CMD_CFGI_CD] = "SMMU_CMD_CFGI_CD",
126
+ [SMMU_CMD_CFGI_CD_ALL] = "SMMU_CMD_CFGI_CD_ALL",
127
+ [SMMU_CMD_CFGI_ALL] = "SMMU_CMD_CFGI_ALL",
128
+ [SMMU_CMD_TLBI_NH_ALL] = "SMMU_CMD_TLBI_NH_ALL",
129
+ [SMMU_CMD_TLBI_NH_ASID] = "SMMU_CMD_TLBI_NH_ASID",
130
+ [SMMU_CMD_TLBI_NH_VA] = "SMMU_CMD_TLBI_NH_VA",
131
+ [SMMU_CMD_TLBI_NH_VAA] = "SMMU_CMD_TLBI_NH_VAA",
132
+ [SMMU_CMD_TLBI_EL3_ALL] = "SMMU_CMD_TLBI_EL3_ALL",
133
+ [SMMU_CMD_TLBI_EL3_VA] = "SMMU_CMD_TLBI_EL3_VA",
134
+ [SMMU_CMD_TLBI_EL2_ALL] = "SMMU_CMD_TLBI_EL2_ALL",
135
+ [SMMU_CMD_TLBI_EL2_ASID] = "SMMU_CMD_TLBI_EL2_ASID",
136
+ [SMMU_CMD_TLBI_EL2_VA] = "SMMU_CMD_TLBI_EL2_VA",
137
+ [SMMU_CMD_TLBI_EL2_VAA] = "SMMU_CMD_TLBI_EL2_VAA",
138
+ [SMMU_CMD_TLBI_S12_VMALL] = "SMMU_CMD_TLBI_S12_VMALL",
139
+ [SMMU_CMD_TLBI_S2_IPA] = "SMMU_CMD_TLBI_S2_IPA",
140
+ [SMMU_CMD_TLBI_NSNH_ALL] = "SMMU_CMD_TLBI_NSNH_ALL",
141
+ [SMMU_CMD_ATC_INV] = "SMMU_CMD_ATC_INV",
142
+ [SMMU_CMD_PRI_RESP] = "SMMU_CMD_PRI_RESP",
143
+ [SMMU_CMD_RESUME] = "SMMU_CMD_RESUME",
144
+ [SMMU_CMD_STALL_TERM] = "SMMU_CMD_STALL_TERM",
145
+ [SMMU_CMD_SYNC] = "SMMU_CMD_SYNC",
146
+};
147
+
132
+
148
+static inline const char *smmu_cmd_string(SMMUCommandType type)
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
149
+{
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
150
+ if (type > SMMU_CMD_NONE && type < ARRAY_SIZE(cmd_stringify)) {
135
+
151
+ return cmd_stringify[type] ? cmd_stringify[type] : "UNKNOWN";
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
152
+ } else {
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
153
+ return "INVALID";
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
+ }
154
+ }
155
+}
155
+}
156
+
156
+
157
+/* CMDQ fields */
157
static bool v7m_push_stack(ARMCPU *cpu)
158
+
159
+typedef enum {
160
+ SMMU_CERROR_NONE = 0,
161
+ SMMU_CERROR_ILL,
162
+ SMMU_CERROR_ABT,
163
+ SMMU_CERROR_ATC_INV_SYNC,
164
+} SMMUCmdError;
165
+
166
+enum { /* Command completion notification */
167
+ CMD_SYNC_SIG_NONE,
168
+ CMD_SYNC_SIG_IRQ,
169
+ CMD_SYNC_SIG_SEV,
170
+};
171
+
172
+#define CMD_TYPE(x) extract32((x)->word[0], 0 , 8)
173
+#define CMD_SSEC(x) extract32((x)->word[0], 10, 1)
174
+#define CMD_SSV(x) extract32((x)->word[0], 11, 1)
175
+#define CMD_RESUME_AC(x) extract32((x)->word[0], 12, 1)
176
+#define CMD_RESUME_AB(x) extract32((x)->word[0], 13, 1)
177
+#define CMD_SYNC_CS(x) extract32((x)->word[0], 12, 2)
178
+#define CMD_SSID(x) extract32((x)->word[0], 12, 20)
179
+#define CMD_SID(x) ((x)->word[1])
180
+#define CMD_VMID(x) extract32((x)->word[1], 0 , 16)
181
+#define CMD_ASID(x) extract32((x)->word[1], 16, 16)
182
+#define CMD_RESUME_STAG(x) extract32((x)->word[2], 0 , 16)
183
+#define CMD_RESP(x) extract32((x)->word[2], 11, 2)
184
+#define CMD_LEAF(x) extract32((x)->word[2], 0 , 1)
185
+#define CMD_STE_RANGE(x) extract32((x)->word[2], 0 , 5)
186
+#define CMD_ADDR(x) ({ \
187
+ uint64_t high = (uint64_t)(x)->word[3]; \
188
+ uint64_t low = extract32((x)->word[2], 12, 20); \
189
+ uint64_t addr = high << 32 | (low << 12); \
190
+ addr; \
191
+ })
192
+
193
+int smmuv3_cmdq_consume(SMMUv3State *s);
194
+
195
#endif
196
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/arm/smmuv3.c
199
+++ b/hw/arm/smmuv3.c
200
@@ -XXX,XX +XXX,XX @@ void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
201
trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
202
}
203
204
+static inline MemTxResult queue_read(SMMUQueue *q, void *data)
205
+{
206
+ dma_addr_t addr = Q_CONS_ENTRY(q);
207
+
208
+ return dma_memory_read(&address_space_memory, addr, data, q->entry_size);
209
+}
210
+
211
+static MemTxResult queue_write(SMMUQueue *q, void *data)
212
+{
213
+ dma_addr_t addr = Q_PROD_ENTRY(q);
214
+ MemTxResult ret;
215
+
216
+ ret = dma_memory_write(&address_space_memory, addr, data, q->entry_size);
217
+ if (ret != MEMTX_OK) {
218
+ return ret;
219
+ }
220
+
221
+ queue_prod_incr(q);
222
+ return MEMTX_OK;
223
+}
224
+
225
+void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
226
+{
227
+ SMMUQueue *q = &s->eventq;
228
+
229
+ if (!smmuv3_eventq_enabled(s)) {
230
+ return;
231
+ }
232
+
233
+ if (smmuv3_q_full(q)) {
234
+ return;
235
+ }
236
+
237
+ queue_write(q, evt);
238
+
239
+ if (smmuv3_q_empty(q)) {
240
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
241
+ }
242
+}
243
+
244
static void smmuv3_init_regs(SMMUv3State *s)
245
{
158
{
246
/**
159
/* Do the "set up stack frame" part of exception entry,
247
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
248
s->sid_split = 0;
161
}
249
}
162
} else {
250
163
/* Lazy stacking enabled, save necessary info to stack later */
251
+int smmuv3_cmdq_consume(SMMUv3State *s)
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
252
+{
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
253
+ SMMUCmdError cmd_error = SMMU_CERROR_NONE;
166
}
254
+ SMMUQueue *q = &s->cmdq;
167
}
255
+ SMMUCommandType type = 0;
168
}
256
+
257
+ if (!smmuv3_cmdq_enabled(s)) {
258
+ return 0;
259
+ }
260
+ /*
261
+ * some commands depend on register values, typically CR0. In case those
262
+ * register values change while handling the command, spec says it
263
+ * is UNPREDICTABLE whether the command is interpreted under the new
264
+ * or old value.
265
+ */
266
+
267
+ while (!smmuv3_q_empty(q)) {
268
+ uint32_t pending = s->gerror ^ s->gerrorn;
269
+ Cmd cmd;
270
+
271
+ trace_smmuv3_cmdq_consume(Q_PROD(q), Q_CONS(q),
272
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
273
+
274
+ if (FIELD_EX32(pending, GERROR, CMDQ_ERR)) {
275
+ break;
276
+ }
277
+
278
+ if (queue_read(q, &cmd) != MEMTX_OK) {
279
+ cmd_error = SMMU_CERROR_ABT;
280
+ break;
281
+ }
282
+
283
+ type = CMD_TYPE(&cmd);
284
+
285
+ trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
286
+
287
+ switch (type) {
288
+ case SMMU_CMD_SYNC:
289
+ if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
290
+ smmuv3_trigger_irq(s, SMMU_IRQ_CMD_SYNC, 0);
291
+ }
292
+ break;
293
+ case SMMU_CMD_PREFETCH_CONFIG:
294
+ case SMMU_CMD_PREFETCH_ADDR:
295
+ case SMMU_CMD_CFGI_STE:
296
+ case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
297
+ case SMMU_CMD_CFGI_CD:
298
+ case SMMU_CMD_CFGI_CD_ALL:
299
+ case SMMU_CMD_TLBI_NH_ALL:
300
+ case SMMU_CMD_TLBI_NH_ASID:
301
+ case SMMU_CMD_TLBI_NH_VA:
302
+ case SMMU_CMD_TLBI_NH_VAA:
303
+ case SMMU_CMD_TLBI_EL3_ALL:
304
+ case SMMU_CMD_TLBI_EL3_VA:
305
+ case SMMU_CMD_TLBI_EL2_ALL:
306
+ case SMMU_CMD_TLBI_EL2_ASID:
307
+ case SMMU_CMD_TLBI_EL2_VA:
308
+ case SMMU_CMD_TLBI_EL2_VAA:
309
+ case SMMU_CMD_TLBI_S12_VMALL:
310
+ case SMMU_CMD_TLBI_S2_IPA:
311
+ case SMMU_CMD_TLBI_NSNH_ALL:
312
+ case SMMU_CMD_ATC_INV:
313
+ case SMMU_CMD_PRI_RESP:
314
+ case SMMU_CMD_RESUME:
315
+ case SMMU_CMD_STALL_TERM:
316
+ trace_smmuv3_unhandled_cmd(type);
317
+ break;
318
+ default:
319
+ cmd_error = SMMU_CERROR_ILL;
320
+ qemu_log_mask(LOG_GUEST_ERROR,
321
+ "Illegal command type: %d\n", CMD_TYPE(&cmd));
322
+ break;
323
+ }
324
+ if (cmd_error) {
325
+ break;
326
+ }
327
+ /*
328
+ * We only increment the cons index after the completion of
329
+ * the command. We do that because the SYNC returns immediately
330
+ * and does not check the completion of previous commands
331
+ */
332
+ queue_cons_incr(q);
333
+ }
334
+
335
+ if (cmd_error) {
336
+ trace_smmuv3_cmdq_consume_error(smmu_cmd_string(type), cmd_error);
337
+ smmu_write_cmdq_err(s, cmd_error);
338
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_CMDQ_ERR_MASK);
339
+ }
340
+
341
+ trace_smmuv3_cmdq_consume_out(Q_PROD(q), Q_CONS(q),
342
+ Q_PROD_WRAP(q), Q_CONS_WRAP(q));
343
+
344
+ return 0;
345
+}
346
+
347
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
348
unsigned size, MemTxAttrs attrs)
349
{
350
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
351
index XXXXXXX..XXXXXXX 100644
352
--- a/hw/arm/trace-events
353
+++ b/hw/arm/trace-events
354
@@ -XXX,XX +XXX,XX @@ smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
355
smmuv3_trigger_irq(int irq) "irq=%d"
356
smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
357
smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
358
+smmuv3_unhandled_cmd(uint32_t type) "Unhandled command type=%d"
359
+smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod=%d cons=%d prod.wrap=%d cons.wrap=%d"
360
+smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
361
+smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
362
+smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
363
--
169
--
364
2.17.0
170
2.20.1
365
171
366
172
diff view generated by jsdifflib
New 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.)
1
5
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
1
From: Mathew Maidment <mathew1800@gmail.com>
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.
2
5
3
The duplication of id_tlbtr_reginfo was unintentionally added within
4
3281af8114c6b8ead02f08b58e3c36895c1ea047 which should have been
5
id_mpuir_reginfo.
6
7
The effect was that for OMAP and StrongARM CPUs we would
8
incorrectly UNDEF writes to MPUIR rather than NOPing them.
9
10
Signed-off-by: Mathew Maidment <mathew1800@gmail.com>
11
Message-id: 20180501184933.37609-2-mathew1800@gmail.com
12
[PMM: tweak commit message]
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
15
---
9
---
16
target/arm/helper.c | 2 +-
10
target/arm/helper.c | 8 ++++++++
17
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 8 insertions(+)
18
12
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
24
for (r = id_cp_reginfo; r->type != ARM_CP_SENTINEL; r++) {
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
25
r->access = PL1_RW;
19
targets_secure ? "secure" : "nonsecure", exc);
26
}
20
27
- id_tlbtr_reginfo.access = PL1_RW;
21
+ if (dotailchain) {
28
+ id_mpuir_reginfo.access = PL1_RW;
22
+ /* Sanitize LR FType and PREFIX bits */
29
id_tlbtr_reginfo.access = PL1_RW;
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
30
}
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
31
if (arm_feature(env, ARM_FEATURE_V8)) {
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
--
32
--
33
2.17.0
33
2.20.1
34
34
35
35
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
The magic value pushed onto the callee stack as an integrity
2
check is different if floating point is present.
2
3
3
At the moment, the SMMUv3 does not support notification on
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
TLB invalidation. So let's log an error as soon as such notifier
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
gets enabled.
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
1 file changed, 19 insertions(+), 3 deletions(-)
6
10
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-11-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/smmuv3.c | 11 +++++++++++
13
1 file changed, 11 insertions(+)
14
15
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/smmuv3.c
13
--- a/target/arm/helper.c
18
+++ b/hw/arm/smmuv3.c
14
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
15
@@ -XXX,XX +XXX,XX @@ load_fail:
20
dc->realize = smmu_realize;
16
return false;
21
}
17
}
22
18
23
+static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
24
+ IOMMUNotifierFlag old,
25
+ IOMMUNotifierFlag new)
26
+{
20
+{
27
+ if (old == IOMMU_NOTIFIER_NONE) {
21
+ /*
28
+ warn_report("SMMUV3 does not support vhost/vfio integration yet: "
22
+ * Return the integrity signature value for the callee-saves
29
+ "devices of those types will not function properly");
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
29
+ sig |= 1;
30
+ }
30
+ }
31
+ return sig;
31
+}
32
+}
32
+
33
+
33
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
34
void *data)
35
bool ignore_faults)
35
{
36
{
36
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
37
38
bool stacked_ok;
38
imrc->translate = smmuv3_translate;
39
uint32_t limit;
39
+ imrc->notify_flag_changed = smmuv3_notify_flag_changed;
40
bool want_psp;
40
}
41
+ uint32_t sig;
41
42
42
static const TypeInfo smmuv3_type_info = {
43
if (dotailchain) {
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
46
/* Write as much of the stack frame as we can. A write failure may
47
* cause us to pend a derived exception.
48
*/
49
+ sig = v7m_integrity_sig(env, lr);
50
stacked_ok =
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
54
ignore_faults) &&
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
57
if (return_to_secure &&
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
60
- uint32_t expected_sig = 0xfefa125b;
61
uint32_t actual_sig;
62
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
64
65
- if (pop_ok && expected_sig != actual_sig) {
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);
43
--
70
--
44
2.17.0
71
2.20.1
45
72
46
73
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
Handle floating point registers in exception return.
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
2
4
3
This patch builds the smmuv3 node in the ACPI IORT table.
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(-)
4
11
5
The RID space of the root complex, which spans 0x0-0x10000
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
6
maps to streamid space 0x0-0x10000 in smmuv3, which in turn
7
maps to deviceid space 0x0-0x10000 in the ITS group.
8
9
The guest must feature the IOMMU probe deferral series
10
(https://lkml.org/lkml/2017/4/10/214) which fixes streamid
11
multiple lookup. This bug is not related to the SMMU emulation.
12
13
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
14
Signed-off-by: Eric Auger <eric.auger@redhat.com>
15
Reviewed-by: Shannon Zhao <zhaoshenglong@huawei.com>
16
Message-id: 1524665762-31355-14-git-send-email-eric.auger@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/acpi/acpi-defs.h | 15 ++++++++++
20
hw/arm/virt-acpi-build.c | 55 ++++++++++++++++++++++++++++++++-----
21
2 files changed, 63 insertions(+), 7 deletions(-)
22
23
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
24
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/acpi/acpi-defs.h
14
--- a/target/arm/helper.c
26
+++ b/include/hw/acpi/acpi-defs.h
15
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
28
} QEMU_PACKED;
17
bool rettobase = false;
29
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
18
bool exc_secure = false;
30
19
bool return_to_secure;
31
+struct AcpiIortSmmu3 {
20
+ bool ftype;
32
+ ACPI_IORT_NODE_HEADER_DEF
21
+ bool restore_s16_s31;
33
+ uint64_t base_address;
22
34
+ uint32_t flags;
23
/* If we're not in Handler mode then jumps to magic exception-exit
35
+ uint32_t reserved2;
24
* addresses don't have magic behaviour. However for the v8M
36
+ uint64_t vatos_address;
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
37
+ uint32_t model;
26
excret);
38
+ uint32_t event_gsiv;
27
}
39
+ uint32_t pri_gsiv;
28
40
+ uint32_t gerr_gsiv;
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
41
+ uint32_t sync_gsiv;
42
+ AcpiIortIdMapping id_mapping_array[0];
43
+} QEMU_PACKED;
44
+typedef struct AcpiIortSmmu3 AcpiIortSmmu3;
45
+
30
+
46
struct AcpiIortRC {
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
47
ACPI_IORT_NODE_HEADER_DEF
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
48
AcpiIortMemoryAccess memory_properties;
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
49
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
34
+ "if FPU not present\n",
50
index XXXXXXX..XXXXXXX 100644
35
+ excret);
51
--- a/hw/arm/virt-acpi-build.c
36
+ ftype = true;
52
+++ b/hw/arm/virt-acpi-build.c
53
@@ -XXX,XX +XXX,XX @@ build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned xsdt_tbl_offset)
54
}
55
56
static void
57
-build_iort(GArray *table_data, BIOSLinker *linker)
58
+build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
59
{
60
- int iort_start = table_data->len;
61
+ int nb_nodes, iort_start = table_data->len;
62
AcpiIortIdMapping *idmap;
63
AcpiIortItsGroup *its;
64
AcpiIortTable *iort;
65
- size_t node_size, iort_length;
66
+ AcpiIortSmmu3 *smmu;
67
+ size_t node_size, iort_length, smmu_offset = 0;
68
AcpiIortRC *rc;
69
70
iort = acpi_data_push(table_data, sizeof(*iort));
71
72
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
73
+ nb_nodes = 3; /* RC, ITS, SMMUv3 */
74
+ } else {
75
+ nb_nodes = 2; /* RC, ITS */
76
+ }
37
+ }
77
+
38
+
78
iort_length = sizeof(*iort);
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
79
- iort->node_count = cpu_to_le32(2); /* RC and ITS nodes */
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
80
+ iort->node_count = cpu_to_le32(nb_nodes);
41
* we pick which FAULTMASK to clear.
81
iort->node_offset = cpu_to_le32(sizeof(*iort));
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
82
43
*/
83
/* ITS group node */
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
84
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
45
85
its->its_count = cpu_to_le32(1);
46
+ /*
86
its->identifiers[0] = 0; /* MADT translation_id */
47
+ * Clear scratch FP values left in caller saved registers; this
87
48
+ * must happen before any kind of tail chaining.
88
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
49
+ */
89
+ int irq = vms->irqmap[VIRT_SMMU];
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;
90
+
62
+
91
+ /* SMMUv3 node */
63
+ for (i = 0; i < 16; i += 2) {
92
+ smmu_offset = iort->node_offset + node_size;
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
93
+ node_size = sizeof(*smmu) + sizeof(*idmap);
65
+ }
94
+ iort_length += node_size;
66
+ vfp_set_fpscr(env, 0);
95
+ smmu = acpi_data_push(table_data, node_size);
67
+ }
96
+
97
+ smmu->type = ACPI_IORT_NODE_SMMU_V3;
98
+ smmu->length = cpu_to_le16(node_size);
99
+ smmu->mapping_count = cpu_to_le32(1);
100
+ smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
101
+ smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
102
+ smmu->event_gsiv = cpu_to_le32(irq);
103
+ smmu->pri_gsiv = cpu_to_le32(irq + 1);
104
+ smmu->gerr_gsiv = cpu_to_le32(irq + 2);
105
+ smmu->sync_gsiv = cpu_to_le32(irq + 3);
106
+
107
+ /* Identity RID mapping covering the whole input RID range */
108
+ idmap = &smmu->id_mapping_array[0];
109
+ idmap->input_base = 0;
110
+ idmap->id_count = cpu_to_le32(0xFFFF);
111
+ idmap->output_base = 0;
112
+ /* output IORT node is the ITS group node (the first node) */
113
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
114
+ }
68
+ }
115
+
69
+
116
/* Root Complex Node */
70
if (sfault) {
117
node_size = sizeof(*rc) + sizeof(*idmap);
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
118
iort_length += node_size;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
119
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker)
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
120
idmap->input_base = 0;
74
}
121
idmap->id_count = cpu_to_le32(0xFFFF);
75
}
122
idmap->output_base = 0;
76
123
- /* output IORT node is the ITS group node (the first node) */
77
+ if (!ftype) {
124
- idmap->output_reference = cpu_to_le32(iort->node_offset);
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
+ }
125
+
90
+
126
+ if (vms->iommu == VIRT_IOMMU_SMMUV3) {
91
+ restore_s16_s31 = return_to_secure &&
127
+ /* output IORT node is the smmuv3 node */
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
128
+ idmap->output_reference = cpu_to_le32(smmu_offset);
93
+
129
+ } else {
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
130
+ /* output IORT node is the ITS group node (the first node) */
95
+ /* State in FPU is still valid, just clear LSPACT */
131
+ idmap->output_reference = cpu_to_le32(iort->node_offset);
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);
132
+ }
191
+ }
133
192
134
iort->length = cpu_to_le32(iort_length);
193
/* The restored xPSR exception field will be zero if we're
135
194
* resuming in Thread mode. If that doesn't match what the
136
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
137
138
if (its_class_name() && !vmc->no_its) {
139
acpi_add_table(table_offsets, tables_blob);
140
- build_iort(tables_blob, tables->linker);
141
+ build_iort(tables_blob, tables->linker, vms);
142
}
143
144
/* XSDT is pointed to by RSDP */
145
--
195
--
146
2.17.0
196
2.20.1
147
197
148
198
diff view generated by jsdifflib
New patch
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
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.
1
5
6
This rearrangement is not strictly necessary, but means that
7
we can put M-profile-only bits next to each other rather
8
than scattered across the flag word.
9
10
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
---
14
target/arm/cpu.h | 11 ++++++-----
15
1 file changed, 6 insertions(+), 5 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * Indicates whether cp register reads and writes by guest code should access
27
+ * the secure or nonsecure bank of banked registers; note that this is not
28
+ * the same thing as the current security state of the processor!
29
+ */
30
+FIELD(TBFLAG_A32, NS, 6, 1)
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
* checks on the other bits at runtime
36
*/
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
38
-/* Indicates whether cp register reads and writes by guest code should access
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
We are close to running out of TB flags for AArch32; we could
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.
1
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-18-peter.maydell@linaro.org
10
---
11
target/arm/cpu.h | 10 ++++++----
12
target/arm/cpu.c | 7 +++++++
13
target/arm/helper.c | 6 +++++-
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
25
+/*
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
27
+ * checks on the other bits at runtime. This shares the same bits as
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
29
+ */
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
31
/*
32
* Indicates whether cp register reads and writes by guest code should access
33
* the secure or nonsecure bank of banked registers; note that this is not
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
39
- * checks on the other bits at runtime
40
- */
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
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/cpu.c
48
+++ b/target/arm/cpu.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
51
}
52
53
+ /*
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
--
101
2.20.1
102
103
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
The M-profile FPCCR.S bit indicates the security status of
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.
2
6
3
Add code to instantiate an smmuv3 in virt machine. A new iommu
7
Implement this by adding a new TB flag which tracks whether
4
integer member is introduced in VirtMachineState to store the type
8
FPCCR.S is different from the current security state, so
5
of the iommu in use.
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.
6
11
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
12
Note that we will add the handling for the other work done
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
by ExecuteFPCheck() in later commits.
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
10
Message-id: 1524665762-31355-13-git-send-email-eric.auger@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
12
---
18
---
13
include/hw/arm/virt.h | 10 +++++++
19
target/arm/cpu.h | 2 ++
14
hw/arm/virt.c | 64 ++++++++++++++++++++++++++++++++++++++++++-
20
target/arm/translate.h | 1 +
15
2 files changed, 73 insertions(+), 1 deletion(-)
21
target/arm/helper.c | 5 +++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
16
24
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
27
--- a/target/arm/cpu.h
20
+++ b/include/hw/arm/virt.h
28
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
22
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
23
#define NUM_GICV2M_SPIS 64
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
24
#define NUM_VIRTIO_TRANSPORTS 32
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
25
+#define NUM_SMMU_IRQS 4
33
+/* For M profile only, set if FPCCR.S does not match current security state */
26
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
27
#define ARCH_GICV3_MAINT_IRQ 9
35
/* For M profile only, Handler (ie not Thread) mode */
28
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
29
@@ -XXX,XX +XXX,XX @@ enum {
37
/* For M profile only, whether we should generate stack-limit checks */
30
VIRT_GIC_V2M,
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
VIRT_GIC_ITS,
32
VIRT_GIC_REDIST,
33
+ VIRT_SMMU,
34
VIRT_UART,
35
VIRT_MMIO,
36
VIRT_RTC,
37
@@ -XXX,XX +XXX,XX @@ enum {
38
VIRT_SECURE_MEM,
39
};
40
41
+typedef enum VirtIOMMUType {
42
+ VIRT_IOMMU_NONE,
43
+ VIRT_IOMMU_SMMUV3,
44
+ VIRT_IOMMU_VIRTIO,
45
+} VirtIOMMUType;
46
+
47
typedef struct MemMapEntry {
48
hwaddr base;
49
hwaddr size;
50
@@ -XXX,XX +XXX,XX @@ typedef struct {
51
bool its;
52
bool virt;
53
int32_t gic_version;
54
+ VirtIOMMUType iommu;
55
struct arm_boot_info bootinfo;
56
const MemMapEntry *memmap;
57
const int *irqmap;
58
@@ -XXX,XX +XXX,XX @@ typedef struct {
59
uint32_t clock_phandle;
60
uint32_t gic_phandle;
61
uint32_t msi_phandle;
62
+ uint32_t iommu_phandle;
63
int psci_conduit;
64
} VirtMachineState;
65
66
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
67
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/virt.c
40
--- a/target/arm/translate.h
69
+++ b/hw/arm/virt.c
41
+++ b/target/arm/translate.h
70
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
71
#include "hw/smbios/smbios.h"
43
bool v7m_handler_mode;
72
#include "qapi/visitor.h"
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
73
#include "standard-headers/linux/input.h"
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
74
+#include "hw/arm/smmuv3.h"
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
75
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
76
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
48
* so that top level loop can generate correct syndrome information.
77
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
49
*/
78
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
79
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
51
index XXXXXXX..XXXXXXX 100644
80
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
52
--- a/target/arm/helper.c
81
[VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
53
+++ b/target/arm/helper.c
82
+ [VIRT_SMMU] = { 0x09050000, 0x00020000 },
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
83
[VIRT_MMIO] = { 0x0a000000, 0x00000200 },
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
84
/* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */
56
}
85
[VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 },
57
86
@@ -XXX,XX +XXX,XX @@ static const int a15irqmap[] = {
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
87
[VIRT_SECURE_UART] = 8,
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
88
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
89
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
90
+ [VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */
91
[VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */
92
};
93
94
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
95
0x7 /* PCI irq */);
96
}
97
98
-static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
99
+static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
100
+ PCIBus *bus)
101
+{
102
+ char *node;
103
+ const char compat[] = "arm,smmu-v3";
104
+ int irq = vms->irqmap[VIRT_SMMU];
105
+ int i;
106
+ hwaddr base = vms->memmap[VIRT_SMMU].base;
107
+ hwaddr size = vms->memmap[VIRT_SMMU].size;
108
+ const char irq_names[] = "eventq\0priq\0cmdq-sync\0gerror";
109
+ DeviceState *dev;
110
+
111
+ if (vms->iommu != VIRT_IOMMU_SMMUV3 || !vms->iommu_phandle) {
112
+ return;
113
+ }
61
+ }
114
+
62
+
115
+ dev = qdev_create(NULL, "arm-smmuv3");
63
*pflags = flags;
64
*cs_base = 0;
65
}
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
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 */
116
+
76
+
117
+ object_property_set_link(OBJECT(dev), OBJECT(bus), "primary-bus",
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
118
+ &error_abort);
78
+ if (s->v8m_fpccr_s_wrong) {
119
+ qdev_init_nofail(dev);
79
+ TCGv_i32 tmp;
120
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
80
+
121
+ for (i = 0; i < NUM_SMMU_IRQS; i++) {
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
122
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
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
+ }
123
+ }
91
+ }
124
+
92
+
125
+ node = g_strdup_printf("/smmuv3@%" PRIx64, base);
93
if (extract32(insn, 28, 4) == 0xf) {
126
+ qemu_fdt_add_subnode(vms->fdt, node);
94
/*
127
+ qemu_fdt_setprop(vms->fdt, node, "compatible", compat, sizeof(compat));
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
128
+ qemu_fdt_setprop_sized_cells(vms->fdt, node, "reg", 2, base, 2, size);
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
129
+
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
130
+ qemu_fdt_setprop_cells(vms->fdt, node, "interrupts",
98
regime_is_secure(env, dc->mmu_idx);
131
+ GIC_FDT_IRQ_TYPE_SPI, irq , GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
132
+ GIC_FDT_IRQ_TYPE_SPI, irq + 1, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
133
+ GIC_FDT_IRQ_TYPE_SPI, irq + 2, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI,
101
dc->cp_regs = cpu->cp_regs;
134
+ GIC_FDT_IRQ_TYPE_SPI, irq + 3, GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
102
dc->features = env->features;
135
+
136
+ qemu_fdt_setprop(vms->fdt, node, "interrupt-names", irq_names,
137
+ sizeof(irq_names));
138
+
139
+ qemu_fdt_setprop_cell(vms->fdt, node, "clocks", vms->clock_phandle);
140
+ qemu_fdt_setprop_string(vms->fdt, node, "clock-names", "apb_pclk");
141
+ qemu_fdt_setprop(vms->fdt, node, "dma-coherent", NULL, 0);
142
+
143
+ qemu_fdt_setprop_cell(vms->fdt, node, "#iommu-cells", 1);
144
+
145
+ qemu_fdt_setprop_cell(vms->fdt, node, "phandle", vms->iommu_phandle);
146
+ g_free(node);
147
+}
148
+
149
+static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
150
{
151
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
152
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
153
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
154
qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 1);
155
create_pcie_irq_map(vms, vms->gic_phandle, irq, nodename);
156
157
+ if (vms->iommu) {
158
+ vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
159
+
160
+ create_smmu(vms, pic, pci->bus);
161
+
162
+ qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
163
+ 0x0, vms->iommu_phandle, 0x0, 0x10000);
164
+ }
165
+
166
g_free(nodename);
167
}
168
103
169
--
104
--
170
2.17.0
105
2.20.1
171
106
172
107
diff view generated by jsdifflib
New patch
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
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().
1
8
9
Implement this with a new TB flag which tracks whether we
10
need to create a new FP context.
11
12
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
---
16
target/arm/cpu.h | 2 ++
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
30
+/* For M profile only, set if we must create a new FP context */
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
32
/* For M profile only, set if FPCCR.S does not match current security state */
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
34
/* For M profile only, Handler (ie not Thread) mode */
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate.h
38
+++ b/target/arm/translate.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
45
* so that top level loop can generate correct syndrome information.
46
*/
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
53
}
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
}
79
+
80
+ if (s->v7m_new_fp_ctxt_needed) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
99
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
106
}
107
108
if (extract32(insn, 28, 4) == 0xf) {
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
--
119
2.20.1
120
121
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Add a new helper function which returns the MMU index to use
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
2
6
3
Now we have relevant helpers for queue and irq
7
We are going to need this for the lazy-FP-stacking code.
4
management, let's implement MMIO write operations.
5
8
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 1524665762-31355-8-git-send-email-eric.auger@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
11
---
12
---
12
hw/arm/smmuv3-internal.h | 8 +-
13
target/arm/cpu.h | 7 +++++++
13
hw/arm/smmuv3.c | 170 +++++++++++++++++++++++++++++++++++++--
14
target/arm/helper.c | 14 +++++++++++---
14
hw/arm/trace-events | 6 ++
15
2 files changed, 18 insertions(+), 3 deletions(-)
15
3 files changed, 174 insertions(+), 10 deletions(-)
16
16
17
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/smmuv3-internal.h
19
--- a/target/arm/cpu.h
20
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ REG32(CR0, 0x20)
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
22
FIELD(CR0, EVENTQEN, 2, 1)
23
FIELD(CR0, CMDQEN, 3, 1)
24
25
+#define SMMU_CR0_RESERVED 0xFFFFFC20
26
+
27
REG32(CR0ACK, 0x24)
28
REG32(CR1, 0x28)
29
REG32(CR2, 0x2c)
30
@@ -XXX,XX +XXX,XX @@ static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
31
return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
32
}
33
34
-/* public until callers get introduced */
35
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
36
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
37
-
38
/* Queue Handling */
39
40
#define Q_BASE(q) ((q)->base & SMMU_BASE_ADDR_MASK)
41
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
42
addr; \
43
})
44
45
-int smmuv3_cmdq_consume(SMMUv3State *s);
46
+#define SMMU_FEATURE_2LVL_STE (1 << 0)
47
48
#endif
49
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmuv3.c
52
+++ b/hw/arm/smmuv3.c
53
@@ -XXX,XX +XXX,XX @@
54
* @irq: irq type
55
* @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
56
*/
57
-void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
58
+static void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq,
59
+ uint32_t gerror_mask)
60
{
61
62
bool pulse = false;
63
@@ -XXX,XX +XXX,XX @@ void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
64
}
22
}
65
}
23
}
66
24
67
-void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
25
+/*
68
+static void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
26
+ * Return the MMU index for a v7M CPU with all relevant information
69
{
27
+ * manually specified.
70
uint32_t pending = s->gerror ^ s->gerrorn;
28
+ */
71
uint32_t toggled = s->gerrorn ^ new_gerrorn;
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
72
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
30
+ bool secstate, bool priv, bool negpri);
73
s->sid_split = 0;
31
+
74
}
32
/* Return the MMU index for a v7M CPU in the specified security and
75
33
* privilege state.
76
-int smmuv3_cmdq_consume(SMMUv3State *s)
34
*/
77
+static int smmuv3_cmdq_consume(SMMUv3State *s)
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
78
{
36
index XXXXXXX..XXXXXXX 100644
79
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
37
--- a/target/arm/helper.c
80
SMMUQueue *q = &s->cmdq;
38
+++ b/target/arm/helper.c
81
@@ -XXX,XX +XXX,XX @@ int smmuv3_cmdq_consume(SMMUv3State *s)
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
82
return 0;
40
return 0;
83
}
41
}
84
42
85
+static MemTxResult smmu_writell(SMMUv3State *s, hwaddr offset,
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
86
+ uint64_t data, MemTxAttrs attrs)
44
- bool secstate, bool priv)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
49
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
52
}
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)
87
+{
65
+{
88
+ switch (offset) {
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
89
+ case A_GERROR_IRQ_CFG0:
67
+
90
+ s->gerror_irq_cfg0 = data;
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
91
+ return MEMTX_OK;
92
+ case A_STRTAB_BASE:
93
+ s->strtab_base = data;
94
+ return MEMTX_OK;
95
+ case A_CMDQ_BASE:
96
+ s->cmdq.base = data;
97
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
98
+ if (s->cmdq.log2size > SMMU_CMDQS) {
99
+ s->cmdq.log2size = SMMU_CMDQS;
100
+ }
101
+ return MEMTX_OK;
102
+ case A_EVENTQ_BASE:
103
+ s->eventq.base = data;
104
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
105
+ if (s->eventq.log2size > SMMU_EVENTQS) {
106
+ s->eventq.log2size = SMMU_EVENTQS;
107
+ }
108
+ return MEMTX_OK;
109
+ case A_EVENTQ_IRQ_CFG0:
110
+ s->eventq_irq_cfg0 = data;
111
+ return MEMTX_OK;
112
+ default:
113
+ qemu_log_mask(LOG_UNIMP,
114
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (WI)\n",
115
+ __func__, offset);
116
+ return MEMTX_OK;
117
+ }
118
+}
69
+}
119
+
70
+
120
+static MemTxResult smmu_writel(SMMUv3State *s, hwaddr offset,
71
/* Return the MMU index for a v7M CPU in the specified security state */
121
+ uint64_t data, MemTxAttrs attrs)
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
122
+{
123
+ switch (offset) {
124
+ case A_CR0:
125
+ s->cr[0] = data;
126
+ s->cr0ack = data & ~SMMU_CR0_RESERVED;
127
+ /* in case the command queue has been enabled */
128
+ smmuv3_cmdq_consume(s);
129
+ return MEMTX_OK;
130
+ case A_CR1:
131
+ s->cr[1] = data;
132
+ return MEMTX_OK;
133
+ case A_CR2:
134
+ s->cr[2] = data;
135
+ return MEMTX_OK;
136
+ case A_IRQ_CTRL:
137
+ s->irq_ctrl = data;
138
+ return MEMTX_OK;
139
+ case A_GERRORN:
140
+ smmuv3_write_gerrorn(s, data);
141
+ /*
142
+ * By acknowledging the CMDQ_ERR, SW may notify cmds can
143
+ * be processed again
144
+ */
145
+ smmuv3_cmdq_consume(s);
146
+ return MEMTX_OK;
147
+ case A_GERROR_IRQ_CFG0: /* 64b */
148
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 0, 32, data);
149
+ return MEMTX_OK;
150
+ case A_GERROR_IRQ_CFG0 + 4:
151
+ s->gerror_irq_cfg0 = deposit64(s->gerror_irq_cfg0, 32, 32, data);
152
+ return MEMTX_OK;
153
+ case A_GERROR_IRQ_CFG1:
154
+ s->gerror_irq_cfg1 = data;
155
+ return MEMTX_OK;
156
+ case A_GERROR_IRQ_CFG2:
157
+ s->gerror_irq_cfg2 = data;
158
+ return MEMTX_OK;
159
+ case A_STRTAB_BASE: /* 64b */
160
+ s->strtab_base = deposit64(s->strtab_base, 0, 32, data);
161
+ return MEMTX_OK;
162
+ case A_STRTAB_BASE + 4:
163
+ s->strtab_base = deposit64(s->strtab_base, 32, 32, data);
164
+ return MEMTX_OK;
165
+ case A_STRTAB_BASE_CFG:
166
+ s->strtab_base_cfg = data;
167
+ if (FIELD_EX32(data, STRTAB_BASE_CFG, FMT) == 1) {
168
+ s->sid_split = FIELD_EX32(data, STRTAB_BASE_CFG, SPLIT);
169
+ s->features |= SMMU_FEATURE_2LVL_STE;
170
+ }
171
+ return MEMTX_OK;
172
+ case A_CMDQ_BASE: /* 64b */
173
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 32, data);
174
+ s->cmdq.log2size = extract64(s->cmdq.base, 0, 5);
175
+ if (s->cmdq.log2size > SMMU_CMDQS) {
176
+ s->cmdq.log2size = SMMU_CMDQS;
177
+ }
178
+ return MEMTX_OK;
179
+ case A_CMDQ_BASE + 4: /* 64b */
180
+ s->cmdq.base = deposit64(s->cmdq.base, 32, 32, data);
181
+ return MEMTX_OK;
182
+ case A_CMDQ_PROD:
183
+ s->cmdq.prod = data;
184
+ smmuv3_cmdq_consume(s);
185
+ return MEMTX_OK;
186
+ case A_CMDQ_CONS:
187
+ s->cmdq.cons = data;
188
+ return MEMTX_OK;
189
+ case A_EVENTQ_BASE: /* 64b */
190
+ s->eventq.base = deposit64(s->eventq.base, 0, 32, data);
191
+ s->eventq.log2size = extract64(s->eventq.base, 0, 5);
192
+ if (s->eventq.log2size > SMMU_EVENTQS) {
193
+ s->eventq.log2size = SMMU_EVENTQS;
194
+ }
195
+ return MEMTX_OK;
196
+ case A_EVENTQ_BASE + 4:
197
+ s->eventq.base = deposit64(s->eventq.base, 32, 32, data);
198
+ return MEMTX_OK;
199
+ case A_EVENTQ_PROD:
200
+ s->eventq.prod = data;
201
+ return MEMTX_OK;
202
+ case A_EVENTQ_CONS:
203
+ s->eventq.cons = data;
204
+ return MEMTX_OK;
205
+ case A_EVENTQ_IRQ_CFG0: /* 64b */
206
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 0, 32, data);
207
+ return MEMTX_OK;
208
+ case A_EVENTQ_IRQ_CFG0 + 4:
209
+ s->eventq_irq_cfg0 = deposit64(s->eventq_irq_cfg0, 32, 32, data);
210
+ return MEMTX_OK;
211
+ case A_EVENTQ_IRQ_CFG1:
212
+ s->eventq_irq_cfg1 = data;
213
+ return MEMTX_OK;
214
+ case A_EVENTQ_IRQ_CFG2:
215
+ s->eventq_irq_cfg2 = data;
216
+ return MEMTX_OK;
217
+ default:
218
+ qemu_log_mask(LOG_UNIMP,
219
+ "%s Unexpected 32-bit access to 0x%"PRIx64" (WI)\n",
220
+ __func__, offset);
221
+ return MEMTX_OK;
222
+ }
223
+}
224
+
225
static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
226
unsigned size, MemTxAttrs attrs)
227
{
73
{
228
- /* not yet implemented */
229
- return MEMTX_ERROR;
230
+ SMMUState *sys = opaque;
231
+ SMMUv3State *s = ARM_SMMUV3(sys);
232
+ MemTxResult r;
233
+
234
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
235
+ offset &= ~0x10000;
236
+
237
+ switch (size) {
238
+ case 8:
239
+ r = smmu_writell(s, offset, data, attrs);
240
+ break;
241
+ case 4:
242
+ r = smmu_writel(s, offset, data, attrs);
243
+ break;
244
+ default:
245
+ r = MEMTX_ERROR;
246
+ break;
247
+ }
248
+
249
+ trace_smmuv3_write_mmio(offset, data, size, r);
250
+ return r;
251
}
252
253
static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
254
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
255
index XXXXXXX..XXXXXXX 100644
256
--- a/hw/arm/trace-events
257
+++ b/hw/arm/trace-events
258
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_consume(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t con
259
smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
260
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
261
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
262
+smmuv3_update(bool is_empty, uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "q empty:%d prod:%d cons:%d p.wrap:%d p.cons:%d"
263
+smmuv3_update_check_cmd(int error) "cmdq not enabled or error :0x%x"
264
+smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
265
+smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
266
+smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
267
+smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
268
--
74
--
269
2.17.0
75
2.20.1
270
76
271
77
diff view generated by jsdifflib
1
Convert the tusb6010 device away from using the old_mmio field
1
In the v7M architecture, if an exception is generated in the process
2
of MemoryRegionOps. This device is used only in the n800 and n810
2
of doing the lazy stacking of FP registers, the handling of
3
boards.
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
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
10
This corresponds to the pseudocode TakePreserveFPException().
4
11
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180427173611.10281-2-peter.maydell@linaro.org
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
8
---
15
---
9
hw/usb/tusb6010.c | 40 ++++++++++++++++++++++++++++++++++++----
16
target/arm/cpu.h | 12 ++++++
10
1 file changed, 36 insertions(+), 4 deletions(-)
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
11
19
12
diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/usb/tusb6010.c
22
--- a/target/arm/cpu.h
15
+++ b/hw/usb/tusb6010.c
23
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static void tusb_async_writew(void *opaque, hwaddr addr,
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
17
}
25
* a different exception).
26
*/
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
28
+/**
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
30
+ * @opaque: the NVIC
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);
18
}
49
}
19
50
20
+static uint64_t tusb_async_readfn(void *opaque, hwaddr addr, unsigned size)
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
21
+{
52
+{
22
+ switch (size) {
53
+ /*
23
+ case 1:
54
+ * Pend an exception during lazy FP stacking. This differs
24
+ return tusb_async_readb(opaque, addr);
55
+ * from the usual exception pending because the logic for
25
+ case 2:
56
+ * whether we should escalate depends on the saved context
26
+ return tusb_async_readh(opaque, addr);
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
27
+ case 4:
58
+ */
28
+ return tusb_async_readw(opaque, addr);
59
+ NVICState *s = (NVICState *)opaque;
29
+ default:
60
+ bool banked = exc_is_banked(irq);
30
+ g_assert_not_reached();
61
+ VecInfo *vec;
31
+ }
62
+ bool targets_secure;
32
+}
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];
33
+
71
+
34
+static void tusb_async_writefn(void *opaque, hwaddr addr,
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
35
+ uint64_t value, unsigned size)
73
+ assert(!secure || banked);
36
+{
74
+
37
+ switch (size) {
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
38
+ case 1:
76
+
39
+ tusb_async_writeb(opaque, addr, value);
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
+ }
40
+ break;
85
+ break;
41
+ case 2:
86
+ case ARMV7M_EXCP_MEM:
42
+ tusb_async_writeh(opaque, addr, value);
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
43
+ break;
88
+ break;
44
+ case 4:
89
+ case ARMV7M_EXCP_USAGE:
45
+ tusb_async_writew(opaque, addr, value);
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);
46
+ break;
97
+ break;
47
+ default:
98
+ default:
48
+ g_assert_not_reached();
99
+ g_assert_not_reached();
49
+ }
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
+ }
50
+}
145
+}
51
+
146
+
52
static const MemoryRegionOps tusb_async_ops = {
147
/* Make pending IRQ active. */
53
- .old_mmio = {
148
void armv7m_nvic_acknowledge_irq(void *opaque)
54
- .read = { tusb_async_readb, tusb_async_readh, tusb_async_readw, },
149
{
55
- .write = { tusb_async_writeb, tusb_async_writeh, tusb_async_writew, },
56
- },
57
+ .read = tusb_async_readfn,
58
+ .write = tusb_async_writefn,
59
+ .valid.min_access_size = 1,
60
+ .valid.max_access_size = 4,
61
.endianness = DEVICE_NATIVE_ENDIAN,
62
};
63
64
--
150
--
65
2.17.0
151
2.20.1
66
152
67
153
diff view generated by jsdifflib
New patch
1
1
Pushing registers to the stack for v7M needs to handle three cases:
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
9
Implement this by changing the existing flag argument that
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
13
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
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
18
1 file changed, 79 insertions(+), 39 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
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
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
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
--
209
2.20.1
210
211
diff view generated by jsdifflib
1
Convert the smc91c111 device away from using the old_mmio field of
1
The M-profile architecture floating point system supports
2
MemoryRegionOps. This device is used by several Arm board models.
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().
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180427173611.10281-3-peter.maydell@linaro.org
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
7
---
11
---
8
hw/net/smc91c111.c | 54 +++++++++++++++++++++-------------------------
12
target/arm/cpu.h | 3 ++
9
1 file changed, 25 insertions(+), 29 deletions(-)
13
target/arm/helper.h | 2 +
10
14
target/arm/translate.h | 1 +
11
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
12
index XXXXXXX..XXXXXXX 100644
16
target/arm/translate.c | 22 ++++++++
13
--- a/hw/net/smc91c111.c
17
5 files changed, 140 insertions(+)
14
+++ b/hw/net/smc91c111.c
18
15
@@ -XXX,XX +XXX,XX @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
return 0;
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
17
}
71
}
18
72
19
-static void smc91c111_writew(void *opaque, hwaddr offset,
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
20
- uint32_t value)
74
+{
21
+static uint64_t smc91c111_readfn(void *opaque, hwaddr addr, unsigned size)
75
+ /* translate.c should never generate calls here in user-only mode */
76
+ g_assert_not_reached();
77
+}
78
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
22
{
80
{
23
- smc91c111_writeb(opaque, offset, value & 0xff);
81
/* The TT instructions can be used by unprivileged code, but in
24
- smc91c111_writeb(opaque, offset + 1, value >> 8);
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
25
+ int i;
83
return false;
26
+ uint32_t val = 0;
27
+
28
+ for (i = 0; i < size; i++) {
29
+ val |= smc91c111_readb(opaque, addr + i) << (i * 8);
30
+ }
31
+ return val;
32
}
84
}
33
85
34
-static void smc91c111_writel(void *opaque, hwaddr offset,
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
35
- uint32_t value)
87
+{
36
+static void smc91c111_writefn(void *opaque, hwaddr addr,
88
+ /*
37
+ uint64_t value, unsigned size)
89
+ * Preserve FP state (because LSPACT was set and we are about
38
{
90
+ * to execute an FP instruction). This corresponds to the
39
+ int i = 0;
91
+ * PreserveFPState() pseudocode.
40
+
92
+ * We may throw an exception if the stacking fails.
41
/* 32-bit writes to offset 0xc only actually write to the bank select
42
- register (offset 0xe) */
43
- if (offset != 0xc)
44
- smc91c111_writew(opaque, offset, value & 0xffff);
45
- smc91c111_writew(opaque, offset + 2, value >> 16);
46
-}
47
+ * register (offset 0xe), so skip the first two bytes we would write.
48
+ */
93
+ */
49
+ if (addr == 0xc && size == 4) {
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
50
+ i += 2;
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
51
+ }
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
52
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
53
-static uint32_t smc91c111_readw(void *opaque, hwaddr offset)
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
54
-{
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
55
- uint32_t val;
100
+ bool stacked_ok = true;
56
- val = smc91c111_readb(opaque, offset);
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
57
- val |= smc91c111_readb(opaque, offset + 1) << 8;
102
+ bool take_exception;
58
- return val;
103
+
59
-}
104
+ /* Take the iothread lock as we are going to touch the NVIC */
60
-
105
+ qemu_mutex_lock_iothread();
61
-static uint32_t smc91c111_readl(void *opaque, hwaddr offset)
106
+
62
-{
107
+ /* Check the background context had access to the FPU */
63
- uint32_t val;
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
64
- val = smc91c111_readw(opaque, offset);
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
65
- val |= smc91c111_readw(opaque, offset + 2) << 16;
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
66
- return val;
111
+ stacked_ok = false;
67
+ for (; i < size; i++) {
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
68
+ smc91c111_writeb(opaque, addr + i,
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
69
+ extract32(value, i * 8, 8));
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
70
+ }
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
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
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
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
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
}
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
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
210
+ }
211
+ }
212
+
213
*pflags = flags;
214
*cs_base = 0;
71
}
215
}
72
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
static int smc91c111_can_receive_nc(NetClientState *nc)
217
index XXXXXXX..XXXXXXX 100644
74
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps smc91c111_mem_ops = {
218
--- a/target/arm/translate.c
75
/* The special case for 32 bit writes to 0xc means we can't just
219
+++ b/target/arm/translate.c
76
* set .impl.min/max_access_size to 1, unfortunately
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
77
*/
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
78
- .old_mmio = {
222
/* Handle M-profile lazy FP state mechanics */
79
- .read = { smc91c111_readb, smc91c111_readw, smc91c111_readl, },
223
80
- .write = { smc91c111_writeb, smc91c111_writew, smc91c111_writel, },
224
+ /* Trigger lazy-state preservation if necessary */
81
- },
225
+ if (s->v7m_lspact) {
82
+ .read = smc91c111_readfn,
226
+ /*
83
+ .write = smc91c111_writefn,
227
+ * Lazy state saving affects external memory and also the NVIC,
84
+ .valid.min_access_size = 1,
228
+ * so we must mark it as an IO operation for icount.
85
+ .valid.max_access_size = 4,
229
+ */
86
.endianness = DEVICE_NATIVE_ENDIAN,
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
87
};
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;
88
255
89
--
256
--
90
2.17.0
257
2.20.1
91
258
92
259
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
We introduce some helpers to handle wired IRQs and especially
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
GERROR interrupt. SMMU writes GERROR register on GERROR event
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
and SW acks GERROR interrupts by setting GERRORn.
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
6
---
7
target/arm/cpu.h | 2 +
8
target/arm/helper.h | 2 +
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
6
12
7
The Wired interrupts are edge sensitive hence the pulse usage.
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-6-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/smmuv3-internal.h | 14 +++++++++
16
hw/arm/smmuv3.c | 64 ++++++++++++++++++++++++++++++++++++++++
17
hw/arm/trace-events | 3 ++
18
3 files changed, 81 insertions(+)
19
20
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/smmuv3-internal.h
15
--- a/target/arm/cpu.h
23
+++ b/hw/arm/smmuv3-internal.h
16
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static inline uint32_t smmuv3_idreg(int regoffset)
17
@@ -XXX,XX +XXX,XX @@
25
return smmuv3_ids[regoffset / 4];
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
24
25
#define ARMV7M_EXCP_RESET 1
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
29
+++ b/target/arm/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
44
g_assert_not_reached();
26
}
45
}
27
46
28
+static inline bool smmuv3_eventq_irq_enabled(SMMUv3State *s)
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
29
+{
48
+{
30
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, EVENTQ_IRQEN);
49
+ /* translate.c should never generate calls here in user-only mode */
50
+ g_assert_not_reached();
31
+}
51
+}
32
+
52
+
33
+static inline bool smmuv3_gerror_irq_enabled(SMMUv3State *s)
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
}
58
}
59
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
34
+{
61
+{
35
+ return FIELD_EX32(s->irq_ctrl, IRQ_CTRL, GERROR_IRQEN);
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
36
+}
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
37
+
65
+
38
+/* public until callers get introduced */
66
+ assert(env->v7m.secure);
39
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask);
40
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t gerrorn);
41
+
67
+
42
#endif
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
43
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
69
+ return;
44
index XXXXXXX..XXXXXXX 100644
70
+ }
45
--- a/hw/arm/smmuv3.c
46
+++ b/hw/arm/smmuv3.c
47
@@ -XXX,XX +XXX,XX @@
48
#include "hw/arm/smmuv3.h"
49
#include "smmuv3-internal.h"
50
51
+/**
52
+ * smmuv3_trigger_irq - pulse @irq if enabled and update
53
+ * GERROR register in case of GERROR interrupt
54
+ *
55
+ * @irq: irq type
56
+ * @gerror_mask: mask of gerrors to toggle (relevant if @irq is GERROR)
57
+ */
58
+void smmuv3_trigger_irq(SMMUv3State *s, SMMUIrq irq, uint32_t gerror_mask)
59
+{
60
+
71
+
61
+ bool pulse = false;
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
+ }
62
+
76
+
63
+ switch (irq) {
77
+ if (lspact) {
64
+ case SMMU_IRQ_EVTQ:
78
+ /* LSPACT should not be active when there is active FP state */
65
+ pulse = smmuv3_eventq_irq_enabled(s);
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
66
+ break;
80
+ }
67
+ case SMMU_IRQ_PRIQ:
68
+ qemu_log_mask(LOG_UNIMP, "PRI not yet supported\n");
69
+ break;
70
+ case SMMU_IRQ_CMD_SYNC:
71
+ pulse = true;
72
+ break;
73
+ case SMMU_IRQ_GERROR:
74
+ {
75
+ uint32_t pending = s->gerror ^ s->gerrorn;
76
+ uint32_t new_gerrors = ~pending & gerror_mask;
77
+
81
+
78
+ if (!new_gerrors) {
82
+ if (fptr & 7) {
79
+ /* only toggle non pending errors */
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
80
+ return;
81
+ }
82
+ s->gerror ^= new_gerrors;
83
+ trace_smmuv3_write_gerror(new_gerrors, s->gerror);
84
+
85
+ pulse = smmuv3_gerror_irq_enabled(s);
86
+ break;
87
+ }
88
+ }
89
+ if (pulse) {
90
+ trace_smmuv3_trigger_irq(irq);
91
+ qemu_irq_pulse(s->irq[irq]);
92
+ }
93
+}
94
+
95
+void smmuv3_write_gerrorn(SMMUv3State *s, uint32_t new_gerrorn)
96
+{
97
+ uint32_t pending = s->gerror ^ s->gerrorn;
98
+ uint32_t toggled = s->gerrorn ^ new_gerrorn;
99
+
100
+ if (toggled & ~pending) {
101
+ qemu_log_mask(LOG_GUEST_ERROR,
102
+ "guest toggles non pending errors = 0x%x\n",
103
+ toggled & ~pending);
104
+ }
84
+ }
105
+
85
+
106
+ /*
86
+ /*
107
+ * We do not raise any error in case guest toggles bits corresponding
87
+ * Note that we do not use v7m_stack_write() here, because the
108
+ * to not active IRQs (CONSTRAINED UNPREDICTABLE)
88
+ * accesses should not set the FSR bits for stacking errors if they
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.
109
+ */
92
+ */
110
+ s->gerrorn = new_gerrorn;
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
95
+ int i;
111
+
96
+
112
+ trace_smmuv3_write_gerrorn(toggled & pending, s->gerrorn);
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
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
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
113
+}
126
+}
114
+
127
+
115
static void smmuv3_init_regs(SMMUv3State *s)
128
static bool v7m_push_stack(ARMCPU *cpu)
116
{
129
{
117
/**
130
/* Do the "set up stack frame" part of exception entry,
118
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
119
index XXXXXXX..XXXXXXX 100644
156
index XXXXXXX..XXXXXXX 100644
120
--- a/hw/arm/trace-events
157
--- a/target/arm/translate.c
121
+++ b/hw/arm/trace-events
158
+++ b/target/arm/translate.c
122
@@ -XXX,XX +XXX,XX @@ smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "base
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
123
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
124
#hw/arm/smmuv3.c
161
goto illegal_op;
125
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
162
}
126
+smmuv3_trigger_irq(int irq) "irq=%d"
163
- /* Just NOP since FP support is not implemented */
127
+smmuv3_write_gerror(uint32_t toggled, uint32_t gerror) "toggled=0x%x, new GERROR=0x%x"
164
+
128
+smmuv3_write_gerrorn(uint32_t acked, uint32_t gerrorn) "acked=0x%x, new GERRORN=0x%x"
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) &&
129
--
181
--
130
2.17.0
182
2.20.1
131
183
132
184
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Implement the VLLDM instruction for v7M for the FPU present cas.
2
2
3
Let's introduce a helper function aiming at recording an
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
event in the event queue.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
6
---
7
target/arm/helper.h | 1 +
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 2 +-
10
3 files changed, 56 insertions(+), 1 deletion(-)
5
11
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1524665762-31355-9-git-send-email-eric.auger@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/smmuv3-internal.h | 148 ++++++++++++++++++++++++++++++++++++++-
12
hw/arm/smmuv3.c | 108 ++++++++++++++++++++++++++--
13
hw/arm/trace-events | 1 +
14
3 files changed, 249 insertions(+), 8 deletions(-)
15
16
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/smmuv3-internal.h
14
--- a/target/arm/helper.h
19
+++ b/hw/arm/smmuv3-internal.h
15
+++ b/target/arm/helper.h
20
@@ -XXX,XX +XXX,XX @@ static inline void smmu_write_cmdq_err(SMMUv3State *s, uint32_t err_type)
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
21
s->cmdq.cons = FIELD_DP32(s->cmdq.cons, CMDQ_CONS, ERR, err_type);
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
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();
22
}
30
}
23
31
24
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt);
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
25
-
26
/* Commands */
27
28
typedef enum SMMUCommandType {
29
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
30
31
#define SMMU_FEATURE_2LVL_STE (1 << 0)
32
33
+/* Events */
34
+
35
+typedef enum SMMUEventType {
36
+ SMMU_EVT_OK = 0x00,
37
+ SMMU_EVT_F_UUT ,
38
+ SMMU_EVT_C_BAD_STREAMID ,
39
+ SMMU_EVT_F_STE_FETCH ,
40
+ SMMU_EVT_C_BAD_STE ,
41
+ SMMU_EVT_F_BAD_ATS_TREQ ,
42
+ SMMU_EVT_F_STREAM_DISABLED ,
43
+ SMMU_EVT_F_TRANS_FORBIDDEN ,
44
+ SMMU_EVT_C_BAD_SUBSTREAMID ,
45
+ SMMU_EVT_F_CD_FETCH ,
46
+ SMMU_EVT_C_BAD_CD ,
47
+ SMMU_EVT_F_WALK_EABT ,
48
+ SMMU_EVT_F_TRANSLATION = 0x10,
49
+ SMMU_EVT_F_ADDR_SIZE ,
50
+ SMMU_EVT_F_ACCESS ,
51
+ SMMU_EVT_F_PERMISSION ,
52
+ SMMU_EVT_F_TLB_CONFLICT = 0x20,
53
+ SMMU_EVT_F_CFG_CONFLICT ,
54
+ SMMU_EVT_E_PAGE_REQ = 0x24,
55
+} SMMUEventType;
56
+
57
+static const char *event_stringify[] = {
58
+ [SMMU_EVT_OK] = "SMMU_EVT_OK",
59
+ [SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
60
+ [SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
61
+ [SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
62
+ [SMMU_EVT_C_BAD_STE] = "SMMU_EVT_C_BAD_STE",
63
+ [SMMU_EVT_F_BAD_ATS_TREQ] = "SMMU_EVT_F_BAD_ATS_TREQ",
64
+ [SMMU_EVT_F_STREAM_DISABLED] = "SMMU_EVT_F_STREAM_DISABLED",
65
+ [SMMU_EVT_F_TRANS_FORBIDDEN] = "SMMU_EVT_F_TRANS_FORBIDDEN",
66
+ [SMMU_EVT_C_BAD_SUBSTREAMID] = "SMMU_EVT_C_BAD_SUBSTREAMID",
67
+ [SMMU_EVT_F_CD_FETCH] = "SMMU_EVT_F_CD_FETCH",
68
+ [SMMU_EVT_C_BAD_CD] = "SMMU_EVT_C_BAD_CD",
69
+ [SMMU_EVT_F_WALK_EABT] = "SMMU_EVT_F_WALK_EABT",
70
+ [SMMU_EVT_F_TRANSLATION] = "SMMU_EVT_F_TRANSLATION",
71
+ [SMMU_EVT_F_ADDR_SIZE] = "SMMU_EVT_F_ADDR_SIZE",
72
+ [SMMU_EVT_F_ACCESS] = "SMMU_EVT_F_ACCESS",
73
+ [SMMU_EVT_F_PERMISSION] = "SMMU_EVT_F_PERMISSION",
74
+ [SMMU_EVT_F_TLB_CONFLICT] = "SMMU_EVT_F_TLB_CONFLICT",
75
+ [SMMU_EVT_F_CFG_CONFLICT] = "SMMU_EVT_F_CFG_CONFLICT",
76
+ [SMMU_EVT_E_PAGE_REQ] = "SMMU_EVT_E_PAGE_REQ",
77
+};
78
+
79
+static inline const char *smmu_event_string(SMMUEventType type)
80
+{
33
+{
81
+ if (type < ARRAY_SIZE(event_stringify)) {
34
+ /* translate.c should never generate calls here in user-only mode */
82
+ return event_stringify[type] ? event_stringify[type] : "UNKNOWN";
35
+ g_assert_not_reached();
83
+ } else {
84
+ return "INVALID";
85
+ }
86
+}
36
+}
87
+
37
+
88
+/* Encode an event record */
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
89
+typedef struct SMMUEventInfo {
39
{
90
+ SMMUEventType type;
40
/* The TT instructions can be used by unprivileged code, but in
91
+ uint32_t sid;
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
92
+ bool recorded;
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
93
+ bool record_trans_faults;
43
}
94
+ union {
44
95
+ struct {
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
96
+ uint32_t ssid;
46
+{
97
+ bool ssv;
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
98
+ dma_addr_t addr;
48
+ assert(env->v7m.secure);
99
+ bool rnw;
100
+ bool pnu;
101
+ bool ind;
102
+ } f_uut;
103
+ struct SSIDInfo {
104
+ uint32_t ssid;
105
+ bool ssv;
106
+ } c_bad_streamid;
107
+ struct SSIDAddrInfo {
108
+ uint32_t ssid;
109
+ bool ssv;
110
+ dma_addr_t addr;
111
+ } f_ste_fetch;
112
+ struct SSIDInfo c_bad_ste;
113
+ struct {
114
+ dma_addr_t addr;
115
+ bool rnw;
116
+ } f_transl_forbidden;
117
+ struct {
118
+ uint32_t ssid;
119
+ } c_bad_substream;
120
+ struct SSIDAddrInfo f_cd_fetch;
121
+ struct SSIDInfo c_bad_cd;
122
+ struct FullInfo {
123
+ bool stall;
124
+ uint16_t stag;
125
+ uint32_t ssid;
126
+ bool ssv;
127
+ bool s2;
128
+ dma_addr_t addr;
129
+ bool rnw;
130
+ bool pnu;
131
+ bool ind;
132
+ uint8_t class;
133
+ dma_addr_t addr2;
134
+ } f_walk_eabt;
135
+ struct FullInfo f_translation;
136
+ struct FullInfo f_addr_size;
137
+ struct FullInfo f_access;
138
+ struct FullInfo f_permission;
139
+ struct SSIDInfo f_cfg_conflict;
140
+ /**
141
+ * not supported yet:
142
+ * F_BAD_ATS_TREQ
143
+ * F_BAD_ATS_TREQ
144
+ * F_TLB_CONFLICT
145
+ * E_PAGE_REQUEST
146
+ * IMPDEF_EVENTn
147
+ */
148
+ } u;
149
+} SMMUEventInfo;
150
+
49
+
151
+/* EVTQ fields */
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
152
+
51
+ return;
153
+#define EVT_Q_OVERFLOW (1 << 31)
154
+
155
+#define EVT_SET_TYPE(x, v) deposit32((x)->word[0], 0 , 8 , v)
156
+#define EVT_SET_SSV(x, v) deposit32((x)->word[0], 11, 1 , v)
157
+#define EVT_SET_SSID(x, v) deposit32((x)->word[0], 12, 20, v)
158
+#define EVT_SET_SID(x, v) ((x)->word[1] = v)
159
+#define EVT_SET_STAG(x, v) deposit32((x)->word[2], 0 , 16, v)
160
+#define EVT_SET_STALL(x, v) deposit32((x)->word[2], 31, 1 , v)
161
+#define EVT_SET_PNU(x, v) deposit32((x)->word[3], 1 , 1 , v)
162
+#define EVT_SET_IND(x, v) deposit32((x)->word[3], 2 , 1 , v)
163
+#define EVT_SET_RNW(x, v) deposit32((x)->word[3], 3 , 1 , v)
164
+#define EVT_SET_S2(x, v) deposit32((x)->word[3], 7 , 1 , v)
165
+#define EVT_SET_CLASS(x, v) deposit32((x)->word[3], 8 , 2 , v)
166
+#define EVT_SET_ADDR(x, addr) \
167
+ do { \
168
+ (x)->word[5] = (uint32_t)(addr >> 32); \
169
+ (x)->word[4] = (uint32_t)(addr & 0xffffffff); \
170
+ } while (0)
171
+#define EVT_SET_ADDR2(x, addr) \
172
+ do { \
173
+ deposit32((x)->word[7], 3, 29, addr >> 16); \
174
+ deposit32((x)->word[7], 0, 16, addr & 0xffff);\
175
+ } while (0)
176
+
177
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
178
+
179
#endif
180
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/hw/arm/smmuv3.c
183
+++ b/hw/arm/smmuv3.c
184
@@ -XXX,XX +XXX,XX @@ static MemTxResult queue_write(SMMUQueue *q, void *data)
185
return MEMTX_OK;
186
}
187
188
-void smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
189
+static MemTxResult smmuv3_write_eventq(SMMUv3State *s, Evt *evt)
190
{
191
SMMUQueue *q = &s->eventq;
192
+ MemTxResult r;
193
+
194
+ if (!smmuv3_eventq_enabled(s)) {
195
+ return MEMTX_ERROR;
196
+ }
52
+ }
197
+
53
+
198
+ if (smmuv3_q_full(q)) {
54
+ /* Check access to the coprocessor is permitted */
199
+ return MEMTX_ERROR;
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
200
+ }
57
+ }
201
+
58
+
202
+ r = queue_write(q, evt);
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
203
+ if (r != MEMTX_OK) {
60
+ /* State in FP is still valid */
204
+ return r;
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);
205
+ }
88
+ }
206
+
89
+
207
+ if (smmuv3_q_empty(q)) {
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
208
+ smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
209
+ }
210
+ return MEMTX_OK;
211
+}
91
+}
212
+
92
+
213
+void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
93
static bool v7m_push_stack(ARMCPU *cpu)
214
+{
94
{
215
+ Evt evt;
95
/* Do the "set up stack frame" part of exception entry,
216
+ MemTxResult r;
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
218
if (!smmuv3_eventq_enabled(s)) {
219
return;
220
}
221
222
- if (smmuv3_q_full(q)) {
223
+ EVT_SET_TYPE(&evt, info->type);
224
+ EVT_SET_SID(&evt, info->sid);
225
+
226
+ switch (info->type) {
227
+ case SMMU_EVT_OK:
228
return;
229
+ case SMMU_EVT_F_UUT:
230
+ EVT_SET_SSID(&evt, info->u.f_uut.ssid);
231
+ EVT_SET_SSV(&evt, info->u.f_uut.ssv);
232
+ EVT_SET_ADDR(&evt, info->u.f_uut.addr);
233
+ EVT_SET_RNW(&evt, info->u.f_uut.rnw);
234
+ EVT_SET_PNU(&evt, info->u.f_uut.pnu);
235
+ EVT_SET_IND(&evt, info->u.f_uut.ind);
236
+ break;
237
+ case SMMU_EVT_C_BAD_STREAMID:
238
+ EVT_SET_SSID(&evt, info->u.c_bad_streamid.ssid);
239
+ EVT_SET_SSV(&evt, info->u.c_bad_streamid.ssv);
240
+ break;
241
+ case SMMU_EVT_F_STE_FETCH:
242
+ EVT_SET_SSID(&evt, info->u.f_ste_fetch.ssid);
243
+ EVT_SET_SSV(&evt, info->u.f_ste_fetch.ssv);
244
+ EVT_SET_ADDR(&evt, info->u.f_ste_fetch.addr);
245
+ break;
246
+ case SMMU_EVT_C_BAD_STE:
247
+ EVT_SET_SSID(&evt, info->u.c_bad_ste.ssid);
248
+ EVT_SET_SSV(&evt, info->u.c_bad_ste.ssv);
249
+ break;
250
+ case SMMU_EVT_F_STREAM_DISABLED:
251
+ break;
252
+ case SMMU_EVT_F_TRANS_FORBIDDEN:
253
+ EVT_SET_ADDR(&evt, info->u.f_transl_forbidden.addr);
254
+ EVT_SET_RNW(&evt, info->u.f_transl_forbidden.rnw);
255
+ break;
256
+ case SMMU_EVT_C_BAD_SUBSTREAMID:
257
+ EVT_SET_SSID(&evt, info->u.c_bad_substream.ssid);
258
+ break;
259
+ case SMMU_EVT_F_CD_FETCH:
260
+ EVT_SET_SSID(&evt, info->u.f_cd_fetch.ssid);
261
+ EVT_SET_SSV(&evt, info->u.f_cd_fetch.ssv);
262
+ EVT_SET_ADDR(&evt, info->u.f_cd_fetch.addr);
263
+ break;
264
+ case SMMU_EVT_C_BAD_CD:
265
+ EVT_SET_SSID(&evt, info->u.c_bad_cd.ssid);
266
+ EVT_SET_SSV(&evt, info->u.c_bad_cd.ssv);
267
+ break;
268
+ case SMMU_EVT_F_WALK_EABT:
269
+ case SMMU_EVT_F_TRANSLATION:
270
+ case SMMU_EVT_F_ADDR_SIZE:
271
+ case SMMU_EVT_F_ACCESS:
272
+ case SMMU_EVT_F_PERMISSION:
273
+ EVT_SET_STALL(&evt, info->u.f_walk_eabt.stall);
274
+ EVT_SET_STAG(&evt, info->u.f_walk_eabt.stag);
275
+ EVT_SET_SSID(&evt, info->u.f_walk_eabt.ssid);
276
+ EVT_SET_SSV(&evt, info->u.f_walk_eabt.ssv);
277
+ EVT_SET_S2(&evt, info->u.f_walk_eabt.s2);
278
+ EVT_SET_ADDR(&evt, info->u.f_walk_eabt.addr);
279
+ EVT_SET_RNW(&evt, info->u.f_walk_eabt.rnw);
280
+ EVT_SET_PNU(&evt, info->u.f_walk_eabt.pnu);
281
+ EVT_SET_IND(&evt, info->u.f_walk_eabt.ind);
282
+ EVT_SET_CLASS(&evt, info->u.f_walk_eabt.class);
283
+ EVT_SET_ADDR2(&evt, info->u.f_walk_eabt.addr2);
284
+ break;
285
+ case SMMU_EVT_F_CFG_CONFLICT:
286
+ EVT_SET_SSID(&evt, info->u.f_cfg_conflict.ssid);
287
+ EVT_SET_SSV(&evt, info->u.f_cfg_conflict.ssv);
288
+ break;
289
+ /* rest is not implemented */
290
+ case SMMU_EVT_F_BAD_ATS_TREQ:
291
+ case SMMU_EVT_F_TLB_CONFLICT:
292
+ case SMMU_EVT_E_PAGE_REQ:
293
+ default:
294
+ g_assert_not_reached();
295
}
296
297
- queue_write(q, evt);
298
-
299
- if (smmuv3_q_empty(q)) {
300
- smmuv3_trigger_irq(s, SMMU_IRQ_EVTQ, 0);
301
+ trace_smmuv3_record_event(smmu_event_string(info->type), info->sid);
302
+ r = smmuv3_write_eventq(s, &evt);
303
+ if (r != MEMTX_OK) {
304
+ smmuv3_trigger_irq(s, SMMU_IRQ_GERROR, R_GERROR_EVENTQ_ABT_ERR_MASK);
305
}
306
+ info->recorded = true;
307
}
308
309
static void smmuv3_init_regs(SMMUv3State *s)
310
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
311
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
312
--- a/hw/arm/trace-events
98
--- a/target/arm/translate.c
313
+++ b/hw/arm/trace-events
99
+++ b/target/arm/translate.c
314
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr:
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
315
smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx val64:0x%lx"
101
TCGv_i32 fptr = load_reg(s, rn);
316
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
102
317
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
103
if (extract32(insn, 20, 1)) {
318
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
104
- /* VLLDM */
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
106
} else {
107
gen_helper_v7m_vlstm(cpu_env, fptr);
108
}
319
--
109
--
320
2.17.0
110
2.20.1
321
111
322
112
diff view generated by jsdifflib
New patch
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
1
2
3
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
---
7
target/arm/cpu.c | 8 ++++++++
8
1 file changed, 8 insertions(+)
9
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
13
+++ b/target/arm/cpu.c
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
15
set_feature(&cpu->env, ARM_FEATURE_M);
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
19
cpu->midr = 0x410fc240; /* r0p0 */
20
cpu->pmsav7_dregion = 8;
21
+ cpu->isar.mvfr0 = 0x10110021;
22
+ cpu->isar.mvfr1 = 0x11000011;
23
+ cpu->isar.mvfr2 = 0x00000000;
24
cpu->id_pfr0 = 0x00000030;
25
cpu->id_pfr1 = 0x00000200;
26
cpu->id_dfr0 = 0x00100000;
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
32
cpu->midr = 0x410fd213; /* r0p3 */
33
cpu->pmsav7_dregion = 16;
34
cpu->sau_sregion = 8;
35
+ cpu->isar.mvfr0 = 0x10110021;
36
+ cpu->isar.mvfr1 = 0x11000011;
37
+ cpu->isar.mvfr2 = 0x00000040;
38
cpu->id_pfr0 = 0x00000030;
39
cpu->id_pfr1 = 0x00000210;
40
cpu->id_dfr0 = 0x00200000;
41
--
42
2.20.1
43
44
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Even though nothing is currently broken (since all boards
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
use first_cpu as boot cpu), make sure that boot_info is set
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
on all CPUs.
5
Move it to common object, so we build it once for all targets.
6
If some board would like support heterogenuos setup (i.e.
7
init boot_info on subset of CPUs) in future, it should add
8
a reasonable API to do it, instead of starting assigning
9
boot_info from some CPU and till the end of present CPUs
10
list.
11
6
12
Ref:
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
"Message-ID: <CAFEAcA_NMWuA8WSs3cNeY6xX1kerO_uAcN_3=fK02BEhHJW86g@mail.gmail.com>"
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
14
15
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 1525176522-200354-5-git-send-email-imammedo@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
11
---
20
hw/arm/boot.c | 2 +-
12
hw/dma/Makefile.objs | 2 +-
21
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
22
14
23
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/boot.c
17
--- a/hw/dma/Makefile.objs
26
+++ b/hw/arm/boot.c
18
+++ b/hw/dma/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ static void arm_load_kernel_notify(Notifier *notifier, void *data)
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
28
}
20
29
info->is_linux = is_linux;
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
30
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
31
- for (cs = CPU(cpu); cs; cs = CPU_NEXT(cs)) {
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
32
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
33
ARM_CPU(cs)->env.boot_info = info;
34
}
35
}
36
--
25
--
37
2.17.0
26
2.20.1
38
27
39
28
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Path analysis shows that size == 3 && !is_q has been eliminated.
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Fixes: Coverity CID1385853
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
8
Message-id: 20180501180455.11214-3-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/translate-a64.c | 6 +++++-
10
hw/arm/aspeed.c | 13 +++++++++----
12
1 file changed, 5 insertions(+), 1 deletion(-)
11
1 file changed, 9 insertions(+), 4 deletions(-)
13
12
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
15
--- a/hw/arm/aspeed.c
17
+++ b/target/arm/translate-a64.c
16
+++ b/hw/arm/aspeed.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@
19
/* All 64-bit element operations can be shared with scalar 2misc */
18
#include "hw/arm/aspeed_soc.h"
20
int pass;
19
#include "hw/boards.h"
21
20
#include "hw/i2c/smbus_eeprom.h"
22
- for (pass = 0; pass < (is_q ? 2 : 1); pass++) {
21
+#include "hw/misc/pca9552.h"
23
+ /* Coverity claims (size == 3 && !is_q) has been eliminated
22
+#include "hw/misc/tmp105.h"
24
+ * from all paths leading to here.
23
#include "qemu/log.h"
25
+ */
24
#include "sysemu/block-backend.h"
26
+ tcg_debug_assert(is_q);
25
#include "hw/loader.h"
27
+ for (pass = 0; pass < 2; pass++) {
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
28
TCGv_i64 tcg_op = tcg_temp_new_i64();
27
eeprom_buf);
29
TCGv_i64 tcg_res = tcg_temp_new_i64();
28
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
32
+ TYPE_TMP105, 0x4d);
33
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
* plugged on the I2C bus header */
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
AspeedSoCState *soc = &bmc->soc;
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
+ 0x60);
43
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ 0x4a);
51
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
* good enough */
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
eeprom_buf);
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
0x60);
61
}
30
62
31
--
63
--
32
2.17.0
64
2.20.1
33
65
34
66
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
In case the MSI is translated by an IOMMU we need to fixup the
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
MSI route with the translated address.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
8
Message-id: 1524665762-31355-12-git-send-email-eric.auger@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/kvm.c | 38 +++++++++++++++++++++++++++++++++++++-
9
hw/arm/nseries.c | 3 ++-
13
target/arm/trace-events | 3 +++
10
1 file changed, 2 insertions(+), 1 deletion(-)
14
2 files changed, 40 insertions(+), 1 deletion(-)
15
11
16
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/kvm.c
14
--- a/hw/arm/nseries.c
19
+++ b/target/arm/kvm.c
15
+++ b/hw/arm/nseries.c
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
21
#include "sysemu/kvm.h"
22
#include "kvm_arm.h"
23
#include "cpu.h"
24
+#include "trace.h"
25
#include "internals.h"
26
#include "hw/arm/arm.h"
27
+#include "hw/pci/pci.h"
28
#include "exec/memattrs.h"
29
#include "exec/address-spaces.h"
30
#include "hw/boards.h"
17
#include "hw/boards.h"
31
@@ -XXX,XX +XXX,XX @@ int kvm_arm_vgic_probe(void)
18
#include "hw/i2c/i2c.h"
32
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
19
#include "hw/devices.h"
33
uint64_t address, uint32_t data, PCIDevice *dev)
20
+#include "hw/misc/tmp105.h"
34
{
21
#include "hw/block/flash.h"
35
- return 0;
22
#include "hw/hw.h"
36
+ AddressSpace *as = pci_device_iommu_address_space(dev);
23
#include "hw/bt.h"
37
+ hwaddr xlat, len, doorbell_gpa;
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
38
+ MemoryRegionSection mrs;
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
39
+ MemoryRegion *mr;
26
40
+ int ret = 1;
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
41
+
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
42
+ if (as == &address_space_memory) {
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
43
+ return 0;
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
44
+ }
45
+
46
+ /* MSI doorbell address is translated by an IOMMU */
47
+
48
+ rcu_read_lock();
49
+ mr = address_space_translate(as, address, &xlat, &len, true);
50
+ if (!mr) {
51
+ goto unlock;
52
+ }
53
+ mrs = memory_region_find(mr, xlat, 1);
54
+ if (!mrs.mr) {
55
+ goto unlock;
56
+ }
57
+
58
+ doorbell_gpa = mrs.offset_within_address_space;
59
+ memory_region_unref(mrs.mr);
60
+
61
+ route->u.msi.address_lo = doorbell_gpa;
62
+ route->u.msi.address_hi = doorbell_gpa >> 32;
63
+
64
+ trace_kvm_arm_fixup_msi_route(address, doorbell_gpa);
65
+
66
+ ret = 0;
67
+
68
+unlock:
69
+ rcu_read_unlock();
70
+ return ret;
71
}
31
}
72
32
73
int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
74
diff --git a/target/arm/trace-events b/target/arm/trace-events
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/trace-events
77
+++ b/target/arm/trace-events
78
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
79
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
80
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
81
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
82
+
83
+# target/arm/kvm.c
84
+kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64
85
--
33
--
86
2.17.0
34
2.20.1
87
35
88
36
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch implements the IOMMU Memory Region translate()
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
callback. Most of the code relates to the translation
4
functions since their introduction in commit 88d2c950b002. Time to
5
configuration decoding and check (STE, CD).
5
remove them.
6
6
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 1524665762-31355-10-git-send-email-eric.auger@redhat.com
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/arm/smmuv3-internal.h | 160 +++++++++++++++++
13
include/hw/devices.h | 3 ---
14
hw/arm/smmuv3.c | 358 +++++++++++++++++++++++++++++++++++++++
14
hw/display/tc6393xb.c | 16 ----------------
15
hw/arm/trace-events | 9 +
15
2 files changed, 19 deletions(-)
16
3 files changed, 527 insertions(+)
17
16
18
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/smmuv3-internal.h
19
--- a/include/hw/devices.h
21
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/include/hw/devices.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUEventInfo {
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
23
22
typedef struct TC6393xbState TC6393xbState;
24
void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *event);
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
25
24
uint32_t base, qemu_irq irq);
26
+/* Configuration Data */
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
27
+
26
- qemu_irq handler);
28
+/* STE Level 1 Descriptor */
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
29
+typedef struct STEDesc {
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
30
+ uint32_t word[2];
29
31
+} STEDesc;
32
+
33
+/* CD Level 1 Descriptor */
34
+typedef struct CDDesc {
35
+ uint32_t word[2];
36
+} CDDesc;
37
+
38
+/* Stream Table Entry(STE) */
39
+typedef struct STE {
40
+ uint32_t word[16];
41
+} STE;
42
+
43
+/* Context Descriptor(CD) */
44
+typedef struct CD {
45
+ uint32_t word[16];
46
+} CD;
47
+
48
+/* STE fields */
49
+
50
+#define STE_VALID(x) extract32((x)->word[0], 0, 1)
51
+
52
+#define STE_CONFIG(x) extract32((x)->word[0], 1, 3)
53
+#define STE_CFG_S1_ENABLED(config) (config & 0x1)
54
+#define STE_CFG_S2_ENABLED(config) (config & 0x2)
55
+#define STE_CFG_ABORT(config) (!(config & 0x4))
56
+#define STE_CFG_BYPASS(config) (config == 0x4)
57
+
58
+#define STE_S1FMT(x) extract32((x)->word[0], 4 , 2)
59
+#define STE_S1CDMAX(x) extract32((x)->word[1], 27, 5)
60
+#define STE_S1STALLD(x) extract32((x)->word[2], 27, 1)
61
+#define STE_EATS(x) extract32((x)->word[2], 28, 2)
62
+#define STE_STRW(x) extract32((x)->word[2], 30, 2)
63
+#define STE_S2VMID(x) extract32((x)->word[4], 0 , 16)
64
+#define STE_S2T0SZ(x) extract32((x)->word[5], 0 , 6)
65
+#define STE_S2SL0(x) extract32((x)->word[5], 6 , 2)
66
+#define STE_S2TG(x) extract32((x)->word[5], 14, 2)
67
+#define STE_S2PS(x) extract32((x)->word[5], 16, 3)
68
+#define STE_S2AA64(x) extract32((x)->word[5], 19, 1)
69
+#define STE_S2HD(x) extract32((x)->word[5], 24, 1)
70
+#define STE_S2HA(x) extract32((x)->word[5], 25, 1)
71
+#define STE_S2S(x) extract32((x)->word[5], 26, 1)
72
+#define STE_CTXPTR(x) \
73
+ ({ \
74
+ unsigned long addr; \
75
+ addr = (uint64_t)extract32((x)->word[1], 0, 16) << 32; \
76
+ addr |= (uint64_t)((x)->word[0] & 0xffffffc0); \
77
+ addr; \
78
+ })
79
+
80
+#define STE_S2TTB(x) \
81
+ ({ \
82
+ unsigned long addr; \
83
+ addr = (uint64_t)extract32((x)->word[7], 0, 16) << 32; \
84
+ addr |= (uint64_t)((x)->word[6] & 0xfffffff0); \
85
+ addr; \
86
+ })
87
+
88
+static inline int oas2bits(int oas_field)
89
+{
90
+ switch (oas_field) {
91
+ case 0:
92
+ return 32;
93
+ case 1:
94
+ return 36;
95
+ case 2:
96
+ return 40;
97
+ case 3:
98
+ return 42;
99
+ case 4:
100
+ return 44;
101
+ case 5:
102
+ return 48;
103
+ }
104
+ return -1;
105
+}
106
+
107
+static inline int pa_range(STE *ste)
108
+{
109
+ int oas_field = MIN(STE_S2PS(ste), SMMU_IDR5_OAS);
110
+
111
+ if (!STE_S2AA64(ste)) {
112
+ return 40;
113
+ }
114
+
115
+ return oas2bits(oas_field);
116
+}
117
+
118
+#define MAX_PA(ste) ((1 << pa_range(ste)) - 1)
119
+
120
+/* CD fields */
121
+
122
+#define CD_VALID(x) extract32((x)->word[0], 30, 1)
123
+#define CD_ASID(x) extract32((x)->word[1], 16, 16)
124
+#define CD_TTB(x, sel) \
125
+ ({ \
126
+ uint64_t hi, lo; \
127
+ hi = extract32((x)->word[(sel) * 2 + 3], 0, 19); \
128
+ hi <<= 32; \
129
+ lo = (x)->word[(sel) * 2 + 2] & ~0xfULL; \
130
+ hi | lo; \
131
+ })
132
+
133
+#define CD_TSZ(x, sel) extract32((x)->word[0], (16 * (sel)) + 0, 6)
134
+#define CD_TG(x, sel) extract32((x)->word[0], (16 * (sel)) + 6, 2)
135
+#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
136
+#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
137
+#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
138
+#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
139
+#define CD_HD(x) extract32((x)->word[1], 10 , 1)
140
+#define CD_HA(x) extract32((x)->word[1], 11 , 1)
141
+#define CD_S(x) extract32((x)->word[1], 12, 1)
142
+#define CD_R(x) extract32((x)->word[1], 13, 1)
143
+#define CD_A(x) extract32((x)->word[1], 14, 1)
144
+#define CD_AARCH64(x) extract32((x)->word[1], 9 , 1)
145
+
146
+#define CDM_VALID(x) ((x)->word[0] & 0x1)
147
+
148
+static inline int is_cd_valid(SMMUv3State *s, STE *ste, CD *cd)
149
+{
150
+ return CD_VALID(cd);
151
+}
152
+
153
+/**
154
+ * tg2granule - Decodes the CD translation granule size field according
155
+ * to the ttbr in use
156
+ * @bits: TG0/1 fields
157
+ * @ttbr: ttbr index in use
158
+ */
159
+static inline int tg2granule(int bits, int ttbr)
160
+{
161
+ switch (bits) {
162
+ case 0:
163
+ return ttbr ? 0 : 12;
164
+ case 1:
165
+ return ttbr ? 14 : 16;
166
+ case 2:
167
+ return ttbr ? 12 : 14;
168
+ case 3:
169
+ return ttbr ? 16 : 0;
170
+ default:
171
+ return 0;
172
+ }
173
+}
174
+
175
+static inline uint64_t l1std_l2ptr(STEDesc *desc)
176
+{
177
+ uint64_t hi, lo;
178
+
179
+ hi = desc->word[1];
180
+ lo = desc->word[0] & ~0x1fULL;
181
+ return hi << 32 | lo;
182
+}
183
+
184
+#define L1STD_SPAN(stm) (extract32((stm)->word[0], 0, 4))
185
+
186
#endif
30
#endif
187
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
188
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
189
--- a/hw/arm/smmuv3.c
33
--- a/hw/display/tc6393xb.c
190
+++ b/hw/arm/smmuv3.c
34
+++ b/hw/display/tc6393xb.c
191
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
192
s->sid_split = 0;
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
41
- return s->gpio_in;
42
-}
43
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
45
{
46
// TC6393xbState *s = opaque;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
48
// FIXME: how does the chip reflect the GPIO input level change?
193
}
49
}
194
50
195
+static int smmu_get_ste(SMMUv3State *s, dma_addr_t addr, STE *buf,
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
196
+ SMMUEventInfo *event)
52
- qemu_irq handler)
197
+{
53
-{
198
+ int ret;
54
- if (line >= TC6393XB_GPIOS) {
199
+
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
200
+ trace_smmuv3_get_ste(addr);
56
- return;
201
+ /* TODO: guarantee 64-bit single-copy atomicity */
57
- }
202
+ ret = dma_memory_read(&address_space_memory, addr,
58
-
203
+ (void *)buf, sizeof(*buf));
59
- s->handler[line] = handler;
204
+ if (ret != MEMTX_OK) {
60
-}
205
+ qemu_log_mask(LOG_GUEST_ERROR,
61
-
206
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
207
+ event->type = SMMU_EVT_F_STE_FETCH;
208
+ event->u.f_ste_fetch.addr = addr;
209
+ return -EINVAL;
210
+ }
211
+ return 0;
212
+
213
+}
214
+
215
+/* @ssid > 0 not supported yet */
216
+static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
217
+ CD *buf, SMMUEventInfo *event)
218
+{
219
+ dma_addr_t addr = STE_CTXPTR(ste);
220
+ int ret;
221
+
222
+ trace_smmuv3_get_cd(addr);
223
+ /* TODO: guarantee 64-bit single-copy atomicity */
224
+ ret = dma_memory_read(&address_space_memory, addr,
225
+ (void *)buf, sizeof(*buf));
226
+ if (ret != MEMTX_OK) {
227
+ qemu_log_mask(LOG_GUEST_ERROR,
228
+ "Cannot fetch pte at address=0x%"PRIx64"\n", addr);
229
+ event->type = SMMU_EVT_F_CD_FETCH;
230
+ event->u.f_ste_fetch.addr = addr;
231
+ return -EINVAL;
232
+ }
233
+ return 0;
234
+}
235
+
236
+/* Returns <0 if the caller has no need to continue the translation */
237
+static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
238
+ STE *ste, SMMUEventInfo *event)
239
+{
240
+ uint32_t config;
241
+ int ret = -EINVAL;
242
+
243
+ if (!STE_VALID(ste)) {
244
+ goto bad_ste;
245
+ }
246
+
247
+ config = STE_CONFIG(ste);
248
+
249
+ if (STE_CFG_ABORT(config)) {
250
+ cfg->aborted = true; /* abort but don't record any event */
251
+ return ret;
252
+ }
253
+
254
+ if (STE_CFG_BYPASS(config)) {
255
+ cfg->bypassed = true;
256
+ return ret;
257
+ }
258
+
259
+ if (STE_CFG_S2_ENABLED(config)) {
260
+ qemu_log_mask(LOG_UNIMP, "SMMUv3 does not support stage 2 yet\n");
261
+ goto bad_ste;
262
+ }
263
+
264
+ if (STE_S1CDMAX(ste) != 0) {
265
+ qemu_log_mask(LOG_UNIMP,
266
+ "SMMUv3 does not support multiple context descriptors yet\n");
267
+ goto bad_ste;
268
+ }
269
+
270
+ if (STE_S1STALLD(ste)) {
271
+ qemu_log_mask(LOG_UNIMP,
272
+ "SMMUv3 S1 stalling fault model not allowed yet\n");
273
+ goto bad_ste;
274
+ }
275
+ return 0;
276
+
277
+bad_ste:
278
+ event->type = SMMU_EVT_C_BAD_STE;
279
+ return -EINVAL;
280
+}
281
+
282
+/**
283
+ * smmu_find_ste - Return the stream table entry associated
284
+ * to the sid
285
+ *
286
+ * @s: smmuv3 handle
287
+ * @sid: stream ID
288
+ * @ste: returned stream table entry
289
+ * @event: handle to an event info
290
+ *
291
+ * Supports linear and 2-level stream table
292
+ * Return 0 on success, -EINVAL otherwise
293
+ */
294
+static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
295
+ SMMUEventInfo *event)
296
+{
297
+ dma_addr_t addr;
298
+ int ret;
299
+
300
+ trace_smmuv3_find_ste(sid, s->features, s->sid_split);
301
+ /* Check SID range */
302
+ if (sid > (1 << SMMU_IDR1_SIDSIZE)) {
303
+ event->type = SMMU_EVT_C_BAD_STREAMID;
304
+ return -EINVAL;
305
+ }
306
+ if (s->features & SMMU_FEATURE_2LVL_STE) {
307
+ int l1_ste_offset, l2_ste_offset, max_l2_ste, span;
308
+ dma_addr_t strtab_base, l1ptr, l2ptr;
309
+ STEDesc l1std;
310
+
311
+ strtab_base = s->strtab_base & SMMU_BASE_ADDR_MASK;
312
+ l1_ste_offset = sid >> s->sid_split;
313
+ l2_ste_offset = sid & ((1 << s->sid_split) - 1);
314
+ l1ptr = (dma_addr_t)(strtab_base + l1_ste_offset * sizeof(l1std));
315
+ /* TODO: guarantee 64-bit single-copy atomicity */
316
+ ret = dma_memory_read(&address_space_memory, l1ptr,
317
+ (uint8_t *)&l1std, sizeof(l1std));
318
+ if (ret != MEMTX_OK) {
319
+ qemu_log_mask(LOG_GUEST_ERROR,
320
+ "Could not read L1PTR at 0X%"PRIx64"\n", l1ptr);
321
+ event->type = SMMU_EVT_F_STE_FETCH;
322
+ event->u.f_ste_fetch.addr = l1ptr;
323
+ return -EINVAL;
324
+ }
325
+
326
+ span = L1STD_SPAN(&l1std);
327
+
328
+ if (!span) {
329
+ /* l2ptr is not valid */
330
+ qemu_log_mask(LOG_GUEST_ERROR,
331
+ "invalid sid=%d (L1STD span=0)\n", sid);
332
+ event->type = SMMU_EVT_C_BAD_STREAMID;
333
+ return -EINVAL;
334
+ }
335
+ max_l2_ste = (1 << span) - 1;
336
+ l2ptr = l1std_l2ptr(&l1std);
337
+ trace_smmuv3_find_ste_2lvl(s->strtab_base, l1ptr, l1_ste_offset,
338
+ l2ptr, l2_ste_offset, max_l2_ste);
339
+ if (l2_ste_offset > max_l2_ste) {
340
+ qemu_log_mask(LOG_GUEST_ERROR,
341
+ "l2_ste_offset=%d > max_l2_ste=%d\n",
342
+ l2_ste_offset, max_l2_ste);
343
+ event->type = SMMU_EVT_C_BAD_STE;
344
+ return -EINVAL;
345
+ }
346
+ addr = l2ptr + l2_ste_offset * sizeof(*ste);
347
+ } else {
348
+ addr = s->strtab_base + sid * sizeof(*ste);
349
+ }
350
+
351
+ if (smmu_get_ste(s, addr, ste, event)) {
352
+ return -EINVAL;
353
+ }
354
+
355
+ return 0;
356
+}
357
+
358
+static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
359
+{
360
+ int ret = -EINVAL;
361
+ int i;
362
+
363
+ if (!CD_VALID(cd) || !CD_AARCH64(cd)) {
364
+ goto bad_cd;
365
+ }
366
+ if (!CD_A(cd)) {
367
+ goto bad_cd; /* SMMU_IDR0.TERM_MODEL == 1 */
368
+ }
369
+ if (CD_S(cd)) {
370
+ goto bad_cd; /* !STE_SECURE && SMMU_IDR0.STALL_MODEL == 1 */
371
+ }
372
+ if (CD_HA(cd) || CD_HD(cd)) {
373
+ goto bad_cd; /* HTTU = 0 */
374
+ }
375
+
376
+ /* we support only those at the moment */
377
+ cfg->aa64 = true;
378
+ cfg->stage = 1;
379
+
380
+ cfg->oas = oas2bits(CD_IPS(cd));
381
+ cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
382
+ cfg->tbi = CD_TBI(cd);
383
+ cfg->asid = CD_ASID(cd);
384
+
385
+ trace_smmuv3_decode_cd(cfg->oas);
386
+
387
+ /* decode data dependent on TT */
388
+ for (i = 0; i <= 1; i++) {
389
+ int tg, tsz;
390
+ SMMUTransTableInfo *tt = &cfg->tt[i];
391
+
392
+ cfg->tt[i].disabled = CD_EPD(cd, i);
393
+ if (cfg->tt[i].disabled) {
394
+ continue;
395
+ }
396
+
397
+ tsz = CD_TSZ(cd, i);
398
+ if (tsz < 16 || tsz > 39) {
399
+ goto bad_cd;
400
+ }
401
+
402
+ tg = CD_TG(cd, i);
403
+ tt->granule_sz = tg2granule(tg, i);
404
+ if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
405
+ goto bad_cd;
406
+ }
407
+
408
+ tt->tsz = tsz;
409
+ tt->ttb = CD_TTB(cd, i);
410
+ if (tt->ttb & ~(MAKE_64BIT_MASK(0, cfg->oas))) {
411
+ goto bad_cd;
412
+ }
413
+ trace_smmuv3_decode_cd_tt(i, tt->tsz, tt->ttb, tt->granule_sz);
414
+ }
415
+
416
+ event->record_trans_faults = CD_R(cd);
417
+
418
+ return 0;
419
+
420
+bad_cd:
421
+ event->type = SMMU_EVT_C_BAD_CD;
422
+ return ret;
423
+}
424
+
425
+/**
426
+ * smmuv3_decode_config - Prepare the translation configuration
427
+ * for the @mr iommu region
428
+ * @mr: iommu memory region the translation config must be prepared for
429
+ * @cfg: output translation configuration which is populated through
430
+ * the different configuration decoding steps
431
+ * @event: must be zero'ed by the caller
432
+ *
433
+ * return < 0 if the translation needs to be aborted (@event is filled
434
+ * accordingly). Return 0 otherwise.
435
+ */
436
+static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
437
+ SMMUEventInfo *event)
438
+{
439
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
440
+ uint32_t sid = smmu_get_sid(sdev);
441
+ SMMUv3State *s = sdev->smmu;
442
+ int ret = -EINVAL;
443
+ STE ste;
444
+ CD cd;
445
+
446
+ if (smmu_find_ste(s, sid, &ste, event)) {
447
+ return ret;
448
+ }
449
+
450
+ if (decode_ste(s, cfg, &ste, event)) {
451
+ return ret;
452
+ }
453
+
454
+ if (smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event)) {
455
+ return ret;
456
+ }
457
+
458
+ return decode_cd(cfg, &cd, event);
459
+}
460
+
461
+static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
462
+ IOMMUAccessFlags flag)
463
+{
464
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
465
+ SMMUv3State *s = sdev->smmu;
466
+ uint32_t sid = smmu_get_sid(sdev);
467
+ SMMUEventInfo event = {.type = SMMU_EVT_OK, .sid = sid};
468
+ SMMUPTWEventInfo ptw_info = {};
469
+ SMMUTransCfg cfg = {};
470
+ IOMMUTLBEntry entry = {
471
+ .target_as = &address_space_memory,
472
+ .iova = addr,
473
+ .translated_addr = addr,
474
+ .addr_mask = ~(hwaddr)0,
475
+ .perm = IOMMU_NONE,
476
+ };
477
+ int ret = 0;
478
+
479
+ if (!smmu_enabled(s)) {
480
+ goto out;
481
+ }
482
+
483
+ ret = smmuv3_decode_config(mr, &cfg, &event);
484
+ if (ret) {
485
+ goto out;
486
+ }
487
+
488
+ if (cfg.aborted) {
489
+ goto out;
490
+ }
491
+
492
+ ret = smmu_ptw(&cfg, addr, flag, &entry, &ptw_info);
493
+ if (ret) {
494
+ switch (ptw_info.type) {
495
+ case SMMU_PTW_ERR_WALK_EABT:
496
+ event.type = SMMU_EVT_F_WALK_EABT;
497
+ event.u.f_walk_eabt.addr = addr;
498
+ event.u.f_walk_eabt.rnw = flag & 0x1;
499
+ event.u.f_walk_eabt.class = 0x1;
500
+ event.u.f_walk_eabt.addr2 = ptw_info.addr;
501
+ break;
502
+ case SMMU_PTW_ERR_TRANSLATION:
503
+ if (event.record_trans_faults) {
504
+ event.type = SMMU_EVT_F_TRANSLATION;
505
+ event.u.f_translation.addr = addr;
506
+ event.u.f_translation.rnw = flag & 0x1;
507
+ }
508
+ break;
509
+ case SMMU_PTW_ERR_ADDR_SIZE:
510
+ if (event.record_trans_faults) {
511
+ event.type = SMMU_EVT_F_ADDR_SIZE;
512
+ event.u.f_addr_size.addr = addr;
513
+ event.u.f_addr_size.rnw = flag & 0x1;
514
+ }
515
+ break;
516
+ case SMMU_PTW_ERR_ACCESS:
517
+ if (event.record_trans_faults) {
518
+ event.type = SMMU_EVT_F_ACCESS;
519
+ event.u.f_access.addr = addr;
520
+ event.u.f_access.rnw = flag & 0x1;
521
+ }
522
+ break;
523
+ case SMMU_PTW_ERR_PERMISSION:
524
+ if (event.record_trans_faults) {
525
+ event.type = SMMU_EVT_F_PERMISSION;
526
+ event.u.f_permission.addr = addr;
527
+ event.u.f_permission.rnw = flag & 0x1;
528
+ }
529
+ break;
530
+ default:
531
+ g_assert_not_reached();
532
+ }
533
+ }
534
+out:
535
+ if (ret) {
536
+ qemu_log_mask(LOG_GUEST_ERROR,
537
+ "%s translation failed for iova=0x%"PRIx64"(%d)\n",
538
+ mr->parent_obj.name, addr, ret);
539
+ entry.perm = IOMMU_NONE;
540
+ smmuv3_record_event(s, &event);
541
+ } else if (!cfg.aborted) {
542
+ entry.perm = flag;
543
+ trace_smmuv3_translate(mr->parent_obj.name, sid, addr,
544
+ entry.translated_addr, entry.perm);
545
+ }
546
+
547
+ return entry;
548
+}
549
+
550
static int smmuv3_cmdq_consume(SMMUv3State *s)
551
{
63
{
552
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
64
uint32_t level, diff;
553
@@ -XXX,XX +XXX,XX @@ static void smmuv3_class_init(ObjectClass *klass, void *data)
554
static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
555
void *data)
556
{
557
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
558
+
559
+ imrc->translate = smmuv3_translate;
560
}
561
562
static const TypeInfo smmuv3_type_info = {
563
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
564
index XXXXXXX..XXXXXXX 100644
565
--- a/hw/arm/trace-events
566
+++ b/hw/arm/trace-events
567
@@ -XXX,XX +XXX,XX @@ smmuv3_write_mmio_idr(uint64_t addr, uint64_t val) "write to RO/Unimpl reg 0x%lx
568
smmuv3_write_mmio_evtq_cons_bef_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "Before clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
569
smmuv3_write_mmio_evtq_cons_after_clear(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "after clearing interrupt prod:0x%x cons:0x%x prod.w:%d cons.w:%d"
570
smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
571
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
572
+smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%lx l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
573
+smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
574
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass iova:0x%"PRIx64" is_write=%d"
575
+smmuv3_translate_in(uint16_t sid, int pci_bus_num, uint64_t strtab_base) "SID:0x%x bus:%d strtab_base:0x%"PRIx64
576
+smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
577
+smmuv3_translate(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
578
+smmuv3_decode_cd(uint32_t oas) "oas=%d"
579
+smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d"
580
--
65
--
581
2.17.0
66
2.20.1
582
67
583
68
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
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
New patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
2
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
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The patch introduces the smmu base device and class for the ARM
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
smmu. Devices for specific versions will be derived from this
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
base device.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
7
We also introduce some important datatypes.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-2-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
8
---
15
hw/arm/Makefile.objs | 1 +
9
include/hw/devices.h | 14 --------------
16
include/hw/arm/smmu-common.h | 123 ++++++++++++++++++++++++++++
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
17
hw/arm/smmu-common.c | 81 ++++++++++++++++++
11
hw/arm/nseries.c | 1 +
18
default-configs/aarch64-softmmu.mak | 1 +
12
hw/misc/cbus.c | 2 +-
19
4 files changed, 206 insertions(+)
13
MAINTAINERS | 1 +
20
create mode 100644 include/hw/arm/smmu-common.h
14
5 files changed, 35 insertions(+), 15 deletions(-)
21
create mode 100644 hw/arm/smmu-common.c
15
create mode 100644 include/hw/misc/cbus.h
22
16
23
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/Makefile.objs
19
--- a/include/hw/devices.h
26
+++ b/hw/arm/Makefile.objs
20
+++ b/include/hw/devices.h
27
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
28
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
22
/* stellaris_input.c */
29
obj-$(CONFIG_IOTKIT) += iotkit.o
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
30
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
24
31
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
25
-/* cbus.c */
32
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
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
33
new file mode 100644
41
new file mode 100644
34
index XXXXXXX..XXXXXXX
42
index XXXXXXX..XXXXXXX
35
--- /dev/null
43
--- /dev/null
36
+++ b/include/hw/arm/smmu-common.h
44
+++ b/include/hw/misc/cbus.h
37
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
38
+/*
46
+/*
39
+ * ARM SMMU Support
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.
40
+ *
50
+ *
41
+ * Copyright (C) 2015-2016 Broadcom Corporation
51
+ * Copyright (C) 2008 Nokia Corporation
42
+ * Copyright (c) 2017 Red Hat, Inc.
52
+ * Written by Andrzej Zaborowski
43
+ * Written by Prem Mallappa, Eric Auger
44
+ *
53
+ *
45
+ * This program is free software; you can redistribute it and/or modify
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
46
+ * it under the terms of the GNU General Public License version 2 as
55
+ * See the COPYING file in the top-level directory.
47
+ * published by the Free Software Foundation.
48
+ *
49
+ * This program is distributed in the hope that it will be useful,
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52
+ * GNU General Public License for more details.
53
+ *
54
+ */
56
+ */
55
+
57
+
56
+#ifndef HW_ARM_SMMU_COMMON_H
58
+#ifndef HW_MISC_CBUS_H
57
+#define HW_ARM_SMMU_COMMON_H
59
+#define HW_MISC_CBUS_H
58
+
60
+
59
+#include "hw/sysbus.h"
61
+#include "hw/irq.h"
60
+#include "hw/pci/pci.h"
61
+
62
+#define SMMU_PCI_BUS_MAX 256
63
+#define SMMU_PCI_DEVFN_MAX 256
64
+
65
+#define SMMU_MAX_VA_BITS 48
66
+
67
+/*
68
+ * Page table walk error types
69
+ */
70
+typedef enum {
71
+ SMMU_PTW_ERR_NONE,
72
+ SMMU_PTW_ERR_WALK_EABT, /* Translation walk external abort */
73
+ SMMU_PTW_ERR_TRANSLATION, /* Translation fault */
74
+ SMMU_PTW_ERR_ADDR_SIZE, /* Address Size fault */
75
+ SMMU_PTW_ERR_ACCESS, /* Access fault */
76
+ SMMU_PTW_ERR_PERMISSION, /* Permission fault */
77
+} SMMUPTWEventType;
78
+
79
+typedef struct SMMUPTWEventInfo {
80
+ SMMUPTWEventType type;
81
+ dma_addr_t addr; /* fetched address that induced an abort, if any */
82
+} SMMUPTWEventInfo;
83
+
84
+typedef struct SMMUTransTableInfo {
85
+ bool disabled; /* is the translation table disabled? */
86
+ uint64_t ttb; /* TT base address */
87
+ uint8_t tsz; /* input range, ie. 2^(64 -tsz)*/
88
+ uint8_t granule_sz; /* granule page shift */
89
+} SMMUTransTableInfo;
90
+
91
+/*
92
+ * Generic structure populated by derived SMMU devices
93
+ * after decoding the configuration information and used as
94
+ * input to the page table walk
95
+ */
96
+typedef struct SMMUTransCfg {
97
+ int stage; /* translation stage */
98
+ bool aa64; /* arch64 or aarch32 translation table */
99
+ bool disabled; /* smmu is disabled */
100
+ bool bypassed; /* translation is bypassed */
101
+ bool aborted; /* translation is aborted */
102
+ uint64_t ttb; /* TT base address */
103
+ uint8_t oas; /* output address width */
104
+ uint8_t tbi; /* Top Byte Ignore */
105
+ uint16_t asid;
106
+ SMMUTransTableInfo tt[2];
107
+} SMMUTransCfg;
108
+
109
+typedef struct SMMUDevice {
110
+ void *smmu;
111
+ PCIBus *bus;
112
+ int devfn;
113
+ IOMMUMemoryRegion iommu;
114
+ AddressSpace as;
115
+} SMMUDevice;
116
+
117
+typedef struct SMMUNotifierNode {
118
+ SMMUDevice *sdev;
119
+ QLIST_ENTRY(SMMUNotifierNode) next;
120
+} SMMUNotifierNode;
121
+
122
+typedef struct SMMUPciBus {
123
+ PCIBus *bus;
124
+ SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
125
+} SMMUPciBus;
126
+
127
+typedef struct SMMUState {
128
+ /* <private> */
129
+ SysBusDevice dev;
130
+ const char *mrtypename;
131
+ MemoryRegion iomem;
132
+
133
+ GHashTable *smmu_pcibus_by_busptr;
134
+ GHashTable *configs; /* cache for configuration data */
135
+ GHashTable *iotlb;
136
+ SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
137
+ PCIBus *pci_bus;
138
+ QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
139
+ uint8_t bus_num;
140
+ PCIBus *primary_bus;
141
+} SMMUState;
142
+
62
+
143
+typedef struct {
63
+typedef struct {
144
+ /* <private> */
64
+ qemu_irq clk;
145
+ SysBusDeviceClass parent_class;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
146
+
68
+
147
+ /*< public >*/
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
148
+
71
+
149
+ DeviceRealize parent_realize;
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
150
+
74
+
151
+} SMMUBaseClass;
75
+void retu_key_event(void *retu, int state);
152
+
76
+
153
+#define TYPE_ARM_SMMU "arm-smmu"
77
+#endif
154
+#define ARM_SMMU(obj) OBJECT_CHECK(SMMUState, (obj), TYPE_ARM_SMMU)
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
155
+#define ARM_SMMU_CLASS(klass) \
79
index XXXXXXX..XXXXXXX 100644
156
+ OBJECT_CLASS_CHECK(SMMUBaseClass, (klass), TYPE_ARM_SMMU)
80
--- a/hw/arm/nseries.c
157
+#define ARM_SMMU_GET_CLASS(obj) \
81
+++ b/hw/arm/nseries.c
158
+ OBJECT_GET_CLASS(SMMUBaseClass, (obj), TYPE_ARM_SMMU)
159
+
160
+#endif /* HW_ARM_SMMU_COMMON */
161
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
162
new file mode 100644
163
index XXXXXXX..XXXXXXX
164
--- /dev/null
165
+++ b/hw/arm/smmu-common.c
166
@@ -XXX,XX +XXX,XX @@
82
@@ -XXX,XX +XXX,XX @@
167
+/*
83
#include "hw/i2c/i2c.h"
168
+ * Copyright (C) 2014-2016 Broadcom Corporation
84
#include "hw/devices.h"
169
+ * Copyright (c) 2017 Red Hat, Inc.
85
#include "hw/display/blizzard.h"
170
+ * Written by Prem Mallappa, Eric Auger
86
+#include "hw/misc/cbus.h"
171
+ *
87
#include "hw/misc/tmp105.h"
172
+ * This program is free software; you can redistribute it and/or modify
88
#include "hw/block/flash.h"
173
+ * it under the terms of the GNU General Public License version 2 as
89
#include "hw/hw.h"
174
+ * published by the Free Software Foundation.
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
175
+ *
176
+ * This program is distributed in the hope that it will be useful,
177
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
178
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
179
+ * GNU General Public License for more details.
180
+ *
181
+ * Author: Prem Mallappa <pmallapp@broadcom.com>
182
+ *
183
+ */
184
+
185
+#include "qemu/osdep.h"
186
+#include "sysemu/sysemu.h"
187
+#include "exec/address-spaces.h"
188
+#include "trace.h"
189
+#include "exec/target_page.h"
190
+#include "qom/cpu.h"
191
+#include "hw/qdev-properties.h"
192
+#include "qapi/error.h"
193
+
194
+#include "qemu/error-report.h"
195
+#include "hw/arm/smmu-common.h"
196
+
197
+static void smmu_base_realize(DeviceState *dev, Error **errp)
198
+{
199
+ SMMUBaseClass *sbc = ARM_SMMU_GET_CLASS(dev);
200
+ Error *local_err = NULL;
201
+
202
+ sbc->parent_realize(dev, &local_err);
203
+ if (local_err) {
204
+ error_propagate(errp, local_err);
205
+ return;
206
+ }
207
+}
208
+
209
+static void smmu_base_reset(DeviceState *dev)
210
+{
211
+ /* will be filled later on */
212
+}
213
+
214
+static Property smmu_dev_properties[] = {
215
+ DEFINE_PROP_UINT8("bus_num", SMMUState, bus_num, 0),
216
+ DEFINE_PROP_LINK("primary-bus", SMMUState, primary_bus, "PCI", PCIBus *),
217
+ DEFINE_PROP_END_OF_LIST(),
218
+};
219
+
220
+static void smmu_base_class_init(ObjectClass *klass, void *data)
221
+{
222
+ DeviceClass *dc = DEVICE_CLASS(klass);
223
+ SMMUBaseClass *sbc = ARM_SMMU_CLASS(klass);
224
+
225
+ dc->props = smmu_dev_properties;
226
+ device_class_set_parent_realize(dc, smmu_base_realize,
227
+ &sbc->parent_realize);
228
+ dc->reset = smmu_base_reset;
229
+}
230
+
231
+static const TypeInfo smmu_base_info = {
232
+ .name = TYPE_ARM_SMMU,
233
+ .parent = TYPE_SYS_BUS_DEVICE,
234
+ .instance_size = sizeof(SMMUState),
235
+ .class_data = NULL,
236
+ .class_size = sizeof(SMMUBaseClass),
237
+ .class_init = smmu_base_class_init,
238
+ .abstract = true,
239
+};
240
+
241
+static void smmu_base_register_types(void)
242
+{
243
+ type_register_static(&smmu_base_info);
244
+}
245
+
246
+type_init(smmu_base_register_types)
247
+
248
diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
249
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
250
--- a/default-configs/aarch64-softmmu.mak
92
--- a/hw/misc/cbus.c
251
+++ b/default-configs/aarch64-softmmu.mak
93
+++ b/hw/misc/cbus.c
252
@@ -XXX,XX +XXX,XX @@ CONFIG_DDC=y
94
@@ -XXX,XX +XXX,XX @@
253
CONFIG_DPCD=y
95
#include "qemu/osdep.h"
254
CONFIG_XLNX_ZYNQMP=y
96
#include "hw/hw.h"
255
CONFIG_XLNX_ZYNQMP_ARM=y
97
#include "hw/irq.h"
256
+CONFIG_ARM_SMMUV3=y
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>
257
--
115
--
258
2.17.0
116
2.20.1
259
117
260
118
diff view generated by jsdifflib
1
From: Prem Mallappa <prem.mallappa@broadcom.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch implements a skeleton for the smmuv3 device.
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Datatypes and register definitions are introduced. The MMIO
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
region, the interrupts and the queue are initialized.
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
6
7
Only the MMIO read operation is implemented here.
8
9
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1524665762-31355-5-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
7
---
15
hw/arm/Makefile.objs | 2 +-
8
include/hw/devices.h | 3 ---
16
hw/arm/smmuv3-internal.h | 142 +++++++++++++++
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
17
include/hw/arm/smmuv3.h | 87 ++++++++++
10
hw/arm/stellaris.c | 2 +-
18
hw/arm/smmuv3.c | 366 +++++++++++++++++++++++++++++++++++++++
11
hw/input/stellaris_input.c | 2 +-
19
hw/arm/trace-events | 3 +
12
MAINTAINERS | 1 +
20
5 files changed, 599 insertions(+), 1 deletion(-)
13
5 files changed, 22 insertions(+), 5 deletions(-)
21
create mode 100644 hw/arm/smmuv3-internal.h
14
create mode 100644 include/hw/input/gamepad.h
22
create mode 100644 include/hw/arm/smmuv3.h
23
create mode 100644 hw/arm/smmuv3.c
24
15
25
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/Makefile.objs
18
--- a/include/hw/devices.h
28
+++ b/hw/arm/Makefile.objs
19
+++ b/include/hw/devices.h
29
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MPS2) += mps2-tz.o
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
30
obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
31
obj-$(CONFIG_IOTKIT) += iotkit.o
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
32
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
23
33
-obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o
24
-/* stellaris_input.c */
34
+obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
35
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
36
new file mode 100644
29
new file mode 100644
37
index XXXXXXX..XXXXXXX
30
index XXXXXXX..XXXXXXX
38
--- /dev/null
31
--- /dev/null
39
+++ b/hw/arm/smmuv3-internal.h
32
+++ b/include/hw/input/gamepad.h
40
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@
41
+/*
34
+/*
42
+ * ARM SMMUv3 support - Internal API
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
43
+ *
36
+ *
44
+ * Copyright (C) 2014-2016 Broadcom Corporation
37
+ * Copyright (c) 2007 CodeSourcery.
45
+ * Copyright (c) 2017 Red Hat, Inc.
38
+ * Written by Paul Brook
46
+ * Written by Prem Mallappa, Eric Auger
47
+ *
39
+ *
48
+ * This program is free software; you can redistribute it and/or modify
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+ * it under the terms of the GNU General Public License version 2 as
41
+ * See the COPYING file in the top-level directory.
50
+ * published by the Free Software Foundation.
51
+ *
52
+ * This program is distributed in the hope that it will be useful,
53
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55
+ * GNU General Public License for more details.
56
+ *
57
+ * You should have received a copy of the GNU General Public License along
58
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
59
+ */
42
+ */
60
+
43
+
61
+#ifndef HW_ARM_SMMU_V3_INTERNAL_H
44
+#ifndef HW_INPUT_GAMEPAD_H
62
+#define HW_ARM_SMMU_V3_INTERNAL_H
45
+#define HW_INPUT_GAMEPAD_H
63
+
46
+
64
+#include "hw/arm/smmu-common.h"
47
+#include "hw/irq.h"
65
+
48
+
66
+/* MMIO Registers */
49
+/* stellaris_input.c */
67
+
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
68
+REG32(IDR0, 0x0)
69
+ FIELD(IDR0, S1P, 1 , 1)
70
+ FIELD(IDR0, TTF, 2 , 2)
71
+ FIELD(IDR0, COHACC, 4 , 1)
72
+ FIELD(IDR0, ASID16, 12, 1)
73
+ FIELD(IDR0, TTENDIAN, 21, 2)
74
+ FIELD(IDR0, STALL_MODEL, 24, 2)
75
+ FIELD(IDR0, TERM_MODEL, 26, 1)
76
+ FIELD(IDR0, STLEVEL, 27, 2)
77
+
78
+REG32(IDR1, 0x4)
79
+ FIELD(IDR1, SIDSIZE, 0 , 6)
80
+ FIELD(IDR1, EVENTQS, 16, 5)
81
+ FIELD(IDR1, CMDQS, 21, 5)
82
+
83
+#define SMMU_IDR1_SIDSIZE 16
84
+#define SMMU_CMDQS 19
85
+#define SMMU_EVENTQS 19
86
+
87
+REG32(IDR2, 0x8)
88
+REG32(IDR3, 0xc)
89
+REG32(IDR4, 0x10)
90
+REG32(IDR5, 0x14)
91
+ FIELD(IDR5, OAS, 0, 3);
92
+ FIELD(IDR5, GRAN4K, 4, 1);
93
+ FIELD(IDR5, GRAN16K, 5, 1);
94
+ FIELD(IDR5, GRAN64K, 6, 1);
95
+
96
+#define SMMU_IDR5_OAS 4
97
+
98
+REG32(IIDR, 0x1c)
99
+REG32(CR0, 0x20)
100
+ FIELD(CR0, SMMU_ENABLE, 0, 1)
101
+ FIELD(CR0, EVENTQEN, 2, 1)
102
+ FIELD(CR0, CMDQEN, 3, 1)
103
+
104
+REG32(CR0ACK, 0x24)
105
+REG32(CR1, 0x28)
106
+REG32(CR2, 0x2c)
107
+REG32(STATUSR, 0x40)
108
+REG32(IRQ_CTRL, 0x50)
109
+ FIELD(IRQ_CTRL, GERROR_IRQEN, 0, 1)
110
+ FIELD(IRQ_CTRL, PRI_IRQEN, 1, 1)
111
+ FIELD(IRQ_CTRL, EVENTQ_IRQEN, 2, 1)
112
+
113
+REG32(IRQ_CTRL_ACK, 0x54)
114
+REG32(GERROR, 0x60)
115
+ FIELD(GERROR, CMDQ_ERR, 0, 1)
116
+ FIELD(GERROR, EVENTQ_ABT_ERR, 2, 1)
117
+ FIELD(GERROR, PRIQ_ABT_ERR, 3, 1)
118
+ FIELD(GERROR, MSI_CMDQ_ABT_ERR, 4, 1)
119
+ FIELD(GERROR, MSI_EVENTQ_ABT_ERR, 5, 1)
120
+ FIELD(GERROR, MSI_PRIQ_ABT_ERR, 6, 1)
121
+ FIELD(GERROR, MSI_GERROR_ABT_ERR, 7, 1)
122
+ FIELD(GERROR, MSI_SFM_ERR, 8, 1)
123
+
124
+REG32(GERRORN, 0x64)
125
+
126
+#define A_GERROR_IRQ_CFG0 0x68 /* 64b */
127
+REG32(GERROR_IRQ_CFG1, 0x70)
128
+REG32(GERROR_IRQ_CFG2, 0x74)
129
+
130
+#define A_STRTAB_BASE 0x80 /* 64b */
131
+
132
+#define SMMU_BASE_ADDR_MASK 0xffffffffffe0
133
+
134
+REG32(STRTAB_BASE_CFG, 0x88)
135
+ FIELD(STRTAB_BASE_CFG, FMT, 16, 2)
136
+ FIELD(STRTAB_BASE_CFG, SPLIT, 6 , 5)
137
+ FIELD(STRTAB_BASE_CFG, LOG2SIZE, 0 , 6)
138
+
139
+#define A_CMDQ_BASE 0x90 /* 64b */
140
+REG32(CMDQ_PROD, 0x98)
141
+REG32(CMDQ_CONS, 0x9c)
142
+ FIELD(CMDQ_CONS, ERR, 24, 7)
143
+
144
+#define A_EVENTQ_BASE 0xa0 /* 64b */
145
+REG32(EVENTQ_PROD, 0xa8)
146
+REG32(EVENTQ_CONS, 0xac)
147
+
148
+#define A_EVENTQ_IRQ_CFG0 0xb0 /* 64b */
149
+REG32(EVENTQ_IRQ_CFG1, 0xb8)
150
+REG32(EVENTQ_IRQ_CFG2, 0xbc)
151
+
152
+#define A_IDREGS 0xfd0
153
+
154
+static inline int smmu_enabled(SMMUv3State *s)
155
+{
156
+ return FIELD_EX32(s->cr[0], CR0, SMMU_ENABLE);
157
+}
158
+
159
+/* Command Queue Entry */
160
+typedef struct Cmd {
161
+ uint32_t word[4];
162
+} Cmd;
163
+
164
+/* Event Queue Entry */
165
+typedef struct Evt {
166
+ uint32_t word[8];
167
+} Evt;
168
+
169
+static inline uint32_t smmuv3_idreg(int regoffset)
170
+{
171
+ /*
172
+ * Return the value of the Primecell/Corelink ID registers at the
173
+ * specified offset from the first ID register.
174
+ * These value indicate an ARM implementation of MMU600 p1
175
+ */
176
+ static const uint8_t smmuv3_ids[] = {
177
+ 0x04, 0, 0, 0, 0x84, 0xB4, 0xF0, 0x10, 0x0D, 0xF0, 0x05, 0xB1
178
+ };
179
+ return smmuv3_ids[regoffset / 4];
180
+}
181
+
51
+
182
+#endif
52
+#endif
183
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
184
new file mode 100644
54
index XXXXXXX..XXXXXXX 100644
185
index XXXXXXX..XXXXXXX
55
--- a/hw/arm/stellaris.c
186
--- /dev/null
56
+++ b/hw/arm/stellaris.c
187
+++ b/include/hw/arm/smmuv3.h
188
@@ -XXX,XX +XXX,XX @@
57
@@ -XXX,XX +XXX,XX @@
189
+/*
58
#include "hw/sysbus.h"
190
+ * Copyright (C) 2014-2016 Broadcom Corporation
59
#include "hw/ssi/ssi.h"
191
+ * Copyright (c) 2017 Red Hat, Inc.
60
#include "hw/arm/arm.h"
192
+ * Written by Prem Mallappa, Eric Auger
61
-#include "hw/devices.h"
193
+ *
62
#include "qemu/timer.h"
194
+ * This program is free software; you can redistribute it and/or modify
63
#include "hw/i2c/i2c.h"
195
+ * it under the terms of the GNU General Public License version 2 as
64
#include "net/net.h"
196
+ * published by the Free Software Foundation.
197
+ *
198
+ * This program is distributed in the hope that it will be useful,
199
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
200
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201
+ * GNU General Public License for more details.
202
+ *
203
+ * You should have received a copy of the GNU General Public License along
204
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
205
+ */
206
+
207
+#ifndef HW_ARM_SMMUV3_H
208
+#define HW_ARM_SMMUV3_H
209
+
210
+#include "hw/arm/smmu-common.h"
211
+#include "hw/registerfields.h"
212
+
213
+#define TYPE_SMMUV3_IOMMU_MEMORY_REGION "smmuv3-iommu-memory-region"
214
+
215
+typedef struct SMMUQueue {
216
+ uint64_t base; /* base register */
217
+ uint32_t prod;
218
+ uint32_t cons;
219
+ uint8_t entry_size;
220
+ uint8_t log2size;
221
+} SMMUQueue;
222
+
223
+typedef struct SMMUv3State {
224
+ SMMUState smmu_state;
225
+
226
+ uint32_t features;
227
+ uint8_t sid_size;
228
+ uint8_t sid_split;
229
+
230
+ uint32_t idr[6];
231
+ uint32_t iidr;
232
+ uint32_t cr[3];
233
+ uint32_t cr0ack;
234
+ uint32_t statusr;
235
+ uint32_t irq_ctrl;
236
+ uint32_t gerror;
237
+ uint32_t gerrorn;
238
+ uint64_t gerror_irq_cfg0;
239
+ uint32_t gerror_irq_cfg1;
240
+ uint32_t gerror_irq_cfg2;
241
+ uint64_t strtab_base;
242
+ uint32_t strtab_base_cfg;
243
+ uint64_t eventq_irq_cfg0;
244
+ uint32_t eventq_irq_cfg1;
245
+ uint32_t eventq_irq_cfg2;
246
+
247
+ SMMUQueue eventq, cmdq;
248
+
249
+ qemu_irq irq[4];
250
+} SMMUv3State;
251
+
252
+typedef enum {
253
+ SMMU_IRQ_EVTQ,
254
+ SMMU_IRQ_PRIQ,
255
+ SMMU_IRQ_CMD_SYNC,
256
+ SMMU_IRQ_GERROR,
257
+} SMMUIrq;
258
+
259
+typedef struct {
260
+ /*< private >*/
261
+ SMMUBaseClass smmu_base_class;
262
+ /*< public >*/
263
+
264
+ DeviceRealize parent_realize;
265
+ DeviceReset parent_reset;
266
+} SMMUv3Class;
267
+
268
+#define TYPE_ARM_SMMUV3 "arm-smmuv3"
269
+#define ARM_SMMUV3(obj) OBJECT_CHECK(SMMUv3State, (obj), TYPE_ARM_SMMUV3)
270
+#define ARM_SMMUV3_CLASS(klass) \
271
+ OBJECT_CLASS_CHECK(SMMUv3Class, (klass), TYPE_ARM_SMMUV3)
272
+#define ARM_SMMUV3_GET_CLASS(obj) \
273
+ OBJECT_GET_CLASS(SMMUv3Class, (obj), TYPE_ARM_SMMUV3)
274
+
275
+#endif
276
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
277
new file mode 100644
278
index XXXXXXX..XXXXXXX
279
--- /dev/null
280
+++ b/hw/arm/smmuv3.c
281
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
282
+/*
66
#include "sysemu/sysemu.h"
283
+ * Copyright (C) 2014-2016 Broadcom Corporation
67
#include "hw/arm/armv7m.h"
284
+ * Copyright (c) 2017 Red Hat, Inc.
68
#include "hw/char/pl011.h"
285
+ * Written by Prem Mallappa, Eric Auger
69
+#include "hw/input/gamepad.h"
286
+ *
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
287
+ * This program is free software; you can redistribute it and/or modify
71
#include "hw/misc/unimp.h"
288
+ * it under the terms of the GNU General Public License version 2 as
72
#include "cpu.h"
289
+ * published by the Free Software Foundation.
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
290
+ *
291
+ * This program is distributed in the hope that it will be useful,
292
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
293
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
294
+ * GNU General Public License for more details.
295
+ *
296
+ * You should have received a copy of the GNU General Public License along
297
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
298
+ */
299
+
300
+#include "qemu/osdep.h"
301
+#include "hw/boards.h"
302
+#include "sysemu/sysemu.h"
303
+#include "hw/sysbus.h"
304
+#include "hw/qdev-core.h"
305
+#include "hw/pci/pci.h"
306
+#include "exec/address-spaces.h"
307
+#include "trace.h"
308
+#include "qemu/log.h"
309
+#include "qemu/error-report.h"
310
+#include "qapi/error.h"
311
+
312
+#include "hw/arm/smmuv3.h"
313
+#include "smmuv3-internal.h"
314
+
315
+static void smmuv3_init_regs(SMMUv3State *s)
316
+{
317
+ /**
318
+ * IDR0: stage1 only, AArch64 only, coherent access, 16b ASID,
319
+ * multi-level stream table
320
+ */
321
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, S1P, 1); /* stage 1 supported */
322
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTF, 2); /* AArch64 PTW only */
323
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, COHACC, 1); /* IO coherent */
324
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, ASID16, 1); /* 16-bit ASID */
325
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TTENDIAN, 2); /* little endian */
326
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STALL_MODEL, 1); /* No stall */
327
+ /* terminated transaction will always be aborted/error returned */
328
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, TERM_MODEL, 1);
329
+ /* 2-level stream table supported */
330
+ s->idr[0] = FIELD_DP32(s->idr[0], IDR0, STLEVEL, 1);
331
+
332
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, SIDSIZE, SMMU_IDR1_SIDSIZE);
333
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, EVENTQS, SMMU_EVENTQS);
334
+ s->idr[1] = FIELD_DP32(s->idr[1], IDR1, CMDQS, SMMU_CMDQS);
335
+
336
+ /* 4K and 64K granule support */
337
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
338
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
339
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
340
+
341
+ s->cmdq.base = deposit64(s->cmdq.base, 0, 5, SMMU_CMDQS);
342
+ s->cmdq.prod = 0;
343
+ s->cmdq.cons = 0;
344
+ s->cmdq.entry_size = sizeof(struct Cmd);
345
+ s->eventq.base = deposit64(s->eventq.base, 0, 5, SMMU_EVENTQS);
346
+ s->eventq.prod = 0;
347
+ s->eventq.cons = 0;
348
+ s->eventq.entry_size = sizeof(struct Evt);
349
+
350
+ s->features = 0;
351
+ s->sid_split = 0;
352
+}
353
+
354
+static MemTxResult smmu_write_mmio(void *opaque, hwaddr offset, uint64_t data,
355
+ unsigned size, MemTxAttrs attrs)
356
+{
357
+ /* not yet implemented */
358
+ return MEMTX_ERROR;
359
+}
360
+
361
+static MemTxResult smmu_readll(SMMUv3State *s, hwaddr offset,
362
+ uint64_t *data, MemTxAttrs attrs)
363
+{
364
+ switch (offset) {
365
+ case A_GERROR_IRQ_CFG0:
366
+ *data = s->gerror_irq_cfg0;
367
+ return MEMTX_OK;
368
+ case A_STRTAB_BASE:
369
+ *data = s->strtab_base;
370
+ return MEMTX_OK;
371
+ case A_CMDQ_BASE:
372
+ *data = s->cmdq.base;
373
+ return MEMTX_OK;
374
+ case A_EVENTQ_BASE:
375
+ *data = s->eventq.base;
376
+ return MEMTX_OK;
377
+ default:
378
+ *data = 0;
379
+ qemu_log_mask(LOG_UNIMP,
380
+ "%s Unexpected 64-bit access to 0x%"PRIx64" (RAZ)\n",
381
+ __func__, offset);
382
+ return MEMTX_OK;
383
+ }
384
+}
385
+
386
+static MemTxResult smmu_readl(SMMUv3State *s, hwaddr offset,
387
+ uint64_t *data, MemTxAttrs attrs)
388
+{
389
+ switch (offset) {
390
+ case A_IDREGS ... A_IDREGS + 0x1f:
391
+ *data = smmuv3_idreg(offset - A_IDREGS);
392
+ return MEMTX_OK;
393
+ case A_IDR0 ... A_IDR5:
394
+ *data = s->idr[(offset - A_IDR0) / 4];
395
+ return MEMTX_OK;
396
+ case A_IIDR:
397
+ *data = s->iidr;
398
+ return MEMTX_OK;
399
+ case A_CR0:
400
+ *data = s->cr[0];
401
+ return MEMTX_OK;
402
+ case A_CR0ACK:
403
+ *data = s->cr0ack;
404
+ return MEMTX_OK;
405
+ case A_CR1:
406
+ *data = s->cr[1];
407
+ return MEMTX_OK;
408
+ case A_CR2:
409
+ *data = s->cr[2];
410
+ return MEMTX_OK;
411
+ case A_STATUSR:
412
+ *data = s->statusr;
413
+ return MEMTX_OK;
414
+ case A_IRQ_CTRL:
415
+ case A_IRQ_CTRL_ACK:
416
+ *data = s->irq_ctrl;
417
+ return MEMTX_OK;
418
+ case A_GERROR:
419
+ *data = s->gerror;
420
+ return MEMTX_OK;
421
+ case A_GERRORN:
422
+ *data = s->gerrorn;
423
+ return MEMTX_OK;
424
+ case A_GERROR_IRQ_CFG0: /* 64b */
425
+ *data = extract64(s->gerror_irq_cfg0, 0, 32);
426
+ return MEMTX_OK;
427
+ case A_GERROR_IRQ_CFG0 + 4:
428
+ *data = extract64(s->gerror_irq_cfg0, 32, 32);
429
+ return MEMTX_OK;
430
+ case A_GERROR_IRQ_CFG1:
431
+ *data = s->gerror_irq_cfg1;
432
+ return MEMTX_OK;
433
+ case A_GERROR_IRQ_CFG2:
434
+ *data = s->gerror_irq_cfg2;
435
+ return MEMTX_OK;
436
+ case A_STRTAB_BASE: /* 64b */
437
+ *data = extract64(s->strtab_base, 0, 32);
438
+ return MEMTX_OK;
439
+ case A_STRTAB_BASE + 4: /* 64b */
440
+ *data = extract64(s->strtab_base, 32, 32);
441
+ return MEMTX_OK;
442
+ case A_STRTAB_BASE_CFG:
443
+ *data = s->strtab_base_cfg;
444
+ return MEMTX_OK;
445
+ case A_CMDQ_BASE: /* 64b */
446
+ *data = extract64(s->cmdq.base, 0, 32);
447
+ return MEMTX_OK;
448
+ case A_CMDQ_BASE + 4:
449
+ *data = extract64(s->cmdq.base, 32, 32);
450
+ return MEMTX_OK;
451
+ case A_CMDQ_PROD:
452
+ *data = s->cmdq.prod;
453
+ return MEMTX_OK;
454
+ case A_CMDQ_CONS:
455
+ *data = s->cmdq.cons;
456
+ return MEMTX_OK;
457
+ case A_EVENTQ_BASE: /* 64b */
458
+ *data = extract64(s->eventq.base, 0, 32);
459
+ return MEMTX_OK;
460
+ case A_EVENTQ_BASE + 4: /* 64b */
461
+ *data = extract64(s->eventq.base, 32, 32);
462
+ return MEMTX_OK;
463
+ case A_EVENTQ_PROD:
464
+ *data = s->eventq.prod;
465
+ return MEMTX_OK;
466
+ case A_EVENTQ_CONS:
467
+ *data = s->eventq.cons;
468
+ return MEMTX_OK;
469
+ default:
470
+ *data = 0;
471
+ qemu_log_mask(LOG_UNIMP,
472
+ "%s unhandled 32-bit access at 0x%"PRIx64" (RAZ)\n",
473
+ __func__, offset);
474
+ return MEMTX_OK;
475
+ }
476
+}
477
+
478
+static MemTxResult smmu_read_mmio(void *opaque, hwaddr offset, uint64_t *data,
479
+ unsigned size, MemTxAttrs attrs)
480
+{
481
+ SMMUState *sys = opaque;
482
+ SMMUv3State *s = ARM_SMMUV3(sys);
483
+ MemTxResult r;
484
+
485
+ /* CONSTRAINED UNPREDICTABLE choice to have page0/1 be exact aliases */
486
+ offset &= ~0x10000;
487
+
488
+ switch (size) {
489
+ case 8:
490
+ r = smmu_readll(s, offset, data, attrs);
491
+ break;
492
+ case 4:
493
+ r = smmu_readl(s, offset, data, attrs);
494
+ break;
495
+ default:
496
+ r = MEMTX_ERROR;
497
+ break;
498
+ }
499
+
500
+ trace_smmuv3_read_mmio(offset, *data, size, r);
501
+ return r;
502
+}
503
+
504
+static const MemoryRegionOps smmu_mem_ops = {
505
+ .read_with_attrs = smmu_read_mmio,
506
+ .write_with_attrs = smmu_write_mmio,
507
+ .endianness = DEVICE_LITTLE_ENDIAN,
508
+ .valid = {
509
+ .min_access_size = 4,
510
+ .max_access_size = 8,
511
+ },
512
+ .impl = {
513
+ .min_access_size = 4,
514
+ .max_access_size = 8,
515
+ },
516
+};
517
+
518
+static void smmu_init_irq(SMMUv3State *s, SysBusDevice *dev)
519
+{
520
+ int i;
521
+
522
+ for (i = 0; i < ARRAY_SIZE(s->irq); i++) {
523
+ sysbus_init_irq(dev, &s->irq[i]);
524
+ }
525
+}
526
+
527
+static void smmu_reset(DeviceState *dev)
528
+{
529
+ SMMUv3State *s = ARM_SMMUV3(dev);
530
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
531
+
532
+ c->parent_reset(dev);
533
+
534
+ smmuv3_init_regs(s);
535
+}
536
+
537
+static void smmu_realize(DeviceState *d, Error **errp)
538
+{
539
+ SMMUState *sys = ARM_SMMU(d);
540
+ SMMUv3State *s = ARM_SMMUV3(sys);
541
+ SMMUv3Class *c = ARM_SMMUV3_GET_CLASS(s);
542
+ SysBusDevice *dev = SYS_BUS_DEVICE(d);
543
+ Error *local_err = NULL;
544
+
545
+ c->parent_realize(d, &local_err);
546
+ if (local_err) {
547
+ error_propagate(errp, local_err);
548
+ return;
549
+ }
550
+
551
+ memory_region_init_io(&sys->iomem, OBJECT(s),
552
+ &smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
553
+
554
+ sys->mrtypename = TYPE_SMMUV3_IOMMU_MEMORY_REGION;
555
+
556
+ sysbus_init_mmio(dev, &sys->iomem);
557
+
558
+ smmu_init_irq(s, dev);
559
+}
560
+
561
+static const VMStateDescription vmstate_smmuv3_queue = {
562
+ .name = "smmuv3_queue",
563
+ .version_id = 1,
564
+ .minimum_version_id = 1,
565
+ .fields = (VMStateField[]) {
566
+ VMSTATE_UINT64(base, SMMUQueue),
567
+ VMSTATE_UINT32(prod, SMMUQueue),
568
+ VMSTATE_UINT32(cons, SMMUQueue),
569
+ VMSTATE_UINT8(log2size, SMMUQueue),
570
+ },
571
+};
572
+
573
+static const VMStateDescription vmstate_smmuv3 = {
574
+ .name = "smmuv3",
575
+ .version_id = 1,
576
+ .minimum_version_id = 1,
577
+ .fields = (VMStateField[]) {
578
+ VMSTATE_UINT32(features, SMMUv3State),
579
+ VMSTATE_UINT8(sid_size, SMMUv3State),
580
+ VMSTATE_UINT8(sid_split, SMMUv3State),
581
+
582
+ VMSTATE_UINT32_ARRAY(cr, SMMUv3State, 3),
583
+ VMSTATE_UINT32(cr0ack, SMMUv3State),
584
+ VMSTATE_UINT32(statusr, SMMUv3State),
585
+ VMSTATE_UINT32(irq_ctrl, SMMUv3State),
586
+ VMSTATE_UINT32(gerror, SMMUv3State),
587
+ VMSTATE_UINT32(gerrorn, SMMUv3State),
588
+ VMSTATE_UINT64(gerror_irq_cfg0, SMMUv3State),
589
+ VMSTATE_UINT32(gerror_irq_cfg1, SMMUv3State),
590
+ VMSTATE_UINT32(gerror_irq_cfg2, SMMUv3State),
591
+ VMSTATE_UINT64(strtab_base, SMMUv3State),
592
+ VMSTATE_UINT32(strtab_base_cfg, SMMUv3State),
593
+ VMSTATE_UINT64(eventq_irq_cfg0, SMMUv3State),
594
+ VMSTATE_UINT32(eventq_irq_cfg1, SMMUv3State),
595
+ VMSTATE_UINT32(eventq_irq_cfg2, SMMUv3State),
596
+
597
+ VMSTATE_STRUCT(cmdq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
598
+ VMSTATE_STRUCT(eventq, SMMUv3State, 0, vmstate_smmuv3_queue, SMMUQueue),
599
+
600
+ VMSTATE_END_OF_LIST(),
601
+ },
602
+};
603
+
604
+static void smmuv3_instance_init(Object *obj)
605
+{
606
+ /* Nothing much to do here as of now */
607
+}
608
+
609
+static void smmuv3_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+ SMMUv3Class *c = ARM_SMMUV3_CLASS(klass);
613
+
614
+ dc->vmsd = &vmstate_smmuv3;
615
+ device_class_set_parent_reset(dc, smmu_reset, &c->parent_reset);
616
+ c->parent_realize = dc->realize;
617
+ dc->realize = smmu_realize;
618
+}
619
+
620
+static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass,
621
+ void *data)
622
+{
623
+}
624
+
625
+static const TypeInfo smmuv3_type_info = {
626
+ .name = TYPE_ARM_SMMUV3,
627
+ .parent = TYPE_ARM_SMMU,
628
+ .instance_size = sizeof(SMMUv3State),
629
+ .instance_init = smmuv3_instance_init,
630
+ .class_size = sizeof(SMMUv3Class),
631
+ .class_init = smmuv3_class_init,
632
+};
633
+
634
+static const TypeInfo smmuv3_iommu_memory_region_info = {
635
+ .parent = TYPE_IOMMU_MEMORY_REGION,
636
+ .name = TYPE_SMMUV3_IOMMU_MEMORY_REGION,
637
+ .class_init = smmuv3_iommu_memory_region_class_init,
638
+};
639
+
640
+static void smmuv3_register_types(void)
641
+{
642
+ type_register(&smmuv3_type_info);
643
+ type_register(&smmuv3_iommu_memory_region_info);
644
+}
645
+
646
+type_init(smmuv3_register_types)
647
+
648
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
649
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
650
--- a/hw/arm/trace-events
75
--- a/hw/input/stellaris_input.c
651
+++ b/hw/arm/trace-events
76
+++ b/hw/input/stellaris_input.c
652
@@ -XXX,XX +XXX,XX @@ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr,
77
@@ -XXX,XX +XXX,XX @@
653
smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
78
*/
654
smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
79
#include "qemu/osdep.h"
655
smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
80
#include "hw/hw.h"
656
+
81
-#include "hw/devices.h"
657
+#hw/arm/smmuv3.c
82
+#include "hw/input/gamepad.h"
658
+smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
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>
659
--
98
--
660
2.17.0
99
2.20.1
661
100
662
101
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Since uWireSlave is only used in this new header, there is no
4
need to expose it via "qemu/typedefs.h".
5
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/omap.h | 6 +-----
12
include/hw/devices.h | 15 ---------------
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
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
26
+++ b/include/hw/arm/omap.h
27
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
29
# define hw_omap_h        "omap.h"
30
#include "hw/irq.h"
31
+#include "hw/input/tsc2xxx.h"
32
#include "target/arm/cpu-qom.h"
33
#include "qemu/log.h"
34
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
50
+++ b/include/hw/devices.h
51
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/include/hw/input/tsc2xxx.h
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+#ifndef HW_INPUT_TSC2XXX_H
95
+#define HW_INPUT_TSC2XXX_H
96
+
97
+#include "hw/irq.h"
98
+#include "ui/console.h"
99
+
100
+typedef struct uWireSlave {
101
+ uint16_t (*receive)(void *opaque);
102
+ void (*send)(void *opaque, uint16_t data);
103
+ void *opaque;
104
+} uWireSlave;
105
+
106
+/* tsc210x.c */
107
+uWireSlave *tsc2102_init(qemu_irq pint);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
113
+
114
+/* tsc2005.c */
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
--
208
2.20.1
209
210
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This patch implements the page table walk for VMSAv8-64.
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Prem Mallappa <prem.mallappa@broadcom.com>
7
Message-id: 1524665762-31355-4-git-send-email-eric.auger@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
hw/arm/smmu-internal.h | 99 ++++++++++++++++
8
include/hw/devices.h | 3 ---
12
include/hw/arm/smmu-common.h | 14 +++
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
13
hw/arm/smmu-common.c | 222 +++++++++++++++++++++++++++++++++++
10
hw/arm/kzm.c | 2 +-
14
hw/arm/trace-events | 9 +-
11
hw/arm/mps2.c | 2 +-
15
4 files changed, 343 insertions(+), 1 deletion(-)
12
hw/arm/realview.c | 1 +
16
create mode 100644 hw/arm/smmu-internal.h
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
17
18
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
21
+++ b/include/hw/devices.h
22
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
25
26
-/* lan9118.c */
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
28
-
29
#endif
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
19
new file mode 100644
31
new file mode 100644
20
index XXXXXXX..XXXXXXX
32
index XXXXXXX..XXXXXXX
21
--- /dev/null
33
--- /dev/null
22
+++ b/hw/arm/smmu-internal.h
34
+++ b/include/hw/net/lan9118.h
23
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@
24
+/*
36
+/*
25
+ * ARM SMMU support - Internal API
37
+ * SMSC LAN9118 Ethernet interface emulation
26
+ *
38
+ *
27
+ * Copyright (c) 2017 Red Hat, Inc.
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
28
+ * Copyright (C) 2014-2016 Broadcom Corporation
40
+ * Written by Paul Brook
29
+ * Written by Prem Mallappa, Eric Auger
30
+ *
41
+ *
31
+ * This program is free software; you can redistribute it and/or modify
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
32
+ * it under the terms of the GNU General Public License version 2 as
43
+ * See the COPYING file in the top-level directory.
33
+ * published by the Free Software Foundation.
34
+ *
35
+ * This program is distributed in the hope that it will be useful,
36
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38
+ * General Public License for more details.
39
+ *
40
+ * You should have received a copy of the GNU General Public License along
41
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
42
+ */
44
+ */
43
+
45
+
44
+#ifndef HW_ARM_SMMU_INTERNAL_H
46
+#ifndef HW_NET_LAN9118_H
45
+#define HW_ARM_SMMU_INTERNAL_H
47
+#define HW_NET_LAN9118_H
46
+
48
+
47
+#define TBI0(tbi) ((tbi) & 0x1)
49
+#include "hw/irq.h"
48
+#define TBI1(tbi) ((tbi) & 0x2 >> 1)
50
+#include "net/net.h"
49
+
51
+
50
+/* PTE Manipulation */
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
51
+
52
+#define ARM_LPAE_PTE_TYPE_SHIFT 0
53
+#define ARM_LPAE_PTE_TYPE_MASK 0x3
54
+
55
+#define ARM_LPAE_PTE_TYPE_BLOCK 1
56
+#define ARM_LPAE_PTE_TYPE_TABLE 3
57
+
58
+#define ARM_LPAE_L3_PTE_TYPE_RESERVED 1
59
+#define ARM_LPAE_L3_PTE_TYPE_PAGE 3
60
+
61
+#define ARM_LPAE_PTE_VALID (1 << 0)
62
+
63
+#define PTE_ADDRESS(pte, shift) \
64
+ (extract64(pte, shift, 47 - shift + 1) << shift)
65
+
66
+#define is_invalid_pte(pte) (!(pte & ARM_LPAE_PTE_VALID))
67
+
68
+#define is_reserved_pte(pte, level) \
69
+ ((level == 3) && \
70
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_RESERVED))
71
+
72
+#define is_block_pte(pte, level) \
73
+ ((level < 3) && \
74
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_BLOCK))
75
+
76
+#define is_table_pte(pte, level) \
77
+ ((level < 3) && \
78
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_TABLE))
79
+
80
+#define is_page_pte(pte, level) \
81
+ ((level == 3) && \
82
+ ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_PAGE))
83
+
84
+/* access permissions */
85
+
86
+#define PTE_AP(pte) \
87
+ (extract64(pte, 6, 2))
88
+
89
+#define PTE_APTABLE(pte) \
90
+ (extract64(pte, 61, 2))
91
+
92
+/*
93
+ * TODO: At the moment all transactions are considered as privileged (EL1)
94
+ * as IOMMU translation callback does not pass user/priv attributes.
95
+ */
96
+#define is_permission_fault(ap, perm) \
97
+ (((perm) & IOMMU_WO) && ((ap) & 0x2))
98
+
99
+#define PTE_AP_TO_PERM(ap) \
100
+ (IOMMU_ACCESS_FLAG(true, !((ap) & 0x2)))
101
+
102
+/* Level Indexing */
103
+
104
+static inline int level_shift(int level, int granule_sz)
105
+{
106
+ return granule_sz + (3 - level) * (granule_sz - 3);
107
+}
108
+
109
+static inline uint64_t level_page_mask(int level, int granule_sz)
110
+{
111
+ return ~(MAKE_64BIT_MASK(0, level_shift(level, granule_sz)));
112
+}
113
+
114
+static inline
115
+uint64_t iova_level_offset(uint64_t iova, int inputsize,
116
+ int level, int gsz)
117
+{
118
+ return ((iova & MAKE_64BIT_MASK(0, inputsize)) >> level_shift(level, gsz)) &
119
+ MAKE_64BIT_MASK(0, gsz - 3);
120
+}
121
+
53
+
122
+#endif
54
+#endif
123
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
124
index XXXXXXX..XXXXXXX 100644
56
index XXXXXXX..XXXXXXX 100644
125
--- a/include/hw/arm/smmu-common.h
57
--- a/hw/arm/kzm.c
126
+++ b/include/hw/arm/smmu-common.h
58
+++ b/hw/arm/kzm.c
127
@@ -XXX,XX +XXX,XX @@ static inline uint16_t smmu_get_sid(SMMUDevice *sdev)
59
@@ -XXX,XX +XXX,XX @@
128
{
60
#include "qemu/error-report.h"
129
return PCI_BUILD_BDF(pci_bus_num(sdev->bus), sdev->devfn);
61
#include "exec/address-spaces.h"
130
}
62
#include "net/net.h"
131
+
63
-#include "hw/devices.h"
132
+/**
64
+#include "hw/net/lan9118.h"
133
+ * smmu_ptw - Perform the page table walk for a given iova / access flags
65
#include "hw/char/serial.h"
134
+ * pair, according to @cfg translation config
66
#include "sysemu/qtest.h"
135
+ */
67
136
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
137
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info);
138
+
139
+/**
140
+ * select_tt - compute which translation table shall be used according to
141
+ * the input iova and translation config and return the TT specific info
142
+ */
143
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
144
+
145
#endif /* HW_ARM_SMMU_COMMON */
146
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
147
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/smmu-common.c
70
--- a/hw/arm/mps2.c
149
+++ b/hw/arm/smmu-common.c
71
+++ b/hw/arm/mps2.c
150
@@ -XXX,XX +XXX,XX @@
72
@@ -XXX,XX +XXX,XX @@
151
73
#include "hw/timer/cmsdk-apb-timer.h"
152
#include "qemu/error-report.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
153
#include "hw/arm/smmu-common.h"
75
#include "hw/misc/mps2-scc.h"
154
+#include "smmu-internal.h"
76
-#include "hw/devices.h"
155
+
77
+#include "hw/net/lan9118.h"
156
+/* VMSAv8-64 Translation */
78
#include "net/net.h"
157
+
79
158
+/**
80
typedef enum MPS2FPGAType {
159
+ * get_pte - Get the content of a page table entry located at
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
160
+ * @base_addr[@index]
161
+ */
162
+static int get_pte(dma_addr_t baseaddr, uint32_t index, uint64_t *pte,
163
+ SMMUPTWEventInfo *info)
164
+{
165
+ int ret;
166
+ dma_addr_t addr = baseaddr + index * sizeof(*pte);
167
+
168
+ /* TODO: guarantee 64-bit single-copy atomicity */
169
+ ret = dma_memory_read(&address_space_memory, addr,
170
+ (uint8_t *)pte, sizeof(*pte));
171
+
172
+ if (ret != MEMTX_OK) {
173
+ info->type = SMMU_PTW_ERR_WALK_EABT;
174
+ info->addr = addr;
175
+ return -EINVAL;
176
+ }
177
+ trace_smmu_get_pte(baseaddr, index, addr, *pte);
178
+ return 0;
179
+}
180
+
181
+/* VMSAv8-64 Translation Table Format Descriptor Decoding */
182
+
183
+/**
184
+ * get_page_pte_address - returns the L3 descriptor output address,
185
+ * ie. the page frame
186
+ * ARM ARM spec: Figure D4-17 VMSAv8-64 level 3 descriptor format
187
+ */
188
+static inline hwaddr get_page_pte_address(uint64_t pte, int granule_sz)
189
+{
190
+ return PTE_ADDRESS(pte, granule_sz);
191
+}
192
+
193
+/**
194
+ * get_table_pte_address - return table descriptor output address,
195
+ * ie. address of next level table
196
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
197
+ */
198
+static inline hwaddr get_table_pte_address(uint64_t pte, int granule_sz)
199
+{
200
+ return PTE_ADDRESS(pte, granule_sz);
201
+}
202
+
203
+/**
204
+ * get_block_pte_address - return block descriptor output address and block size
205
+ * ARM ARM Figure D4-16 VMSAv8-64 level0, level1, and level 2 descriptor formats
206
+ */
207
+static inline hwaddr get_block_pte_address(uint64_t pte, int level,
208
+ int granule_sz, uint64_t *bsz)
209
+{
210
+ int n = (granule_sz - 3) * (4 - level) + 3;
211
+
212
+ *bsz = 1 << n;
213
+ return PTE_ADDRESS(pte, n);
214
+}
215
+
216
+SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova)
217
+{
218
+ bool tbi = extract64(iova, 55, 1) ? TBI1(cfg->tbi) : TBI0(cfg->tbi);
219
+ uint8_t tbi_byte = tbi * 8;
220
+
221
+ if (cfg->tt[0].tsz &&
222
+ !extract64(iova, 64 - cfg->tt[0].tsz, cfg->tt[0].tsz - tbi_byte)) {
223
+ /* there is a ttbr0 region and we are in it (high bits all zero) */
224
+ return &cfg->tt[0];
225
+ } else if (cfg->tt[1].tsz &&
226
+ !extract64(iova, 64 - cfg->tt[1].tsz, cfg->tt[1].tsz - tbi_byte)) {
227
+ /* there is a ttbr1 region and we are in it (high bits all one) */
228
+ return &cfg->tt[1];
229
+ } else if (!cfg->tt[0].tsz) {
230
+ /* ttbr0 region is "everything not in the ttbr1 region" */
231
+ return &cfg->tt[0];
232
+ } else if (!cfg->tt[1].tsz) {
233
+ /* ttbr1 region is "everything not in the ttbr0 region" */
234
+ return &cfg->tt[1];
235
+ }
236
+ /* in the gap between the two regions, this is a Translation fault */
237
+ return NULL;
238
+}
239
+
240
+/**
241
+ * smmu_ptw_64 - VMSAv8-64 Walk of the page tables for a given IOVA
242
+ * @cfg: translation config
243
+ * @iova: iova to translate
244
+ * @perm: access type
245
+ * @tlbe: IOMMUTLBEntry (out)
246
+ * @info: handle to an error info
247
+ *
248
+ * Return 0 on success, < 0 on error. In case of error, @info is filled
249
+ * and tlbe->perm is set to IOMMU_NONE.
250
+ * Upon success, @tlbe is filled with translated_addr and entry
251
+ * permission rights.
252
+ */
253
+static int smmu_ptw_64(SMMUTransCfg *cfg,
254
+ dma_addr_t iova, IOMMUAccessFlags perm,
255
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
256
+{
257
+ dma_addr_t baseaddr, indexmask;
258
+ int stage = cfg->stage;
259
+ SMMUTransTableInfo *tt = select_tt(cfg, iova);
260
+ uint8_t level, granule_sz, inputsize, stride;
261
+
262
+ if (!tt || tt->disabled) {
263
+ info->type = SMMU_PTW_ERR_TRANSLATION;
264
+ goto error;
265
+ }
266
+
267
+ granule_sz = tt->granule_sz;
268
+ stride = granule_sz - 3;
269
+ inputsize = 64 - tt->tsz;
270
+ level = 4 - (inputsize - 4) / stride;
271
+ indexmask = (1ULL << (inputsize - (stride * (4 - level)))) - 1;
272
+ baseaddr = extract64(tt->ttb, 0, 48);
273
+ baseaddr &= ~indexmask;
274
+
275
+ tlbe->iova = iova;
276
+ tlbe->addr_mask = (1 << granule_sz) - 1;
277
+
278
+ while (level <= 3) {
279
+ uint64_t subpage_size = 1ULL << level_shift(level, granule_sz);
280
+ uint64_t mask = subpage_size - 1;
281
+ uint32_t offset = iova_level_offset(iova, inputsize, level, granule_sz);
282
+ uint64_t pte;
283
+ dma_addr_t pte_addr = baseaddr + offset * sizeof(pte);
284
+ uint8_t ap;
285
+
286
+ if (get_pte(baseaddr, offset, &pte, info)) {
287
+ goto error;
288
+ }
289
+ trace_smmu_ptw_level(level, iova, subpage_size,
290
+ baseaddr, offset, pte);
291
+
292
+ if (is_invalid_pte(pte) || is_reserved_pte(pte, level)) {
293
+ trace_smmu_ptw_invalid_pte(stage, level, baseaddr,
294
+ pte_addr, offset, pte);
295
+ info->type = SMMU_PTW_ERR_TRANSLATION;
296
+ goto error;
297
+ }
298
+
299
+ if (is_page_pte(pte, level)) {
300
+ uint64_t gpa = get_page_pte_address(pte, granule_sz);
301
+
302
+ ap = PTE_AP(pte);
303
+ if (is_permission_fault(ap, perm)) {
304
+ info->type = SMMU_PTW_ERR_PERMISSION;
305
+ goto error;
306
+ }
307
+
308
+ tlbe->translated_addr = gpa + (iova & mask);
309
+ tlbe->perm = PTE_AP_TO_PERM(ap);
310
+ trace_smmu_ptw_page_pte(stage, level, iova,
311
+ baseaddr, pte_addr, pte, gpa);
312
+ return 0;
313
+ }
314
+ if (is_block_pte(pte, level)) {
315
+ uint64_t block_size;
316
+ hwaddr gpa = get_block_pte_address(pte, level, granule_sz,
317
+ &block_size);
318
+
319
+ ap = PTE_AP(pte);
320
+ if (is_permission_fault(ap, perm)) {
321
+ info->type = SMMU_PTW_ERR_PERMISSION;
322
+ goto error;
323
+ }
324
+
325
+ trace_smmu_ptw_block_pte(stage, level, baseaddr,
326
+ pte_addr, pte, iova, gpa,
327
+ block_size >> 20);
328
+
329
+ tlbe->translated_addr = gpa + (iova & mask);
330
+ tlbe->perm = PTE_AP_TO_PERM(ap);
331
+ return 0;
332
+ }
333
+
334
+ /* table pte */
335
+ ap = PTE_APTABLE(pte);
336
+
337
+ if (is_permission_fault(ap, perm)) {
338
+ info->type = SMMU_PTW_ERR_PERMISSION;
339
+ goto error;
340
+ }
341
+ baseaddr = get_table_pte_address(pte, granule_sz);
342
+ level++;
343
+ }
344
+
345
+ info->type = SMMU_PTW_ERR_TRANSLATION;
346
+
347
+error:
348
+ tlbe->perm = IOMMU_NONE;
349
+ return -EINVAL;
350
+}
351
+
352
+/**
353
+ * smmu_ptw - Walk the page tables for an IOVA, according to @cfg
354
+ *
355
+ * @cfg: translation configuration
356
+ * @iova: iova to translate
357
+ * @perm: tentative access type
358
+ * @tlbe: returned entry
359
+ * @info: ptw event handle
360
+ *
361
+ * return 0 on success
362
+ */
363
+inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
364
+ IOMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
365
+{
366
+ if (!cfg->aa64) {
367
+ /*
368
+ * This code path is not entered as we check this while decoding
369
+ * the configuration data in the derived SMMU model.
370
+ */
371
+ g_assert_not_reached();
372
+ }
373
+
374
+ return smmu_ptw_64(cfg, iova, perm, tlbe, info);
375
+}
376
377
/**
378
* The bus number is used for lookup when SID based invalidation occurs.
379
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
380
index XXXXXXX..XXXXXXX 100644
82
index XXXXXXX..XXXXXXX 100644
381
--- a/hw/arm/trace-events
83
--- a/hw/arm/realview.c
382
+++ b/hw/arm/trace-events
84
+++ b/hw/arm/realview.c
383
@@ -XXX,XX +XXX,XX @@
85
@@ -XXX,XX +XXX,XX @@
384
virt_acpi_setup(void) "No fw cfg or ACPI disabled. Bailing out."
86
#include "hw/arm/arm.h"
385
87
#include "hw/arm/primecell.h"
386
# hw/arm/smmu-common.c
88
#include "hw/devices.h"
387
-smmu_add_mr(const char *name) "%s"
89
+#include "hw/net/lan9118.h"
388
\ No newline at end of file
90
#include "hw/pci/pci.h"
389
+smmu_add_mr(const char *name) "%s"
91
#include "net/net.h"
390
+smmu_page_walk(int stage, uint64_t baseaddr, int first_level, uint64_t start, uint64_t end) "stage=%d, baseaddr=0x%"PRIx64", first level=%d, start=0x%"PRIx64", end=0x%"PRIx64
92
#include "sysemu/sysemu.h"
391
+smmu_lookup_table(int level, uint64_t baseaddr, int granule_sz, uint64_t start, uint64_t end, int flags, uint64_t subpage_size) "level=%d baseaddr=0x%"PRIx64" granule=%d, start=0x%"PRIx64" end=0x%"PRIx64" flags=%d subpage_size=0x%"PRIx64
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
392
+smmu_ptw_level(int level, uint64_t iova, size_t subpage_size, uint64_t baseaddr, uint32_t offset, uint64_t pte) "level=%d iova=0x%"PRIx64" subpage_sz=0x%lx baseaddr=0x%"PRIx64" offset=%d => pte=0x%"PRIx64
94
index XXXXXXX..XXXXXXX 100644
393
+smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint32_t offset, uint64_t pte) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" offset=%d pte=0x%"PRIx64
95
--- a/hw/arm/vexpress.c
394
+smmu_ptw_page_pte(int stage, int level, uint64_t iova, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t address) "stage=%d level=%d iova=0x%"PRIx64" base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" page address = 0x%"PRIx64
96
+++ b/hw/arm/vexpress.c
395
+smmu_ptw_block_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr, uint64_t pte, uint64_t iova, uint64_t gpa, int bsize_mb) "stage=%d level=%d base@=0x%"PRIx64" pte@=0x%"PRIx64" pte=0x%"PRIx64" iova=0x%"PRIx64" block address = 0x%"PRIx64" block size = %d MiB"
97
@@ -XXX,XX +XXX,XX @@
396
+smmu_get_pte(uint64_t baseaddr, int index, uint64_t pteaddr, uint64_t pte) "baseaddr=0x%"PRIx64" index=0x%x, pteaddr=0x%"PRIx64", pte=0x%"PRIx64
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"
397
--
119
--
398
2.17.0
120
2.20.1
399
121
400
122
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This allows to pin the host controller in the Linux PCI domain space.
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Linux requires that property to be available consistently or not at all,
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
in which case the domain number becomes unstable on additions/removals.
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Adding it here won't make a difference in practice for most setups as we
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
7
only expose one controller.
8
9
However, enabling Jailhouse on top may introduce another controller, and
10
that one would like to have stable address as well. So the property is
11
needed for the first controller as well.
12
13
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
14
Message-id: 3301c5bc-7b47-1b0e-8ce4-30435057a276@web.de
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
8
---
18
hw/arm/virt.c | 1 +
9
include/hw/net/ne2000-isa.h | 6 ++++++
19
1 file changed, 1 insertion(+)
10
1 file changed, 6 insertions(+)
20
11
21
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/virt.c
14
--- a/include/hw/net/ne2000-isa.h
24
+++ b/hw/arm/virt.c
15
+++ b/include/hw/net/ne2000-isa.h
25
@@ -XXX,XX +XXX,XX @@ static void create_pcie(const VirtMachineState *vms, qemu_irq *pic)
16
@@ -XXX,XX +XXX,XX @@
26
qemu_fdt_setprop_string(vms->fdt, nodename, "device_type", "pci");
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
27
qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 3);
18
* See the COPYING file in the top-level directory.
28
qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 2);
19
*/
29
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "linux,pci-domain", 0);
20
+
30
qemu_fdt_setprop_cells(vms->fdt, nodename, "bus-range", 0,
21
+#ifndef HW_NET_NE2K_ISA_H
31
nr_pcie_buses - 1);
22
+#define HW_NET_NE2K_ISA_H
32
qemu_fdt_setprop(vms->fdt, nodename, "dma-coherent", NULL, 0);
23
+
24
#include "hw/hw.h"
25
#include "hw/qdev.h"
26
#include "hw/isa/isa.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
29
return d;
30
}
31
+
32
+#endif
33
--
33
--
34
2.17.0
34
2.20.1
35
35
36
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The (size > 3 && !is_q) condition is identical to the preceeding test
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
of bit 3 in immh; eliminate it. For the benefit of Coverity, assert
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
that size is within the bounds we expect.
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
6
7
Fixes: Coverity CID1385846
8
Fixes: Coverity CID1385849
9
Fixes: Coverity CID1385852
10
Fixes: Coverity CID1385857
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20180501180455.11214-2-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
7
---
16
target/arm/translate-a64.c | 6 +-----
8
include/hw/net/lan9118.h | 2 ++
17
1 file changed, 1 insertion(+), 5 deletions(-)
9
hw/arm/exynos4_boards.c | 3 ++-
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
18
13
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
16
--- a/include/hw/net/lan9118.h
22
+++ b/target/arm/translate-a64.c
17
+++ b/include/hw/net/lan9118.h
23
@@ -XXX,XX +XXX,XX @@ static void handle_vec_simd_shri(DisasContext *s, bool is_q, bool is_u,
18
@@ -XXX,XX +XXX,XX @@
24
unallocated_encoding(s);
19
#include "hw/irq.h"
25
return;
20
#include "net/net.h"
21
22
+#define TYPE_LAN9118 "lan9118"
23
+
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
25
26
#endif
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/arm/arm.h"
33
#include "exec/address-spaces.h"
34
#include "hw/arm/exynos4210.h"
35
+#include "hw/net/lan9118.h"
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 = {
26
}
74
}
27
-
75
};
28
- if (size > 3 && !is_q) {
76
29
- unallocated_encoding(s);
77
-#define TYPE_LAN9118 "lan9118"
30
- return;
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
31
- }
79
32
+ tcg_debug_assert(size <= 3);
80
typedef struct {
33
34
if (!fp_access_check(s)) {
35
return;
36
--
81
--
37
2.17.0
82
2.20.1
38
83
39
84
diff view generated by jsdifflib
1
From: Thomas Huth <thuth@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
When running omap1/2 or pxa2xx based ARM machines with -nodefaults,
3
This commit finally deletes "hw/devices.h".
4
they bail out immediately complaining about a "missing SecureDigital
5
device". That's not how the "default" devices in vl.c are meant to
6
work - it should be possible for a board to also start up without
7
default devices. So let's turn the error message and exit() into
8
a warning instead.
9
4
10
Signed-off-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
11
Message-id: 1525326811-3233-1-git-send-email-thuth@redhat.com
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
hw/arm/omap1.c | 8 ++++----
10
include/hw/devices.h | 11 -----------
17
hw/arm/omap2.c | 8 ++++----
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
18
hw/arm/pxa2xx.c | 15 +++++++--------
12
hw/arm/gumstix.c | 2 +-
19
3 files changed, 15 insertions(+), 16 deletions(-)
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
20
21
21
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
22
diff --git a/include/hw/devices.h b/include/hw/devices.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
22
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/omap1.c
66
--- a/hw/arm/gumstix.c
24
+++ b/hw/arm/omap1.c
67
+++ b/hw/arm/gumstix.c
25
@@ -XXX,XX +XXX,XX @@
68
@@ -XXX,XX +XXX,XX @@
26
#include "hw/arm/soc_dma.h"
69
#include "hw/arm/pxa.h"
27
#include "sysemu/block-backend.h"
70
#include "net/net.h"
28
#include "sysemu/blockdev.h"
71
#include "hw/block/flash.h"
29
+#include "sysemu/qtest.h"
72
-#include "hw/devices.h"
30
#include "qemu/range.h"
73
+#include "hw/net/smc91c111.h"
74
#include "hw/boards.h"
75
#include "exec/address-spaces.h"
76
#include "sysemu/qtest.h"
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu-common.h"
83
#include "cpu.h"
31
#include "hw/sysbus.h"
84
#include "hw/sysbus.h"
32
#include "qemu/cutils.h"
85
-#include "hw/devices.h"
33
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *system_memory,
86
#include "hw/boards.h"
34
omap_findclk(s, "dpll3"));
87
#include "hw/arm/arm.h"
35
88
#include "hw/misc/arm_integrator_debug.h"
36
dinfo = drive_get(IF_SD, 0, 0);
89
+#include "hw/net/smc91c111.h"
37
- if (!dinfo) {
90
#include "net/net.h"
38
- error_report("missing SecureDigital device");
91
#include "exec/address-spaces.h"
39
- exit(1);
92
#include "sysemu/sysemu.h"
40
+ if (!dinfo && !qtest_enabled()) {
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
41
+ warn_report("missing SecureDigital device");
42
}
43
s->mmc = omap_mmc_init(0xfffb7800, system_memory,
44
- blk_by_legacy_dinfo(dinfo),
45
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
46
qdev_get_gpio_in(s->ih[1], OMAP_INT_OQN),
47
&s->drq[OMAP_DMA_MMC_TX],
48
omap_findclk(s, "mmc_ck"));
49
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
50
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/omap2.c
95
--- a/hw/arm/mainstone.c
52
+++ b/hw/arm/omap2.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
53
@@ -XXX,XX +XXX,XX @@
124
@@ -XXX,XX +XXX,XX @@
54
#include "cpu.h"
125
#include "cpu.h"
55
#include "sysemu/block-backend.h"
126
#include "hw/sysbus.h"
56
#include "sysemu/blockdev.h"
57
+#include "sysemu/qtest.h"
58
#include "hw/boards.h"
59
#include "hw/hw.h"
60
#include "hw/arm/arm.h"
127
#include "hw/arm/arm.h"
61
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
128
-#include "hw/devices.h"
62
s->drq[OMAP24XX_DMA_GPMC]);
129
+#include "hw/net/smc91c111.h"
63
130
#include "net/net.h"
64
dinfo = drive_get(IF_SD, 0, 0);
131
#include "sysemu/sysemu.h"
65
- if (!dinfo) {
132
#include "hw/pci/pci.h"
66
- error_report("missing SecureDigital device");
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
67
- exit(1);
68
+ if (!dinfo && !qtest_enabled()) {
69
+ warn_report("missing SecureDigital device");
70
}
71
s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9),
72
- blk_by_legacy_dinfo(dinfo),
73
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
74
qdev_get_gpio_in(s->ih[0], OMAP_INT_24XX_MMC_IRQ),
75
&s->drq[OMAP24XX_DMA_MMC1_TX],
76
omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
77
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
78
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/pxa2xx.c
135
--- a/hw/net/smc91c111.c
80
+++ b/hw/arm/pxa2xx.c
136
+++ b/hw/net/smc91c111.c
81
@@ -XXX,XX +XXX,XX @@
137
@@ -XXX,XX +XXX,XX @@
82
#include "chardev/char-fe.h"
138
#include "qemu/osdep.h"
83
#include "sysemu/block-backend.h"
139
#include "hw/sysbus.h"
84
#include "sysemu/blockdev.h"
140
#include "net/net.h"
85
+#include "sysemu/qtest.h"
141
-#include "hw/devices.h"
86
#include "qemu/cutils.h"
142
+#include "hw/net/smc91c111.h"
87
143
#include "qemu/log.h"
88
static struct {
144
/* For crc32 */
89
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(MemoryRegion *address_space,
145
#include <zlib.h>
90
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 121);
91
92
dinfo = drive_get(IF_SD, 0, 0);
93
- if (!dinfo) {
94
- error_report("missing SecureDigital device");
95
- exit(1);
96
+ if (!dinfo && !qtest_enabled()) {
97
+ warn_report("missing SecureDigital device");
98
}
99
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
100
- blk_by_legacy_dinfo(dinfo),
101
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
102
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
103
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
104
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
105
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size)
106
s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85);
107
108
dinfo = drive_get(IF_SD, 0, 0);
109
- if (!dinfo) {
110
- error_report("missing SecureDigital device");
111
- exit(1);
112
+ if (!dinfo && !qtest_enabled()) {
113
+ warn_report("missing SecureDigital device");
114
}
115
s->mmc = pxa2xx_mmci_init(address_space, 0x41100000,
116
- blk_by_legacy_dinfo(dinfo),
117
+ dinfo ? blk_by_legacy_dinfo(dinfo) : NULL,
118
qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC),
119
qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI),
120
qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI));
121
--
146
--
122
2.17.0
147
2.20.1
123
148
124
149
diff view generated by jsdifflib