1
target-arm queue: mostly smallish stuff. I expect to send
1
First pullreq for arm of the 4.1 series, since I'm back from
2
out another pullreq at the end of this week, but since this
2
holiday now. This is mostly my M-profile FPU series and Philippe's
3
is up to 32 patches already I'd rather send it out now
3
devices.h cleanup. I have a pile of other patchsets to work through
4
than accumulate a monster sized patchset.
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
5
6
6
thanks
7
thanks
7
-- PMM
8
-- PMM
8
9
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
9
11
10
The following changes since commit 0ab4c574a55448a37b9f616259b82950742c9427:
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
11
12
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20180626-pull-request' into staging (2018-06-26 16:44:57 +0100)
13
13
14
are available in the Git repository at:
14
are available in the Git repository at:
15
15
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180626
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
17
17
18
for you to fetch changes up to 9b945a9ee36a34eaeca412ef9ef35fbfe33c2c85:
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
19
19
20
aspeed/timer: use the APB frequency from the SCU (2018-06-26 17:50:42 +0100)
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
21
21
22
----------------------------------------------------------------
22
----------------------------------------------------------------
23
target-arm queue:
23
target-arm queue:
24
* aspeed: set APB clocks correctly (fixes slowdown on palmetto)
24
* remove "bag of random stuff" hw/devices.h header
25
* smmuv3: cache config data and TLB entries
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
26
* v7m/v8m: support read/write from MPU regions smaller than 1K
26
* hw/dma: Compile the bcm2835_dma device as common object
27
* various: clean up logging/debug messages
27
* configure: Remove --source-path option
28
* xilinx_spips: Make dma transactions as per dma_burst_size
28
* hw/ssi/xilinx_spips: Avoid variable length array
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Cédric Le Goater (6):
32
Eric Auger (1):
32
aspeed/smc: fix dummy cycles count when in dual IO mode
33
hw/arm/smmuv3: Remove SMMUNotifierNode
33
aspeed/smc: fix HW strapping
34
aspeed/smc: rename aspeed_smc_flash_send_addr() to aspeed_smc_flash_setup()
35
aspeed/scu: introduce clock frequencies
36
aspeed: initialize the SCU controller first
37
aspeed/timer: use the APB frequency from the SCU
38
34
39
Eric Auger (3):
35
Peter Maydell (28):
40
hw/arm/smmuv3: Cache/invalidate config data
36
hw/ssi/xilinx_spips: Avoid variable length array
41
hw/arm/smmuv3: IOTLB emulation
37
configure: Remove --source-path option
42
hw/arm/smmuv3: Add notifications on invalidation
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
43
64
44
Jia He (1):
65
Philippe Mathieu-Daudé (13):
45
hw/arm/smmuv3: Fix translate error handling
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
46
79
47
Joel Stanley (1):
80
configure | 10 +-
48
MAINTAINERS: Add ASPEED BMCs
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
49
139
50
Peter Maydell (3):
51
tcg: Support MMU protection regions smaller than TARGET_PAGE_SIZE
52
target/arm: Set page (region) size in get_phys_addr_pmsav7()
53
target/arm: Handle small regions in get_phys_addr_pmsav8()
54
55
Philippe Mathieu-Daudé (17):
56
MAINTAINERS: Adopt the Gumstix computers-on-module machines
57
hw/input/pckbd: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
58
hw/input/tsc2005: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
59
hw/dma/omap_dma: Use qemu_log_mask(UNIMP) instead of printf
60
hw/dma/omap_dma: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
61
hw/ssi/omap_spi: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
62
hw/sd/omap_mmc: Use qemu_log_mask(UNIMP) instead of printf
63
hw/i2c/omap_i2c: Use qemu_log_mask(UNIMP) instead of fprintf
64
hw/arm/omap1: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
65
hw/arm/omap: Use qemu_log_mask(GUEST_ERROR) instead of fprintf
66
hw/arm/stellaris: Use qemu_log_mask(UNIMP) instead of fprintf
67
hw/net/stellaris_enet: Fix a typo
68
hw/net/stellaris_enet: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
69
hw/net/smc91c111: Use qemu_log_mask(GUEST_ERROR) instead of hw_error
70
hw/net/smc91c111: Use qemu_log_mask(UNIMP) instead of fprintf
71
hw/arm/stellaris: Fix gptm_write() error message
72
hw/arm/stellaris: Use HWADDR_PRIx to display register address
73
74
Sai Pavan Boddu (1):
75
xilinx_spips: Make dma transactions as per dma_burst_size
76
77
accel/tcg/softmmu_template.h | 24 ++-
78
hw/arm/smmuv3-internal.h | 12 +-
79
include/exec/cpu-all.h | 5 +-
80
include/hw/arm/omap.h | 30 +--
81
include/hw/arm/smmu-common.h | 24 +++
82
include/hw/arm/smmuv3.h | 1 +
83
include/hw/misc/aspeed_scu.h | 70 ++++++-
84
include/hw/ssi/xilinx_spips.h | 5 +-
85
include/hw/timer/aspeed_timer.h | 4 +
86
accel/tcg/cputlb.c | 131 +++++++++++--
87
hw/arm/aspeed_soc.c | 42 ++--
88
hw/arm/omap1.c | 18 +-
89
hw/arm/smmu-common.c | 118 ++++++++++-
90
hw/arm/smmuv3.c | 420 ++++++++++++++++++++++++++++++++++++----
91
hw/arm/stellaris.c | 8 +-
92
hw/dma/omap_dma.c | 70 ++++---
93
hw/i2c/omap_i2c.c | 20 +-
94
hw/input/pckbd.c | 4 +-
95
hw/input/tsc2005.c | 13 +-
96
hw/misc/aspeed_scu.c | 106 ++++++++++
97
hw/net/smc91c111.c | 21 +-
98
hw/net/stellaris_enet.c | 11 +-
99
hw/sd/omap_mmc.c | 13 +-
100
hw/ssi/aspeed_smc.c | 48 ++---
101
hw/ssi/omap_spi.c | 15 +-
102
hw/ssi/xilinx_spips.c | 23 ++-
103
hw/timer/aspeed_timer.c | 19 +-
104
target/arm/helper.c | 115 +++++++----
105
MAINTAINERS | 14 +-
106
hw/arm/trace-events | 27 ++-
107
30 files changed, 1176 insertions(+), 255 deletions(-)
108
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Let's cache config data to avoid fetching and parsing STE/CD
3
The SMMUNotifierNode struct is not necessary and brings extra
4
structures on each translation. We invalidate them on data structure
4
complexity so let's remove it. We now directly track the SMMUDevices
5
invalidation commands.
5
which have registered IOMMU MR notifiers.
6
6
7
We put in place a per-smmu mutex to protect the config cache. This
7
This is inspired from the same transformation on intel-iommu
8
will be useful too to protect the IOTLB cache. The caches can be
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
9
accessed without BQL, ie. in IO dataplane. The same kind of mutex was
9
("intel-iommu: remove IntelIOMMUNotifierNode")
10
put in place in the intel viommu.
11
10
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Message-id: 1529653501-15358-3-git-send-email-eric.auger@redhat.com
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
15
---
17
include/hw/arm/smmu-common.h | 5 ++
16
include/hw/arm/smmu-common.h | 8 ++------
18
include/hw/arm/smmuv3.h | 1 +
17
hw/arm/smmu-common.c | 6 +++---
19
hw/arm/smmu-common.c | 24 ++++++-
18
hw/arm/smmuv3.c | 28 +++++++---------------------
20
hw/arm/smmuv3.c | 135 +++++++++++++++++++++++++++++++++--
19
3 files changed, 12 insertions(+), 30 deletions(-)
21
hw/arm/trace-events | 6 ++
22
5 files changed, 164 insertions(+), 7 deletions(-)
23
20
24
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
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/arm/smmu-common.h
23
--- a/include/hw/arm/smmu-common.h
27
+++ b/include/hw/arm/smmu-common.h
24
+++ b/include/hw/arm/smmu-common.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
29
int devfn;
30
IOMMUMemoryRegion iommu;
31
AddressSpace as;
26
AddressSpace as;
32
+ uint32_t cfg_cache_hits;
27
uint32_t cfg_cache_hits;
33
+ uint32_t cfg_cache_misses;
28
uint32_t cfg_cache_misses;
29
+ QLIST_ENTRY(SMMUDevice) next;
34
} SMMUDevice;
30
} SMMUDevice;
35
31
36
typedef struct SMMUNotifierNode {
32
-typedef struct SMMUNotifierNode {
37
@@ -XXX,XX +XXX,XX @@ int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
33
- SMMUDevice *sdev;
38
*/
34
- QLIST_ENTRY(SMMUNotifierNode) next;
39
SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
35
-} SMMUNotifierNode;
40
36
-
41
+/* Return the iommu mr associated to @sid, or NULL if none */
37
typedef struct SMMUPciBus {
42
+IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
38
PCIBus *bus;
43
+
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
44
#endif /* HW_ARM_SMMU_COMMON */
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
45
diff --git a/include/hw/arm/smmuv3.h b/include/hw/arm/smmuv3.h
41
GHashTable *iotlb;
46
index XXXXXXX..XXXXXXX 100644
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
47
--- a/include/hw/arm/smmuv3.h
43
PCIBus *pci_bus;
48
+++ b/include/hw/arm/smmuv3.h
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
49
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUv3State {
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
50
SMMUQueue eventq, cmdq;
46
uint8_t bus_num;
51
47
PCIBus *primary_bus;
52
qemu_irq irq[4];
48
} SMMUState;
53
+ QemuMutex mutex;
54
} SMMUv3State;
55
56
typedef enum {
57
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
58
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/smmu-common.c
51
--- a/hw/arm/smmu-common.c
60
+++ b/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
61
@@ -XXX,XX +XXX,XX @@ static AddressSpace *smmu_find_add_as(PCIBus *bus, void *opaque, int devfn)
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
62
return &sdev->as;
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
63
}
65
}
64
66
65
+IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
66
+{
67
+ uint8_t bus_n, devfn;
68
+ SMMUPciBus *smmu_bus;
69
+ SMMUDevice *smmu;
70
+
71
+ bus_n = PCI_BUS_NUM(sid);
72
+ smmu_bus = smmu_find_smmu_pcibus(s, bus_n);
73
+ if (smmu_bus) {
74
+ devfn = sid & 0x7;
75
+ smmu = smmu_bus->pbdev[devfn];
76
+ if (smmu) {
77
+ return &smmu->iommu;
78
+ }
79
+ }
80
+ return NULL;
81
+}
82
+
83
static void smmu_base_realize(DeviceState *dev, Error **errp)
84
{
85
SMMUState *s = ARM_SMMU(dev);
86
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
87
error_propagate(errp, local_err);
88
return;
89
}
90
-
91
+ s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free);
92
s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
93
94
if (s->primary_bus) {
95
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
96
97
static void smmu_base_reset(DeviceState *dev)
98
{
99
- /* will be filled later on */
100
+ SMMUState *s = ARM_SMMU(dev);
101
+
102
+ g_hash_table_remove_all(s->configs);
103
}
104
105
static Property smmu_dev_properties[] = {
106
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
107
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/smmuv3.c
69
--- a/hw/arm/smmuv3.c
109
+++ b/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
110
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
111
return decode_cd(cfg, &cd, event);
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
112
}
119
}
113
120
114
+/**
115
+ * smmuv3_get_config - Look up for a cached copy of configuration data for
116
+ * @sdev and on cache miss performs a configuration structure decoding from
117
+ * guest RAM.
118
+ *
119
+ * @sdev: SMMUDevice handle
120
+ * @event: output event info
121
+ *
122
+ * The configuration cache contains data resulting from both STE and CD
123
+ * decoding under the form of an SMMUTransCfg struct. The hash table is indexed
124
+ * by the SMMUDevice handle.
125
+ */
126
+static SMMUTransCfg *smmuv3_get_config(SMMUDevice *sdev, SMMUEventInfo *event)
127
+{
128
+ SMMUv3State *s = sdev->smmu;
129
+ SMMUState *bc = &s->smmu_state;
130
+ SMMUTransCfg *cfg;
131
+
132
+ cfg = g_hash_table_lookup(bc->configs, sdev);
133
+ if (cfg) {
134
+ sdev->cfg_cache_hits++;
135
+ trace_smmuv3_config_cache_hit(smmu_get_sid(sdev),
136
+ sdev->cfg_cache_hits, sdev->cfg_cache_misses,
137
+ 100 * sdev->cfg_cache_hits /
138
+ (sdev->cfg_cache_hits + sdev->cfg_cache_misses));
139
+ } else {
140
+ sdev->cfg_cache_misses++;
141
+ trace_smmuv3_config_cache_miss(smmu_get_sid(sdev),
142
+ sdev->cfg_cache_hits, sdev->cfg_cache_misses,
143
+ 100 * sdev->cfg_cache_hits /
144
+ (sdev->cfg_cache_hits + sdev->cfg_cache_misses));
145
+ cfg = g_new0(SMMUTransCfg, 1);
146
+
147
+ if (!smmuv3_decode_config(&sdev->iommu, cfg, event)) {
148
+ g_hash_table_insert(bc->configs, sdev, cfg);
149
+ } else {
150
+ g_free(cfg);
151
+ cfg = NULL;
152
+ }
153
+ }
154
+ return cfg;
155
+}
156
+
157
+static void smmuv3_flush_config(SMMUDevice *sdev)
158
+{
159
+ SMMUv3State *s = sdev->smmu;
160
+ SMMUState *bc = &s->smmu_state;
161
+
162
+ trace_smmuv3_config_cache_inv(smmu_get_sid(sdev));
163
+ g_hash_table_remove(bc->configs, sdev);
164
+}
165
+
166
static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
167
IOMMUAccessFlags flag, int iommu_idx)
168
{
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
170
SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
171
SMMUPTWEventInfo ptw_info = {};
172
SMMUTranslationStatus status;
173
- SMMUTransCfg cfg = {};
174
+ SMMUTransCfg *cfg = NULL;
175
IOMMUTLBEntry entry = {
176
.target_as = &address_space_memory,
177
.iova = addr,
178
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
179
.perm = IOMMU_NONE,
180
};
181
182
+ qemu_mutex_lock(&s->mutex);
183
+
184
if (!smmu_enabled(s)) {
185
status = SMMU_TRANS_DISABLE;
186
goto epilogue;
187
}
188
189
- if (smmuv3_decode_config(mr, &cfg, &event)) {
190
+ cfg = smmuv3_get_config(sdev, &event);
191
+ if (!cfg) {
192
status = SMMU_TRANS_ERROR;
193
goto epilogue;
194
}
195
196
- if (cfg.aborted) {
197
+ if (cfg->aborted) {
198
status = SMMU_TRANS_ABORT;
199
goto epilogue;
200
}
201
202
- if (cfg.bypassed) {
203
+ if (cfg->bypassed) {
204
status = SMMU_TRANS_BYPASS;
205
goto epilogue;
206
}
207
208
- if (smmu_ptw(&cfg, addr, flag, &entry, &ptw_info)) {
209
+ if (smmu_ptw(cfg, addr, flag, &entry, &ptw_info)) {
210
switch (ptw_info.type) {
211
case SMMU_PTW_ERR_WALK_EABT:
212
event.type = SMMU_EVT_F_WALK_EABT;
213
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
214
}
215
216
epilogue:
217
+ qemu_mutex_unlock(&s->mutex);
218
switch (status) {
219
case SMMU_TRANS_SUCCESS:
220
entry.perm = flag;
221
@@ -XXX,XX +XXX,XX @@ epilogue:
222
223
static int smmuv3_cmdq_consume(SMMUv3State *s)
224
{
225
+ SMMUState *bs = ARM_SMMU(s);
226
SMMUCmdError cmd_error = SMMU_CERROR_NONE;
227
SMMUQueue *q = &s->cmdq;
228
SMMUCommandType type = 0;
229
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
230
231
trace_smmuv3_cmdq_opcode(smmu_cmd_string(type));
232
233
+ qemu_mutex_lock(&s->mutex);
234
switch (type) {
235
case SMMU_CMD_SYNC:
236
if (CMD_SYNC_CS(&cmd) & CMD_SYNC_SIG_IRQ) {
237
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
238
break;
239
case SMMU_CMD_PREFETCH_CONFIG:
240
case SMMU_CMD_PREFETCH_ADDR:
241
+ break;
242
case SMMU_CMD_CFGI_STE:
243
+ {
244
+ uint32_t sid = CMD_SID(&cmd);
245
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
246
+ SMMUDevice *sdev;
247
+
248
+ if (CMD_SSEC(&cmd)) {
249
+ cmd_error = SMMU_CERROR_ILL;
250
+ break;
251
+ }
252
+
253
+ if (!mr) {
254
+ break;
255
+ }
256
+
257
+ trace_smmuv3_cmdq_cfgi_ste(sid);
258
+ sdev = container_of(mr, SMMUDevice, iommu);
259
+ smmuv3_flush_config(sdev);
260
+
261
+ break;
262
+ }
263
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
264
+ {
265
+ uint32_t start = CMD_SID(&cmd), end, i;
266
+ uint8_t range = CMD_STE_RANGE(&cmd);
267
+
268
+ if (CMD_SSEC(&cmd)) {
269
+ cmd_error = SMMU_CERROR_ILL;
270
+ break;
271
+ }
272
+
273
+ end = start + (1 << (range + 1)) - 1;
274
+ trace_smmuv3_cmdq_cfgi_ste_range(start, end);
275
+
276
+ for (i = start; i <= end; i++) {
277
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
278
+ SMMUDevice *sdev;
279
+
280
+ if (!mr) {
281
+ continue;
282
+ }
283
+ sdev = container_of(mr, SMMUDevice, iommu);
284
+ smmuv3_flush_config(sdev);
285
+ }
286
+ break;
287
+ }
288
case SMMU_CMD_CFGI_CD:
289
case SMMU_CMD_CFGI_CD_ALL:
290
+ {
291
+ uint32_t sid = CMD_SID(&cmd);
292
+ IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, sid);
293
+ SMMUDevice *sdev;
294
+
295
+ if (CMD_SSEC(&cmd)) {
296
+ cmd_error = SMMU_CERROR_ILL;
297
+ break;
298
+ }
299
+
300
+ if (!mr) {
301
+ break;
302
+ }
303
+
304
+ trace_smmuv3_cmdq_cfgi_cd(sid);
305
+ sdev = container_of(mr, SMMUDevice, iommu);
306
+ smmuv3_flush_config(sdev);
307
+ break;
308
+ }
309
case SMMU_CMD_TLBI_NH_ALL:
310
case SMMU_CMD_TLBI_NH_ASID:
311
case SMMU_CMD_TLBI_NH_VA:
312
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
313
"Illegal command type: %d\n", CMD_TYPE(&cmd));
314
break;
315
}
316
+ qemu_mutex_unlock(&s->mutex);
317
if (cmd_error) {
318
break;
319
}
320
@@ -XXX,XX +XXX,XX @@ static void smmu_realize(DeviceState *d, Error **errp)
321
return;
322
}
323
324
+ qemu_mutex_init(&s->mutex);
325
+
326
memory_region_init_io(&sys->iomem, OBJECT(s),
327
&smmu_mem_ops, sys, TYPE_ARM_SMMUV3, 0x20000);
328
329
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
330
index XXXXXXX..XXXXXXX 100644
331
--- a/hw/arm/trace-events
332
+++ b/hw/arm/trace-events
333
@@ -XXX,XX +XXX,XX @@ smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t tr
334
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
335
smmuv3_decode_cd(uint32_t oas) "oas=%d"
336
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"
337
+smmuv3_cmdq_cfgi_ste(int streamid) "streamid =%d"
338
+smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%d - end=0x%d"
339
+smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
340
+smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
341
+smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
342
+smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
343
--
121
--
344
2.17.1
122
2.20.1
345
123
346
124
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
2
4
3
Suggested-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20180624040609.17572-17-f4bug@amsat.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
8
---
11
---
9
hw/arm/stellaris.c | 6 ++++--
12
hw/ssi/xilinx_spips.c | 6 ++++--
10
1 file changed, 4 insertions(+), 2 deletions(-)
13
1 file changed, 4 insertions(+), 2 deletions(-)
11
14
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/stellaris.c
17
--- a/hw/ssi/xilinx_spips.c
15
+++ b/hw/arm/stellaris.c
18
+++ b/hw/ssi/xilinx_spips.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t gptm_read(void *opaque, hwaddr offset,
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
17
return 0;
20
18
default:
21
static inline void stripe8(uint8_t *x, int num, bool dir)
19
qemu_log_mask(LOG_GUEST_ERROR,
22
{
20
- "GPTM: read at bad offset 0x%x\n", (int)offset);
23
- uint8_t r[num];
21
+ "GPTM: read at bad offset 0x02%" HWADDR_PRIx "\n",
24
- memset(r, 0, sizeof(uint8_t) * num);
22
+ offset);
25
+ uint8_t r[MAX_NUM_BUSSES];
23
return 0;
26
int idx[2] = {0, 0};
24
}
27
int bit[2] = {0, 7};
25
}
28
int d = dir;
26
@@ -XXX,XX +XXX,XX @@ static void gptm_write(void *opaque, hwaddr offset,
29
27
break;
30
+ assert(num <= MAX_NUM_BUSSES);
28
default:
31
+ memset(r, 0, sizeof(uint8_t) * num);
29
qemu_log_mask(LOG_GUEST_ERROR,
32
+
30
- "GPTM: write at bad offset 0x%x\n", (int)offset);
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
31
+ "GPTM: write at bad offset 0x02%" HWADDR_PRIx "\n",
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
32
+ offset);
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
33
}
34
gptm_update_irq(s);
35
}
36
--
36
--
37
2.17.1
37
2.20.1
38
38
39
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
2
5
3
Suggested-by: Thomas Huth <thuth@redhat.com>
6
There isn't really an obvious use case for the --source-path
4
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
option, and in commit 927128222b0a91f56c13a in 2017 we
5
Message-id: 20180624040609.17572-12-f4bug@amsat.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
21
---
8
hw/net/stellaris_enet.c | 2 +-
22
configure | 10 ++--------
9
1 file changed, 1 insertion(+), 1 deletion(-)
23
1 file changed, 2 insertions(+), 8 deletions(-)
10
24
11
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
25
diff --git a/configure b/configure
12
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100755
13
--- a/hw/net/stellaris_enet.c
27
--- a/configure
14
+++ b/hw/net/stellaris_enet.c
28
+++ b/configure
15
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
16
return s->np;
30
17
case 0x38: /* TR */
31
# default parameters
18
return 0;
32
source_path=$(dirname "$0")
19
- case 0x3c: /* Undocuented: Timestamp? */
33
+# make source path absolute
20
+ case 0x3c: /* Undocumented: Timestamp? */
34
+source_path=$(cd "$source_path"; pwd)
21
return 0;
35
cpu=""
22
default:
36
iasl="iasl"
23
hw_error("stellaris_enet_read: Bad offset %x\n", (int)offset);
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]
24
--
74
--
25
2.17.1
75
2.20.1
26
76
27
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
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The M-profile floating point support has three associated config
2
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
CPACR and NSACR have behaviour other than reads-as-zero.
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Add support for all of these as simple reads-as-written registers.
5
Message-id: 20180624040609.17572-5-f4bug@amsat.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
20
---
8
hw/dma/omap_dma.c | 64 +++++++++++++++++++++++++++++------------------
21
target/arm/cpu.h | 34 ++++++++++++
9
1 file changed, 40 insertions(+), 24 deletions(-)
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
10
23
target/arm/cpu.c | 5 ++
11
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
24
target/arm/machine.c | 16 ++++++
12
index XXXXXXX..XXXXXXX 100644
25
4 files changed, 180 insertions(+)
13
--- a/hw/dma/omap_dma.c
26
14
+++ b/hw/dma/omap_dma.c
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
28
index XXXXXXX..XXXXXXX 100644
16
ch->burst[0] = (value & 0x0180) >> 7;
29
--- a/target/arm/cpu.h
17
ch->pack[0] = (value & 0x0040) >> 6;
30
+++ b/target/arm/cpu.h
18
ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
19
- if (ch->port[0] >= __omap_dma_port_last)
32
uint32_t scr[M_REG_NUM_BANKS];
20
- printf("%s: invalid DMA port %i\n", __func__,
33
uint32_t msplim[M_REG_NUM_BANKS];
21
- ch->port[0]);
34
uint32_t psplim[M_REG_NUM_BANKS];
22
- if (ch->port[1] >= __omap_dma_port_last)
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
23
- printf("%s: invalid DMA port %i\n", __func__,
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
24
- ch->port[1]);
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
25
+ if (ch->port[0] >= __omap_dma_port_last) {
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
26
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
39
+ uint32_t nsacr;
27
+ __func__, ch->port[0]);
40
} v7m;
28
+ }
41
29
+ if (ch->port[1] >= __omap_dma_port_last) {
42
/* Information associated with an exception about to be taken:
30
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
31
+ __func__, ch->port[1]);
44
*/
32
+ }
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
33
ch->data_type = 1 << (value & 3);
46
34
if ((value & 3) == 3) {
47
+/* v7M FPCCR bits */
35
- printf("%s: bad data_type for DMA channel\n", __func__);
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
36
+ qemu_log_mask(LOG_GUEST_ERROR,
49
+FIELD(V7M_FPCCR, USER, 1, 1)
37
+ "%s: bad data_type for DMA channel\n", __func__);
50
+FIELD(V7M_FPCCR, S, 2, 1)
38
ch->data_type >>= 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;
39
}
146
}
40
break;
147
break;
41
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
148
+ case 0xd88: /* CPACR */
42
if (value & 2)                        /* SOFTRESET */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
43
omap_dma_reset(s->dma);
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
44
s->ocp = value & 0x3321;
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
45
- if (((s->ocp >> 12) & 3) == 3)                /* MIDLEMODE */
152
+ }
46
- fprintf(stderr, "%s: invalid DMA power mode\n", __func__);
153
+ break;
47
+ if (((s->ocp >> 12) & 3) == 3) { /* MIDLEMODE */
154
+ case 0xd8c: /* NSACR */
48
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA power mode\n",
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
49
+ __func__);
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
50
+ }
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
51
return;
158
+ }
52
159
+ break;
53
case 0x78:    /* DMA4_GCR */
160
case 0xd90: /* MPU_TYPE */
54
s->gcr = value & 0x00ff00ff;
161
return; /* RO */
55
-    if ((value & 0xff) == 0x00)        /* MAX_CHANNEL_FIFO_DEPTH */
162
case 0xd94: /* MPU_CTRL */
56
- fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __func__);
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
57
+ if ((value & 0xff) == 0x00) { /* MAX_CHANNEL_FIFO_DEPTH */
58
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: wrong FIFO depth in GCR\n",
59
+ __func__);
60
+ }
61
return;
62
63
case 0x80 ... 0xfff:
64
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
65
case 0x00:    /* DMA4_CCR */
66
ch->buf_disable = (value >> 25) & 1;
67
ch->src_sync = (value >> 24) & 1;    /* XXX For CamDMA must be 1 */
68
- if (ch->buf_disable && !ch->src_sync)
69
- fprintf(stderr, "%s: Buffering disable is not allowed in "
70
- "destination synchronised mode\n", __func__);
71
+ if (ch->buf_disable && !ch->src_sync) {
72
+ qemu_log_mask(LOG_GUEST_ERROR,
73
+ "%s: Buffering disable is not allowed in "
74
+ "destination synchronised mode\n", __func__);
75
+ }
76
ch->prefetch = (value >> 23) & 1;
77
ch->bs = (value >> 18) & 1;
78
ch->transparent_copy = (value >> 17) & 1;
79
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
80
ch->suspend = (value & 0x0100) >> 8;
81
ch->priority = (value & 0x0040) >> 6;
82
ch->fs = (value & 0x0020) >> 5;
83
- if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1])
84
- fprintf(stderr, "%s: For a packet transfer at least one port "
85
- "must be constant-addressed\n", __func__);
86
+ if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1]) {
87
+ qemu_log_mask(LOG_GUEST_ERROR,
88
+ "%s: For a packet transfer at least one port "
89
+ "must be constant-addressed\n", __func__);
90
+ }
91
ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
92
/* XXX must be 0x01 for CamDMA */
93
94
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
95
ch->endian_lock[0] =(value >> 20) & 1;
96
ch->endian[1] =(value >> 19) & 1;
97
ch->endian_lock[1] =(value >> 18) & 1;
98
- if (ch->endian[0] != ch->endian[1])
99
- fprintf(stderr, "%s: DMA endianness conversion enable attempt\n",
100
- __func__);
101
+ if (ch->endian[0] != ch->endian[1]) {
102
+ qemu_log_mask(LOG_GUEST_ERROR,
103
+ "%s: DMA endianness conversion enable attempt\n",
104
+ __func__);
105
+ }
106
ch->write_mode = (value >> 16) & 3;
107
ch->burst[1] = (value & 0xc000) >> 14;
108
ch->pack[1] = (value & 0x2000) >> 13;
109
@@ -XXX,XX +XXX,XX @@ static void omap_dma4_write(void *opaque, hwaddr addr,
110
ch->burst[0] = (value & 0x0180) >> 7;
111
ch->pack[0] = (value & 0x0040) >> 6;
112
ch->translate[0] = (value & 0x003c) >> 2;
113
- if (ch->translate[0] | ch->translate[1])
114
- fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
115
- __func__);
116
+ if (ch->translate[0] | ch->translate[1]) {
117
+ qemu_log_mask(LOG_GUEST_ERROR,
118
+ "%s: bad MReqAddressTranslate sideband signal\n",
119
+ __func__);
120
+ }
121
ch->data_type = 1 << (value & 3);
122
if ((value & 3) == 3) {
123
- printf("%s: bad data_type for DMA channel\n", __func__);
124
+ qemu_log_mask(LOG_GUEST_ERROR,
125
+ "%s: bad data_type for DMA channel\n", __func__);
126
ch->data_type >>= 1;
127
}
164
}
128
break;
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
};
129
--
286
--
130
2.17.1
287
2.20.1
131
288
132
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
We emulate a TLB cache of size SMMU_IOTLB_MAX_SIZE=256.
4
M-profile also has CPACR and NSACR similar to A-profile;
4
It is implemented as a hash table whose key is a combination
5
they behave slightly differently:
5
of the 16b asid and 48b IOVA (Jenkins hash).
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
6
9
7
Entries are invalidated on TLB invalidation commands, either
10
Honour the CPACR and NSACR settings. The NSACR handling
8
globally, or per asid, or per asid/iova.
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
9
15
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Message-id: 1529653501-15358-4-git-send-email-eric.auger@redhat.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
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
14
---
19
---
15
include/hw/arm/smmu-common.h | 13 +++++
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
16
hw/arm/smmu-common.c | 60 ++++++++++++++++++++++
21
target/arm/translate.c | 10 ++++++--
17
hw/arm/smmuv3.c | 98 ++++++++++++++++++++++++++++++++++--
22
2 files changed, 60 insertions(+), 5 deletions(-)
18
hw/arm/trace-events | 9 ++++
19
4 files changed, 176 insertions(+), 4 deletions(-)
20
23
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
26
--- a/target/arm/helper.c
24
+++ b/include/hw/arm/smmu-common.h
27
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
26
uint8_t tbi; /* Top Byte Ignore */
29
return target_el;
27
uint16_t asid;
30
}
28
SMMUTransTableInfo tt[2];
31
29
+ uint32_t iotlb_hits; /* counts IOTLB hits for this asid */
32
+/*
30
+ uint32_t iotlb_misses; /* counts IOTLB misses for this asid */
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
31
} SMMUTransCfg;
34
+ * security state and privilege level.
32
35
+ */
33
typedef struct SMMUDevice {
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
34
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUPciBus {
35
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
36
} SMMUPciBus;
37
38
+typedef struct SMMUIOTLBKey {
39
+ uint64_t iova;
40
+ uint16_t asid;
41
+} SMMUIOTLBKey;
42
+
43
typedef struct SMMUState {
44
/* <private> */
45
SysBusDevice dev;
46
@@ -XXX,XX +XXX,XX @@ SMMUTransTableInfo *select_tt(SMMUTransCfg *cfg, dma_addr_t iova);
47
/* Return the iommu mr associated to @sid, or NULL if none */
48
IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid);
49
50
+#define SMMU_IOTLB_MAX_SIZE 256
51
+
52
+void smmu_iotlb_inv_all(SMMUState *s);
53
+void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
54
+void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova);
55
+
56
#endif /* HW_ARM_SMMU_COMMON */
57
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/smmu-common.c
60
+++ b/hw/arm/smmu-common.c
61
@@ -XXX,XX +XXX,XX @@
62
#include "qom/cpu.h"
63
#include "hw/qdev-properties.h"
64
#include "qapi/error.h"
65
+#include "qemu/jhash.h"
66
67
#include "qemu/error-report.h"
68
#include "hw/arm/smmu-common.h"
69
#include "smmu-internal.h"
70
71
+/* IOTLB Management */
72
+
73
+inline void smmu_iotlb_inv_all(SMMUState *s)
74
+{
37
+{
75
+ trace_smmu_iotlb_inv_all();
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
76
+ g_hash_table_remove_all(s->iotlb);
39
+ case 0:
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
41
+ return false;
42
+ case 1:
43
+ return is_priv;
44
+ case 3:
45
+ return true;
46
+ default:
47
+ g_assert_not_reached();
48
+ }
77
+}
49
+}
78
+
50
+
79
+static gboolean smmu_hash_remove_by_asid(gpointer key, gpointer value,
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
80
+ gpointer user_data)
52
ARMMMUIdx mmu_idx, bool ignfault)
81
+{
53
{
82
+ uint16_t asid = *(uint16_t *)user_data;
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
83
+ SMMUIOTLBKey *iotlb_key = (SMMUIOTLBKey *)key;
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;
84
+
67
+
85
+ return iotlb_key->asid == asid;
68
+ if (env->exception.target_el == 3) {
86
+}
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
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
+ }
87
+
89
+
88
+inline void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova)
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
89
+{
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
90
+ SMMUIOTLBKey key = {.asid = asid, .iova = iova};
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
91
+
96
+
92
+ trace_smmu_iotlb_inv_iova(asid, iova);
97
+ return 0;
93
+ g_hash_table_remove(s->iotlb, &key);
94
+}
95
+
96
+inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
97
+{
98
+ trace_smmu_iotlb_inv_asid(asid);
99
+ g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
100
+}
101
+
102
/* VMSAv8-64 Translation */
103
104
/**
105
@@ -XXX,XX +XXX,XX @@ IOMMUMemoryRegion *smmu_iommu_mr(SMMUState *s, uint32_t sid)
106
return NULL;
107
}
108
109
+static guint smmu_iotlb_key_hash(gconstpointer v)
110
+{
111
+ SMMUIOTLBKey *key = (SMMUIOTLBKey *)v;
112
+ uint32_t a, b, c;
113
+
114
+ /* Jenkins hash */
115
+ a = b = c = JHASH_INITVAL + sizeof(*key);
116
+ a += key->asid;
117
+ b += extract64(key->iova, 0, 32);
118
+ c += extract64(key->iova, 32, 32);
119
+
120
+ __jhash_mix(a, b, c);
121
+ __jhash_final(a, b, c);
122
+
123
+ return c;
124
+}
125
+
126
+static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
127
+{
128
+ const SMMUIOTLBKey *k1 = v1;
129
+ const SMMUIOTLBKey *k2 = v2;
130
+
131
+ return (k1->asid == k2->asid) && (k1->iova == k2->iova);
132
+}
133
+
134
static void smmu_base_realize(DeviceState *dev, Error **errp)
135
{
136
SMMUState *s = ARM_SMMU(dev);
137
@@ -XXX,XX +XXX,XX @@ static void smmu_base_realize(DeviceState *dev, Error **errp)
138
return;
139
}
140
s->configs = g_hash_table_new_full(NULL, NULL, NULL, g_free);
141
+ s->iotlb = g_hash_table_new_full(smmu_iotlb_key_hash, smmu_iotlb_key_equal,
142
+ g_free, g_free);
143
s->smmu_pcibus_by_busptr = g_hash_table_new(NULL, NULL);
144
145
if (s->primary_bus) {
146
@@ -XXX,XX +XXX,XX @@ static void smmu_base_reset(DeviceState *dev)
147
SMMUState *s = ARM_SMMU(dev);
148
149
g_hash_table_remove_all(s->configs);
150
+ g_hash_table_remove_all(s->iotlb);
151
}
152
153
static Property smmu_dev_properties[] = {
154
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
155
index XXXXXXX..XXXXXXX 100644
156
--- a/hw/arm/smmuv3.c
157
+++ b/hw/arm/smmuv3.c
158
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
159
SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
160
SMMUPTWEventInfo ptw_info = {};
161
SMMUTranslationStatus status;
162
+ SMMUState *bs = ARM_SMMU(s);
163
+ uint64_t page_mask, aligned_addr;
164
+ IOMMUTLBEntry *cached_entry = NULL;
165
+ SMMUTransTableInfo *tt;
166
SMMUTransCfg *cfg = NULL;
167
IOMMUTLBEntry entry = {
168
.target_as = &address_space_memory,
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
170
.addr_mask = ~(hwaddr)0,
171
.perm = IOMMU_NONE,
172
};
173
+ SMMUIOTLBKey key, *new_key;
174
175
qemu_mutex_lock(&s->mutex);
176
177
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
178
goto epilogue;
179
}
180
181
- if (smmu_ptw(cfg, addr, flag, &entry, &ptw_info)) {
182
+ tt = select_tt(cfg, addr);
183
+ if (!tt) {
184
+ if (event.record_trans_faults) {
185
+ event.type = SMMU_EVT_F_TRANSLATION;
186
+ event.u.f_translation.addr = addr;
187
+ event.u.f_translation.rnw = flag & 0x1;
188
+ }
189
+ status = SMMU_TRANS_ERROR;
190
+ goto epilogue;
191
+ }
98
+ }
192
+
99
+
193
+ page_mask = (1ULL << (tt->granule_sz)) - 1;
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
194
+ aligned_addr = addr & ~page_mask;
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
195
+
102
* 1 : trap only EL0 accesses
196
+ key.asid = cfg->asid;
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
197
+ key.iova = aligned_addr;
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
198
+
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
199
+ cached_entry = g_hash_table_lookup(bs->iotlb, &key);
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
200
+ if (cached_entry) {
107
- || arm_el_is_aa64(env, 1)) {
201
+ cfg->iotlb_hits++;
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
202
+ trace_smmu_iotlb_cache_hit(cfg->asid, aligned_addr,
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
203
+ cfg->iotlb_hits, cfg->iotlb_misses,
110
}
204
+ 100 * cfg->iotlb_hits /
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
205
+ (cfg->iotlb_hits + cfg->iotlb_misses));
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
206
+ if ((flag & IOMMU_WO) && !(cached_entry->perm & IOMMU_WO)) {
113
index XXXXXXX..XXXXXXX 100644
207
+ status = SMMU_TRANS_ERROR;
114
--- a/target/arm/translate.c
208
+ if (event.record_trans_faults) {
115
+++ b/target/arm/translate.c
209
+ event.type = SMMU_EVT_F_PERMISSION;
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
210
+ event.u.f_permission.addr = addr;
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
211
+ event.u.f_permission.rnw = flag & 0x1;
118
*/
212
+ }
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);
213
+ } else {
125
+ } else {
214
+ status = SMMU_TRANS_SUCCESS;
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
215
+ }
129
+ }
216
+ goto epilogue;
130
return 0;
217
+ }
218
+
219
+ cfg->iotlb_misses++;
220
+ trace_smmu_iotlb_cache_miss(cfg->asid, addr & ~page_mask,
221
+ cfg->iotlb_hits, cfg->iotlb_misses,
222
+ 100 * cfg->iotlb_hits /
223
+ (cfg->iotlb_hits + cfg->iotlb_misses));
224
+
225
+ if (g_hash_table_size(bs->iotlb) >= SMMU_IOTLB_MAX_SIZE) {
226
+ smmu_iotlb_inv_all(bs);
227
+ }
228
+
229
+ cached_entry = g_new0(IOMMUTLBEntry, 1);
230
+
231
+ if (smmu_ptw(cfg, aligned_addr, flag, cached_entry, &ptw_info)) {
232
+ g_free(cached_entry);
233
switch (ptw_info.type) {
234
case SMMU_PTW_ERR_WALK_EABT:
235
event.type = SMMU_EVT_F_WALK_EABT;
236
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
237
}
238
status = SMMU_TRANS_ERROR;
239
} else {
240
+ new_key = g_new0(SMMUIOTLBKey, 1);
241
+ new_key->asid = cfg->asid;
242
+ new_key->iova = aligned_addr;
243
+ g_hash_table_insert(bs->iotlb, new_key, cached_entry);
244
status = SMMU_TRANS_SUCCESS;
245
}
131
}
246
132
247
@@ -XXX,XX +XXX,XX @@ epilogue:
248
switch (status) {
249
case SMMU_TRANS_SUCCESS:
250
entry.perm = flag;
251
+ entry.translated_addr = cached_entry->translated_addr +
252
+ (addr & page_mask);
253
+ entry.addr_mask = cached_entry->addr_mask;
254
trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
255
entry.translated_addr, entry.perm);
256
break;
257
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
258
smmuv3_flush_config(sdev);
259
break;
260
}
261
- case SMMU_CMD_TLBI_NH_ALL:
262
case SMMU_CMD_TLBI_NH_ASID:
263
- case SMMU_CMD_TLBI_NH_VA:
264
+ {
265
+ uint16_t asid = CMD_ASID(&cmd);
266
+
267
+ trace_smmuv3_cmdq_tlbi_nh_asid(asid);
268
+ smmu_iotlb_inv_asid(bs, asid);
269
+ break;
270
+ }
271
+ case SMMU_CMD_TLBI_NH_ALL:
272
+ case SMMU_CMD_TLBI_NSNH_ALL:
273
+ trace_smmuv3_cmdq_tlbi_nh();
274
+ smmu_iotlb_inv_all(bs);
275
+ break;
276
case SMMU_CMD_TLBI_NH_VAA:
277
+ {
278
+ dma_addr_t addr = CMD_ADDR(&cmd);
279
+ uint16_t vmid = CMD_VMID(&cmd);
280
+
281
+ trace_smmuv3_cmdq_tlbi_nh_vaa(vmid, addr);
282
+ smmu_iotlb_inv_all(bs);
283
+ break;
284
+ }
285
+ case SMMU_CMD_TLBI_NH_VA:
286
+ {
287
+ uint16_t asid = CMD_ASID(&cmd);
288
+ uint16_t vmid = CMD_VMID(&cmd);
289
+ dma_addr_t addr = CMD_ADDR(&cmd);
290
+ bool leaf = CMD_LEAF(&cmd);
291
+
292
+ trace_smmuv3_cmdq_tlbi_nh_va(vmid, asid, addr, leaf);
293
+ smmu_iotlb_inv_iova(bs, asid, addr);
294
+ break;
295
+ }
296
case SMMU_CMD_TLBI_EL3_ALL:
297
case SMMU_CMD_TLBI_EL3_VA:
298
case SMMU_CMD_TLBI_EL2_ALL:
299
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
300
case SMMU_CMD_TLBI_EL2_VAA:
301
case SMMU_CMD_TLBI_S12_VMALL:
302
case SMMU_CMD_TLBI_S2_IPA:
303
- case SMMU_CMD_TLBI_NSNH_ALL:
304
case SMMU_CMD_ATC_INV:
305
case SMMU_CMD_PRI_RESP:
306
case SMMU_CMD_RESUME:
307
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
308
index XXXXXXX..XXXXXXX 100644
309
--- a/hw/arm/trace-events
310
+++ b/hw/arm/trace-events
311
@@ -XXX,XX +XXX,XX @@ smmu_ptw_invalid_pte(int stage, int level, uint64_t baseaddr, uint64_t pteaddr,
312
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
313
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"
314
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
315
+smmu_iotlb_cache_hit(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache HIT asid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
316
+smmu_iotlb_cache_miss(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss, uint32_t p) "IOTLB cache MISS asid=%d addr=0x%"PRIx64" hit=%d miss=%d hit rate=%d"
317
+smmu_iotlb_inv_all(void) "IOTLB invalidate all"
318
+smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
319
+smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
320
321
#hw/arm/smmuv3.c
322
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
323
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%d - end=0x%d"
324
smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
325
smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
326
smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
327
+smmuv3_cmdq_tlbi_nh_va(int vmid, int asid, uint64_t addr, bool leaf) "vmid =%d asid =%d addr=0x%"PRIx64" leaf=%d"
328
+smmuv3_cmdq_tlbi_nh_vaa(int vmid, uint64_t addr) "vmid =%d addr=0x%"PRIx64
329
+smmuv3_cmdq_tlbi_nh(void) ""
330
+smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
331
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
332
--
133
--
333
2.17.1
134
2.20.1
334
135
335
136
diff view generated by jsdifflib
New patch
1
Correct the decode of the M-profile "coprocessor and
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
1
6
7
For the moment we leave VLLDM and VLSTM as NOPs; in
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
16
1 file changed, 22 insertions(+), 4 deletions(-)
17
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
21
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
23
case 6: case 7: case 14: case 15:
24
/* Coprocessor. */
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
26
- /* We don't currently implement M profile FP support,
27
- * so this entire space should give a NOCP fault, with
28
- * the exception of the v8M VLLDM and VLSTM insns, which
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
31
+ if (extract32(insn, 24, 2) == 3) {
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
33
+ }
34
+
35
+ /*
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
37
+ * * if there is no FPU then these insns must NOP in
38
+ * Secure state and UNDEF in Nonsecure state
39
+ * * if there is an FPU then these insns do not have
40
+ * the usual behaviour that disas_vfp_insn() provides of
41
+ * being controlled by CPACR/NSACR enable bits or the
42
+ * lazy-stacking logic.
43
*/
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
45
(insn & 0xffa00f00) == 0xec200a00) {
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
47
/* Just NOP since FP support is not implemented */
48
break;
49
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
51
+ ((insn >> 8) & 0xe) == 10) {
52
+ /* FP, and the CPU supports it */
53
+ if (disas_vfp_insn(s, insn)) {
54
+ goto illegal_op;
55
+ }
56
+ break;
57
+ }
58
+
59
/* All other insns: NOCP */
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
61
default_exception_el(s));
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
New patch
1
If the floating point extension is present, then the SG instruction
2
must clear the CONTROL_S.SFPA bit. Implement this.
1
3
4
(On a no-FPU system the bit will always be zero, so we don't need
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
target/arm/helper.c | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
", executing it\n", env->regs[15]);
21
env->regs[14] &= ~1;
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
switch_v7m_security_state(env, true);
24
xpsr_write(env, 0, XPSR_IT);
25
env->regs[15] += 4;
26
--
27
2.20.1
28
29
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
2
6
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-8-f4bug@amsat.org
6
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-9-peter.maydell@linaro.org
7
---
10
---
8
hw/i2c/omap_i2c.c | 20 ++++++++++++--------
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
9
1 file changed, 12 insertions(+), 8 deletions(-)
12
1 file changed, 49 insertions(+), 8 deletions(-)
10
13
11
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/i2c/omap_i2c.c
16
--- a/target/arm/helper.c
14
+++ b/hw/i2c/omap_i2c.c
17
+++ b/target/arm/helper.c
15
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
19
return xpsr_read(env) & mask;
17
*/
20
break;
18
#include "qemu/osdep.h"
21
case 20: /* CONTROL */
19
+#include "qemu/log.h"
22
- return env->v7m.control[env->v7m.secure];
20
#include "hw/hw.h"
23
+ {
21
#include "hw/i2c/i2c.h"
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
22
#include "hw/arm/omap.h"
25
+ if (!env->v7m.secure) {
23
@@ -XXX,XX +XXX,XX @@ static void omap_i2c_write(void *opaque, hwaddr addr,
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;
24
}
63
}
25
break;
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);
26
}
96
}
27
- if ((value & (1 << 15)) && !(value & (1 << 10))) {    /* MST */
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
28
- fprintf(stderr, "%s: I^2C slave mode not supported\n",
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
29
- __func__);
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
30
+ if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
31
+ qemu_log_mask(LOG_UNIMP, "%s: I^2C slave mode not supported\n",
32
+ __func__);
33
break;
34
}
101
}
35
- if ((value & (1 << 15)) && value & (1 << 8)) {        /* XA */
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
36
- fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
103
+ /*
37
- __func__);
104
+ * SFPA is RAZ/WI from NS or if no FPU.
38
+ if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
39
+ qemu_log_mask(LOG_UNIMP,
106
+ * Both are stored in the S bank.
40
+ "%s: 10-bit addressing mode not supported\n",
107
+ */
41
+ __func__);
108
+ if (env->v7m.secure) {
42
break;
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
43
}
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
44
if ((value & (1 << 15)) && value & (1 << 0)) {        /* STT */
111
+ }
45
@@ -XXX,XX +XXX,XX @@ static void omap_i2c_write(void *opaque, hwaddr addr,
112
+ if (cur_el > 0 &&
46
s->stat |= 0x3f;
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
47
omap_i2c_interrupts_update(s);
114
+ extract32(env->v7m.nsacr, 10, 1))) {
48
}
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
49
- if (value & (1 << 15))                    /* ST_EN */
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
50
- fprintf(stderr, "%s: System Test not supported\n", __func__);
117
+ }
51
+ if (value & (1 << 15)) { /* ST_EN */
52
+ qemu_log_mask(LOG_UNIMP,
53
+ "%s: System Test not supported\n", __func__);
54
+ }
118
+ }
55
break;
119
break;
56
57
default:
120
default:
121
bad_reg:
58
--
122
--
59
2.17.1
123
2.20.1
60
124
61
125
diff view generated by jsdifflib
1
Allow ARMv8M to handle small MPU and SAU region sizes, by making
1
Currently the code in v7m_push_stack() which detects a violation
2
get_phys_add_pmsav8() set the page size to the 1 if the MPU or
2
of the v8M stack limit simply returns early if it does so. This
3
SAU region covers less than a TARGET_PAGE_SIZE.
3
is OK for the current integer-only code, but won't work for the
4
4
floating point handling we're about to add. We need to continue
5
We choose to use a size of 1 because it makes no difference to
5
executing the rest of the function so that we check for other
6
the core code, and avoids having to track both the base and
6
exceptions like not having permission to use the FPU and so
7
limit for SAU and MPU and then convert into an artificially
7
that we correctly set the FPCCR state if we are doing lazy
8
restricted "page size" that the core code will then ignore.
8
stacking. Refactor to avoid the early return.
9
10
Since the core TCG code can't handle execution from small
11
MPU regions, we strip the exec permission from them so that
12
any execution attempts will cause an MPU exception, rather
13
than allowing it to end up with a cpu_abort() in
14
get_page_addr_code().
15
16
(The previous code's intention was to make any small page be
17
treated as having no permissions, but unfortunately errors
18
in the implementation meant that it didn't behave that way.
19
It's possible that some binaries using small regions were
20
accidentally working with our old behaviour and won't now.)
21
22
We also retain an existing bug, where we ignored the possibility
23
that the SAU region might not cover the entire page, in the
24
case of executable regions. This is necessary because some
25
currently-working guest code images rely on being able to
26
execute from addresses which are covered by a page-sized
27
MPU region but a smaller SAU region. We can remove this
28
workaround if we ever support execution from small regions.
29
9
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20180620130619.11362-4-peter.maydell@linaro.org
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
33
---
13
---
34
target/arm/helper.c | 78 ++++++++++++++++++++++++++++++++-------------
14
target/arm/helper.c | 23 ++++++++++++++++++-----
35
1 file changed, 55 insertions(+), 23 deletions(-)
15
1 file changed, 18 insertions(+), 5 deletions(-)
36
16
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
40
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
41
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
42
22
* should ignore further stack faults trying to process
43
/* Security attributes for an address, as returned by v8m_security_lookup. */
23
* that derived exception.)
44
typedef struct V8M_SAttributes {
45
+ bool subpage; /* true if these attrs don't cover the whole TARGET_PAGE */
46
bool ns;
47
bool nsc;
48
uint8_t sregion;
49
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
50
int r;
51
bool idau_exempt = false, idau_ns = true, idau_nsc = true;
52
int idau_region = IREGION_NOTVALID;
53
+ uint32_t addr_page_base = address & TARGET_PAGE_MASK;
54
+ uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
55
56
if (cpu->idau) {
57
IDAUInterfaceClass *iic = IDAU_INTERFACE_GET_CLASS(cpu->idau);
58
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
59
uint32_t limit = env->sau.rlar[r] | 0x1f;
60
61
if (base <= address && limit >= address) {
62
+ if (base > addr_page_base || limit < addr_page_limit) {
63
+ sattrs->subpage = true;
64
+ }
65
if (sattrs->srvalid) {
66
/* If we hit in more than one region then we must report
67
* as Secure, not NS-Callable, with no valid region
68
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
69
static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
70
MMUAccessType access_type, ARMMMUIdx mmu_idx,
71
hwaddr *phys_ptr, MemTxAttrs *txattrs,
72
- int *prot, ARMMMUFaultInfo *fi, uint32_t *mregion)
73
+ int *prot, bool *is_subpage,
74
+ ARMMMUFaultInfo *fi, uint32_t *mregion)
75
{
76
/* Perform a PMSAv8 MPU lookup (without also doing the SAU check
77
* that a full phys-to-virt translation does).
78
* mregion is (if not NULL) set to the region number which matched,
79
* or -1 if no region number is returned (MPU off, address did not
80
* hit a region, address hit in multiple regions).
81
+ * We set is_subpage to true if the region hit doesn't cover the
82
+ * entire TARGET_PAGE the address is within.
83
*/
24
*/
84
ARMCPU *cpu = arm_env_get_cpu(env);
25
- bool stacked_ok;
85
bool is_user = regime_is_user(env, mmu_idx);
26
+ bool stacked_ok = true, limitviol = false;
86
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
27
CPUARMState *env = &cpu->env;
87
int n;
28
uint32_t xpsr = xpsr_read(env);
88
int matchregion = -1;
29
uint32_t frameptr = env->regs[13];
89
bool hit = false;
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
90
+ uint32_t addr_page_base = address & TARGET_PAGE_MASK;
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
91
+ uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
32
env->v7m.secure);
92
33
env->regs[13] = limit;
93
+ *is_subpage = false;
34
- return true;
94
*phys_ptr = address;
35
+ /*
95
*prot = 0;
36
+ * We won't try to perform any further memory accesses but
96
if (mregion) {
37
+ * we must continue through the following code to check for
97
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
38
+ * permission faults during FPU state preservation, and we
98
continue;
39
+ * must update FPCCR if lazy stacking is enabled.
99
}
40
+ */
100
41
+ limitviol = true;
101
+ if (base > addr_page_base || limit < addr_page_limit) {
42
+ stacked_ok = false;
102
+ *is_subpage = true;
103
+ }
104
+
105
if (hit) {
106
/* Multiple regions match -- always a failure (unlike
107
* PMSAv7 where highest-numbered-region wins)
108
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
109
110
matchregion = n;
111
hit = true;
112
-
113
- if (base & ~TARGET_PAGE_MASK) {
114
- qemu_log_mask(LOG_UNIMP,
115
- "MPU_RBAR[%d]: No support for MPU region base"
116
- "address of 0x%" PRIx32 ". Minimum alignment is "
117
- "%d\n",
118
- n, base, TARGET_PAGE_BITS);
119
- continue;
120
- }
121
- if ((limit + 1) & ~TARGET_PAGE_MASK) {
122
- qemu_log_mask(LOG_UNIMP,
123
- "MPU_RBAR[%d]: No support for MPU region limit"
124
- "address of 0x%" PRIx32 ". Minimum alignment is "
125
- "%d\n",
126
- n, limit, TARGET_PAGE_BITS);
127
- continue;
128
- }
129
}
43
}
130
}
44
}
131
45
132
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
133
47
* (which may be taken in preference to the one we started with
134
fi->type = ARMFault_Permission;
48
* if it has higher priority).
135
fi->level = 1;
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;
136
+ /*
61
+ /*
137
+ * Core QEMU code can't handle execution from small pages yet, so
62
+ * If we broke a stack limit then SP was already updated earlier;
138
+ * don't try it. This means any attempted execution will generate
63
+ * otherwise we update SP regardless of whether any of the stack
139
+ * an MPU exception, rather than eventually causing QEMU to exit in
64
+ * accesses failed or we took some other kind of fault.
140
+ * get_page_addr_code().
141
+ */
65
+ */
142
+ if (*is_subpage && (*prot & PAGE_EXEC)) {
66
+ if (!limitviol) {
143
+ qemu_log_mask(LOG_UNIMP,
67
+ env->regs[13] = frameptr;
144
+ "MPU: No support for execution from regions "
145
+ "smaller than 1K\n");
146
+ *prot &= ~PAGE_EXEC;
147
+ }
68
+ }
148
return !(*prot & (1 << access_type));
69
70
return !stacked_ok;
149
}
71
}
150
151
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
152
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
153
MMUAccessType access_type, ARMMMUIdx mmu_idx,
154
hwaddr *phys_ptr, MemTxAttrs *txattrs,
155
- int *prot, ARMMMUFaultInfo *fi)
156
+ int *prot, target_ulong *page_size,
157
+ ARMMMUFaultInfo *fi)
158
{
159
uint32_t secure = regime_is_secure(env, mmu_idx);
160
V8M_SAttributes sattrs = {};
161
+ bool ret;
162
+ bool mpu_is_subpage;
163
164
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
165
v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
166
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
167
} else {
168
fi->type = ARMFault_QEMU_SFault;
169
}
170
+ *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
171
*phys_ptr = address;
172
*prot = 0;
173
return true;
174
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
175
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
176
*/
177
fi->type = ARMFault_QEMU_SFault;
178
+ *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
179
*phys_ptr = address;
180
*prot = 0;
181
return true;
182
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
183
}
184
}
185
186
- return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
187
- txattrs, prot, fi, NULL);
188
+ ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
189
+ txattrs, prot, &mpu_is_subpage, fi, NULL);
190
+ /*
191
+ * TODO: this is a temporary hack to ignore the fact that the SAU region
192
+ * is smaller than a page if this is an executable region. We never
193
+ * supported small MPU regions, but we did (accidentally) allow small
194
+ * SAU regions, and if we now made small SAU regions not be executable
195
+ * then this would break previously working guest code. We can't
196
+ * remove this until/unless we implement support for execution from
197
+ * small regions.
198
+ */
199
+ if (*prot & PAGE_EXEC) {
200
+ sattrs.subpage = false;
201
+ }
202
+ *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
203
+ return ret;
204
}
205
206
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
207
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
208
if (arm_feature(env, ARM_FEATURE_V8)) {
209
/* PMSAv8 */
210
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
211
- phys_ptr, attrs, prot, fi);
212
+ phys_ptr, attrs, prot, page_size, fi);
213
} else if (arm_feature(env, ARM_FEATURE_V7)) {
214
/* PMSAv7 */
215
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
216
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
217
uint32_t mregion;
218
bool targetpriv;
219
bool targetsec = env->v7m.secure;
220
+ bool is_subpage;
221
222
/* Work out what the security state and privilege level we're
223
* interested in is...
224
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
225
if (arm_current_el(env) != 0 || alt) {
226
/* We can ignore the return value as prot is always set */
227
pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
228
- &phys_addr, &attrs, &prot, &fi, &mregion);
229
+ &phys_addr, &attrs, &prot, &is_subpage,
230
+ &fi, &mregion);
231
if (mregion == -1) {
232
mrvalid = false;
233
mregion = 0;
234
--
72
--
235
2.17.1
73
2.20.1
236
74
237
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: Cédric Le Goater <clg@kaod.org>
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
Also handle the fake transfers for dummy bytes in this setup
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
routine. It will be useful when we activate MMIO execution.
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
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Message-id: 20180612065716.10587-4-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/ssi/aspeed_smc.c | 31 ++++++++++++++++---------------
12
1 file changed, 16 insertions(+), 15 deletions(-)
13
14
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/aspeed_smc.c
16
--- a/target/arm/cpu.h
17
+++ b/hw/ssi/aspeed_smc.c
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
19
return dummies;
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
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;
20
}
45
}
21
46
22
-static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
23
+static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr)
48
+{
24
{
49
+ /*
25
const AspeedSMCState *s = fl->controller;
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
26
uint8_t cmd = aspeed_smc_flash_cmd(fl);
51
+ * configured at a priority which would allow it to interrupt the
27
+ int i;
52
+ * current execution priority.
28
53
+ *
29
/* Flash access can not exceed CS segment */
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
30
addr = aspeed_smc_check_segment_addr(fl, addr);
55
+ * for non-banked exceptions secure is always false; for banked exceptions
31
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
56
+ * it indicates which of the exceptions is required.
32
ssi_transfer(s->spi, (addr >> 16) & 0xff);
57
+ */
33
ssi_transfer(s->spi, (addr >> 8) & 0xff);
58
+ NVICState *s = (NVICState *)opaque;
34
ssi_transfer(s->spi, (addr & 0xff));
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
35
+
65
+
36
+ /*
66
+ /*
37
+ * Use fake transfers to model dummy bytes. The value should
67
+ * HardFault is an odd special case: we always check against -1,
38
+ * be configured to some non-zero value in fast read mode and
68
+ * even if we're secure and HardFault has priority -3; we never
39
+ * zero in read mode. But, as the HW allows inconsistent
69
+ * need to check for enabled state.
40
+ * settings, let's check for fast read mode.
41
+ */
70
+ */
42
+ if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
71
+ if (irq == ARMV7M_EXCP_HARD) {
43
+ for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
72
+ return running > -1;
44
+ ssi_transfer(fl->controller->spi, 0xFF);
45
+ }
46
+ }
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
80
+
81
/* callback when external interrupt line is changed */
82
static void set_irq_level(void *opaque, int n, int level)
83
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
47
}
90
}
48
91
49
static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
50
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size)
93
+ bool apply_splim)
51
case CTRL_READMODE:
94
+{
52
case CTRL_FREADMODE:
95
+ /*
53
aspeed_smc_flash_select(fl);
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
54
- aspeed_smc_flash_send_addr(fl, addr);
97
+ * that we will need later in order to do lazy FP reg stacking.
55
-
98
+ */
56
- /*
99
+ bool is_secure = env->v7m.secure;
57
- * Use fake transfers to model dummy bytes. The value should
100
+ void *nvic = env->nvic;
58
- * be configured to some non-zero value in fast read mode and
101
+ /*
59
- * zero in read mode. But, as the HW allows inconsistent
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
60
- * settings, let's check for fast read mode.
103
+ * are banked and we want to update the bit in the bank for the
61
- */
104
+ * current security state; and in one case we want to specifically
62
- if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) {
105
+ * update the NS banked version of a bit even if we are secure.
63
- for (i = 0; i < aspeed_smc_flash_dummies(fl); i++) {
106
+ */
64
- ssi_transfer(fl->controller->spi, 0xFF);
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
65
- }
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
66
- }
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
67
+ aspeed_smc_flash_setup(fl, addr);
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
68
111
+
69
for (i = 0; i < size; i++) {
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
70
ret |= ssi_transfer(s->spi, 0x0) << (8 * i);
113
+
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data,
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
72
break;
115
+ bool splimviol;
73
case CTRL_WRITEMODE:
116
+ uint32_t splim = v7m_sp_limit(env);
74
aspeed_smc_flash_select(fl);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
75
- aspeed_smc_flash_send_addr(fl, addr);
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
76
+ aspeed_smc_flash_setup(fl, addr);
119
+
77
120
+ splimviol = !ign && frameptr < splim;
78
for (i = 0; i < size; i++) {
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
79
ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
122
+ }
123
+
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
125
+
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
155
+}
156
+
157
static bool v7m_push_stack(ARMCPU *cpu)
158
{
159
/* Do the "set up stack frame" part of exception entry,
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
161
}
162
} else {
163
/* Lazy stacking enabled, save necessary info to stack later */
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
166
}
167
}
168
}
80
--
169
--
81
2.17.1
170
2.20.1
82
171
83
172
diff view generated by jsdifflib
1
We want to handle small MPU region sizes for ARMv7M. To do this,
1
For v8M floating point support, transitions from Secure
2
make get_phys_addr_pmsav7() set the page size to the region
2
to Non-secure state via BLNS and BLXNS must clear the
3
size if it is less that TARGET_PAGE_SIZE, rather than working
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
only in TARGET_PAGE_SIZE chunks.
4
BranchToNS() function.)
5
6
Since the core TCG code con't handle execution from small
7
MPU regions, we strip the exec permission from them so that
8
any execution attempts will cause an MPU exception, rather
9
than allowing it to end up with a cpu_abort() in
10
get_page_addr_code().
11
12
(The previous code's intention was to make any small page be
13
treated as having no permissions, but unfortunately errors
14
in the implementation meant that it didn't behave that way.
15
It's possible that some binaries using small regions were
16
accidentally working with our old behaviour and won't now.)
17
5
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20180620130619.11362-3-peter.maydell@linaro.org
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
21
---
9
---
22
target/arm/helper.c | 37 ++++++++++++++++++++++++++-----------
10
target/arm/helper.c | 4 ++++
23
1 file changed, 26 insertions(+), 11 deletions(-)
11
1 file changed, 4 insertions(+)
24
12
25
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
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
28
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
30
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
18
/* translate.c should have made BXNS UNDEF unless we're secure */
31
MMUAccessType access_type, ARMMMUIdx mmu_idx,
19
assert(env->v7m.secure);
32
hwaddr *phys_ptr, int *prot,
20
33
+ target_ulong *page_size,
21
+ if (!(dest & 1)) {
34
ARMMMUFaultInfo *fi)
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
35
{
36
ARMCPU *cpu = arm_env_get_cpu(env);
37
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
38
bool is_user = regime_is_user(env, mmu_idx);
39
40
*phys_ptr = address;
41
+ *page_size = TARGET_PAGE_SIZE;
42
*prot = 0;
43
44
if (regime_translation_disabled(env, mmu_idx) ||
45
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
46
rsize++;
47
}
48
}
49
- if (rsize < TARGET_PAGE_BITS) {
50
- qemu_log_mask(LOG_UNIMP,
51
- "DRSR[%d]: No support for MPU (sub)region size of"
52
- " %" PRIu32 " bytes. Minimum is %d.\n",
53
- n, (1 << rsize), TARGET_PAGE_SIZE);
54
- continue;
55
- }
56
if (srdis) {
57
continue;
58
}
59
+ if (rsize < TARGET_PAGE_BITS) {
60
+ *page_size = 1 << rsize;
61
+ }
62
break;
63
}
64
65
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
66
67
fi->type = ARMFault_Permission;
68
fi->level = 1;
69
+ /*
70
+ * Core QEMU code can't handle execution from small pages yet, so
71
+ * don't try it. This way we'll get an MPU exception, rather than
72
+ * eventually causing QEMU to exit in get_page_addr_code().
73
+ */
74
+ if (*page_size < TARGET_PAGE_SIZE && (*prot & PAGE_EXEC)) {
75
+ qemu_log_mask(LOG_UNIMP,
76
+ "MPU: No support for execution from regions "
77
+ "smaller than 1K\n");
78
+ *prot &= ~PAGE_EXEC;
79
+ }
23
+ }
80
return !(*prot & (1 << access_type));
24
switch_v7m_security_state(env, dest & 1);
81
}
25
env->thumb = 1;
82
26
env->regs[15] = dest & ~1;
83
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
84
} else if (arm_feature(env, ARM_FEATURE_V7)) {
28
*/
85
/* PMSAv7 */
29
write_v7m_exception(env, 1);
86
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
30
}
87
- phys_ptr, prot, fi);
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
88
+ phys_ptr, prot, page_size, fi);
32
switch_v7m_security_state(env, 0);
89
} else {
33
env->thumb = 1;
90
/* Pre-v7 MPU */
34
env->regs[15] = dest;
91
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
92
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
93
core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
94
&attrs, &prot, &page_size, fi, NULL);
95
if (!ret) {
96
- /* Map a single [sub]page. */
97
- phys_addr &= TARGET_PAGE_MASK;
98
- address &= TARGET_PAGE_MASK;
99
+ /*
100
+ * Map a single [sub]page. Regions smaller than our declared
101
+ * target page size are handled specially, so for those we
102
+ * pass in the exact addresses.
103
+ */
104
+ if (page_size >= TARGET_PAGE_SIZE) {
105
+ phys_addr &= TARGET_PAGE_MASK;
106
+ address &= TARGET_PAGE_MASK;
107
+ }
108
tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
109
prot, mmu_idx, page_size);
110
return 0;
111
--
35
--
112
2.17.1
36
2.20.1
113
37
114
38
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
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
When configured in dual I/O mode, address and data are sent in dual
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
mode, including the dummy byte cycles in between. Adapt the count to
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the IO setting.
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 8 ++++++++
11
1 file changed, 8 insertions(+)
6
12
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
8
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
9
Message-id: 20180612065716.10587-2-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/aspeed_smc.c | 9 ++++++++-
13
1 file changed, 8 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/aspeed_smc.c
15
--- a/target/arm/helper.c
18
+++ b/hw/ssi/aspeed_smc.c
16
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
20
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
21
/* CEx Control Register */
19
targets_secure ? "secure" : "nonsecure", exc);
22
#define R_CTRL0 (0x10 / 4)
20
23
+#define CTRL_IO_DUAL_DATA (1 << 29)
21
+ if (dotailchain) {
24
+#define CTRL_IO_DUAL_ADDR_DATA (1 << 28) /* Includes dummies */
22
+ /* Sanitize LR FType and PREFIX bits */
25
#define CTRL_CMD_SHIFT 16
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
26
#define CTRL_CMD_MASK 0xff
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
27
#define CTRL_DUMMY_HIGH_SHIFT 14
25
+ }
28
@@ -XXX,XX +XXX,XX @@ static int aspeed_smc_flash_dummies(const AspeedSMCFlash *fl)
26
+ lr = deposit32(lr, 24, 8, 0xff);
29
uint32_t r_ctrl0 = s->regs[s->r_ctrl0 + fl->id];
30
uint32_t dummy_high = (r_ctrl0 >> CTRL_DUMMY_HIGH_SHIFT) & 0x1;
31
uint32_t dummy_low = (r_ctrl0 >> CTRL_DUMMY_LOW_SHIFT) & 0x3;
32
+ uint32_t dummies = ((dummy_high << 2) | dummy_low) * 8;
33
34
- return ((dummy_high << 2) | dummy_low) * 8;
35
+ if (r_ctrl0 & CTRL_IO_DUAL_ADDR_DATA) {
36
+ dummies /= 2;
37
+ }
27
+ }
38
+
28
+
39
+ return dummies;
29
if (arm_feature(env, ARM_FEATURE_V8)) {
40
}
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
41
31
(lr & R_V7M_EXCRET_S_MASK)) {
42
static void aspeed_smc_flash_send_addr(AspeedSMCFlash *fl, uint32_t addr)
43
--
32
--
44
2.17.1
33
2.20.1
45
34
46
35
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The magic value pushed onto the callee stack as an integrity
2
check is different if floating point is present.
2
3
3
TCMI_VERBOSE is no more used, drop the OMAP_8/16/32B_REG macros.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
1 file changed, 19 insertions(+), 3 deletions(-)
4
10
5
Suggested-by: Thomas Huth <thuth@redhat.com>
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Message-id: 20180624040609.17572-9-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/omap.h | 18 ------------------
12
hw/arm/omap1.c | 18 ++++++++++++------
13
2 files changed, 12 insertions(+), 24 deletions(-)
14
15
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/omap.h
13
--- a/target/arm/helper.c
18
+++ b/include/hw/arm/omap.h
14
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ enum {
15
@@ -XXX,XX +XXX,XX @@ load_fail:
20
#define OMAP_GPIOSW_INVERTED    0x0001
16
return false;
21
#define OMAP_GPIOSW_OUTPUT    0x0002
17
}
22
18
23
-# define TCMI_VERBOSE            1
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
24
-
25
-# ifdef TCMI_VERBOSE
26
-# define OMAP_8B_REG(paddr)        \
27
- fprintf(stderr, "%s: 8-bit register " OMAP_FMT_plx "\n",    \
28
- __func__, paddr)
29
-# define OMAP_16B_REG(paddr)        \
30
- fprintf(stderr, "%s: 16-bit register " OMAP_FMT_plx "\n",    \
31
- __func__, paddr)
32
-# define OMAP_32B_REG(paddr)        \
33
- fprintf(stderr, "%s: 32-bit register " OMAP_FMT_plx "\n",    \
34
- __func__, paddr)
35
-# else
36
-# define OMAP_8B_REG(paddr)
37
-# define OMAP_16B_REG(paddr)
38
-# define OMAP_32B_REG(paddr)
39
-# endif
40
-
41
# define OMAP_MPUI_REG_MASK        0x000007ff
42
43
#endif /* hw_omap_h */
44
diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/omap1.c
47
+++ b/hw/arm/omap1.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "qemu/cutils.h"
50
#include "qemu/bcd.h"
51
52
+static inline void omap_log_badwidth(const char *funcname, hwaddr addr, int sz)
53
+{
20
+{
54
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: %d-bit register %#08" HWADDR_PRIx "\n",
21
+ /*
55
+ funcname, 8 * sz, addr);
22
+ * Return the integrity signature value for the callee-saves
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
+ }
31
+ return sig;
56
+}
32
+}
57
+
33
+
58
/* Should signal the TCMI/GPMC */
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
59
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr)
35
bool ignore_faults)
60
{
36
{
61
uint8_t ret;
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
62
38
bool stacked_ok;
63
- OMAP_8B_REG(addr);
39
uint32_t limit;
64
+ omap_log_badwidth(__func__, addr, 1);
40
bool want_psp;
65
cpu_physical_memory_read(addr, &ret, 1);
41
+ uint32_t sig;
66
return ret;
42
67
}
43
if (dotailchain) {
68
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write8(void *opaque, hwaddr addr,
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
69
{
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
70
uint8_t val8 = value;
46
/* Write as much of the stack frame as we can. A write failure may
71
47
* cause us to pend a derived exception.
72
- OMAP_8B_REG(addr);
48
*/
73
+ omap_log_badwidth(__func__, addr, 1);
49
+ sig = v7m_integrity_sig(env, lr);
74
cpu_physical_memory_write(addr, &val8, 1);
50
stacked_ok =
75
}
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
76
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
77
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read16(void *opaque, hwaddr addr)
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
78
{
54
ignore_faults) &&
79
uint16_t ret;
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
80
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
81
- OMAP_16B_REG(addr);
57
if (return_to_secure &&
82
+ omap_log_badwidth(__func__, addr, 2);
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
83
cpu_physical_memory_read(addr, &ret, 2);
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
84
return ret;
60
- uint32_t expected_sig = 0xfefa125b;
85
}
61
uint32_t actual_sig;
86
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write16(void *opaque, hwaddr addr,
62
87
{
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
88
uint16_t val16 = value;
64
89
65
- if (pop_ok && expected_sig != actual_sig) {
90
- OMAP_16B_REG(addr);
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
91
+ omap_log_badwidth(__func__, addr, 2);
67
/* Take a SecureFault on the current stack */
92
cpu_physical_memory_write(addr, &val16, 2);
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
93
}
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
94
95
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
96
{
97
uint32_t ret;
98
99
- OMAP_32B_REG(addr);
100
+ omap_log_badwidth(__func__, addr, 4);
101
cpu_physical_memory_read(addr, &ret, 4);
102
return ret;
103
}
104
@@ -XXX,XX +XXX,XX @@ uint32_t omap_badwidth_read32(void *opaque, hwaddr addr)
105
void omap_badwidth_write32(void *opaque, hwaddr addr,
106
uint32_t value)
107
{
108
- OMAP_32B_REG(addr);
109
+ omap_log_badwidth(__func__, addr, 4);
110
cpu_physical_memory_write(addr, &value, 4);
111
}
112
113
--
70
--
114
2.17.1
71
2.20.1
115
72
116
73
diff view generated by jsdifflib
1
Add support for MMU protection regions that are smaller than
1
Handle floating point registers in exception return.
2
TARGET_PAGE_SIZE. We do this by marking the TLB entry for those
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
pages with a flag TLB_RECHECK. This flag causes us to always
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
take the slow-path for accesses. In the slow path we can then
5
special case them to always call tlb_fill() again, so we have
6
the correct information for the exact address being accessed.
7
8
This change allows us to handle reading and writing from small
9
regions; we cannot deal with execution from the small region.
10
4
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180620130619.11362-2-peter.maydell@linaro.org
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
14
---
8
---
15
accel/tcg/softmmu_template.h | 24 ++++---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
16
include/exec/cpu-all.h | 5 +-
10
1 file changed, 141 insertions(+), 1 deletion(-)
17
accel/tcg/cputlb.c | 131 +++++++++++++++++++++++++++++------
18
3 files changed, 130 insertions(+), 30 deletions(-)
19
11
20
diff --git a/accel/tcg/softmmu_template.h b/accel/tcg/softmmu_template.h
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/accel/tcg/softmmu_template.h
14
--- a/target/arm/helper.c
23
+++ b/accel/tcg/softmmu_template.h
15
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
25
static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState *env,
17
bool rettobase = false;
26
size_t mmu_idx, size_t index,
18
bool exc_secure = false;
27
target_ulong addr,
19
bool return_to_secure;
28
- uintptr_t retaddr)
20
+ bool ftype;
29
+ uintptr_t retaddr,
21
+ bool restore_s16_s31;
30
+ bool recheck)
22
31
{
23
/* If we're not in Handler mode then jumps to magic exception-exit
32
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
24
* addresses don't have magic behaviour. However for the v8M
33
- return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, DATA_SIZE);
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
34
+ return io_readx(env, iotlbentry, mmu_idx, addr, retaddr, recheck,
26
excret);
35
+ DATA_SIZE);
36
}
37
#endif
38
39
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_le_ld_name(CPUArchState *env, target_ulong addr,
40
41
/* ??? Note that the io helpers always read data in the target
42
byte ordering. We should push the LE/BE request down into io. */
43
- res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
44
+ res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
45
+ tlb_addr & TLB_RECHECK);
46
res = TGT_LE(res);
47
return res;
48
}
27
}
49
@@ -XXX,XX +XXX,XX @@ WORD_TYPE helper_be_ld_name(CPUArchState *env, target_ulong addr,
28
50
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
51
/* ??? Note that the io helpers always read data in the target
52
byte ordering. We should push the LE/BE request down into io. */
53
- res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr);
54
+ res = glue(io_read, SUFFIX)(env, mmu_idx, index, addr, retaddr,
55
+ tlb_addr & TLB_RECHECK);
56
res = TGT_BE(res);
57
return res;
58
}
59
@@ -XXX,XX +XXX,XX @@ static inline void glue(io_write, SUFFIX)(CPUArchState *env,
60
size_t mmu_idx, size_t index,
61
DATA_TYPE val,
62
target_ulong addr,
63
- uintptr_t retaddr)
64
+ uintptr_t retaddr,
65
+ bool recheck)
66
{
67
CPUIOTLBEntry *iotlbentry = &env->iotlb[mmu_idx][index];
68
- return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr, DATA_SIZE);
69
+ return io_writex(env, iotlbentry, mmu_idx, val, addr, retaddr,
70
+ recheck, DATA_SIZE);
71
}
72
73
void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
74
@@ -XXX,XX +XXX,XX @@ void helper_le_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
75
/* ??? Note that the io helpers always read data in the target
76
byte ordering. We should push the LE/BE request down into io. */
77
val = TGT_LE(val);
78
- glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
79
+ glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr,
80
+ retaddr, tlb_addr & TLB_RECHECK);
81
return;
82
}
83
84
@@ -XXX,XX +XXX,XX @@ void helper_be_st_name(CPUArchState *env, target_ulong addr, DATA_TYPE val,
85
/* ??? Note that the io helpers always read data in the target
86
byte ordering. We should push the LE/BE request down into io. */
87
val = TGT_BE(val);
88
- glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr);
89
+ glue(io_write, SUFFIX)(env, mmu_idx, index, val, addr, retaddr,
90
+ tlb_addr & TLB_RECHECK);
91
return;
92
}
93
94
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
95
index XXXXXXX..XXXXXXX 100644
96
--- a/include/exec/cpu-all.h
97
+++ b/include/exec/cpu-all.h
98
@@ -XXX,XX +XXX,XX @@ CPUArchState *cpu_copy(CPUArchState *env);
99
#define TLB_NOTDIRTY (1 << (TARGET_PAGE_BITS - 2))
100
/* Set if TLB entry is an IO callback. */
101
#define TLB_MMIO (1 << (TARGET_PAGE_BITS - 3))
102
+/* Set if TLB entry must have MMU lookup repeated for every access */
103
+#define TLB_RECHECK (1 << (TARGET_PAGE_BITS - 4))
104
105
/* Use this mask to check interception with an alignment mask
106
* in a TCG backend.
107
*/
108
-#define TLB_FLAGS_MASK (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO)
109
+#define TLB_FLAGS_MASK (TLB_INVALID_MASK | TLB_NOTDIRTY | TLB_MMIO \
110
+ | TLB_RECHECK)
111
112
void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
113
void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf);
114
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/accel/tcg/cputlb.c
117
+++ b/accel/tcg/cputlb.c
118
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
119
target_ulong code_address;
120
uintptr_t addend;
121
CPUTLBEntry *te, *tv, tn;
122
- hwaddr iotlb, xlat, sz;
123
+ hwaddr iotlb, xlat, sz, paddr_page;
124
+ target_ulong vaddr_page;
125
unsigned vidx = env->vtlb_index++ % CPU_VTLB_SIZE;
126
int asidx = cpu_asidx_from_attrs(cpu, attrs);
127
128
assert_cpu_is_self(cpu);
129
- assert(size >= TARGET_PAGE_SIZE);
130
- if (size != TARGET_PAGE_SIZE) {
131
- tlb_add_large_page(env, vaddr, size);
132
- }
133
134
- sz = size;
135
- section = address_space_translate_for_iotlb(cpu, asidx, paddr, &xlat, &sz,
136
- attrs, &prot);
137
+ if (size < TARGET_PAGE_SIZE) {
138
+ sz = TARGET_PAGE_SIZE;
139
+ } else {
140
+ if (size > TARGET_PAGE_SIZE) {
141
+ tlb_add_large_page(env, vaddr, size);
142
+ }
143
+ sz = size;
144
+ }
145
+ vaddr_page = vaddr & TARGET_PAGE_MASK;
146
+ paddr_page = paddr & TARGET_PAGE_MASK;
147
+
30
+
148
+ section = address_space_translate_for_iotlb(cpu, asidx, paddr_page,
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
149
+ &xlat, &sz, attrs, &prot);
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
150
assert(sz >= TARGET_PAGE_SIZE);
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
151
34
+ "if FPU not present\n",
152
tlb_debug("vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx
35
+ excret);
153
" prot=%x idx=%d\n",
36
+ ftype = true;
154
vaddr, paddr, prot, mmu_idx);
155
156
- address = vaddr;
157
- if (!memory_region_is_ram(section->mr) && !memory_region_is_romd(section->mr)) {
158
+ address = vaddr_page;
159
+ if (size < TARGET_PAGE_SIZE) {
160
+ /*
161
+ * Slow-path the TLB entries; we will repeat the MMU check and TLB
162
+ * fill on every access.
163
+ */
164
+ address |= TLB_RECHECK;
165
+ }
166
+ if (!memory_region_is_ram(section->mr) &&
167
+ !memory_region_is_romd(section->mr)) {
168
/* IO memory case */
169
address |= TLB_MMIO;
170
addend = 0;
171
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
172
}
173
174
code_address = address;
175
- iotlb = memory_region_section_get_iotlb(cpu, section, vaddr, paddr, xlat,
176
- prot, &address);
177
+ iotlb = memory_region_section_get_iotlb(cpu, section, vaddr_page,
178
+ paddr_page, xlat, prot, &address);
179
180
- index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
181
+ index = (vaddr_page >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
182
te = &env->tlb_table[mmu_idx][index];
183
/* do not discard the translation in te, evict it into a victim tlb */
184
tv = &env->tlb_v_table[mmu_idx][vidx];
185
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
186
* TARGET_PAGE_BITS, and either
187
* + the ram_addr_t of the page base of the target RAM (if NOTDIRTY or ROM)
188
* + the offset within section->mr of the page base (otherwise)
189
- * We subtract the vaddr (which is page aligned and thus won't
190
+ * We subtract the vaddr_page (which is page aligned and thus won't
191
* disturb the low bits) to give an offset which can be added to the
192
* (non-page-aligned) vaddr of the eventual memory access to get
193
* the MemoryRegion offset for the access. Note that the vaddr we
194
* subtract here is that of the page base, and not the same as the
195
* vaddr we add back in io_readx()/io_writex()/get_page_addr_code().
196
*/
197
- env->iotlb[mmu_idx][index].addr = iotlb - vaddr;
198
+ env->iotlb[mmu_idx][index].addr = iotlb - vaddr_page;
199
env->iotlb[mmu_idx][index].attrs = attrs;
200
201
/* Now calculate the new entry */
202
- tn.addend = addend - vaddr;
203
+ tn.addend = addend - vaddr_page;
204
if (prot & PAGE_READ) {
205
tn.addr_read = address;
206
} else {
207
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
208
tn.addr_write = address | TLB_MMIO;
209
} else if (memory_region_is_ram(section->mr)
210
&& cpu_physical_memory_is_clean(
211
- memory_region_get_ram_addr(section->mr) + xlat)) {
212
+ memory_region_get_ram_addr(section->mr) + xlat)) {
213
tn.addr_write = address | TLB_NOTDIRTY;
214
} else {
215
tn.addr_write = address;
216
@@ -XXX,XX +XXX,XX @@ static inline ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
217
218
static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
219
int mmu_idx,
220
- target_ulong addr, uintptr_t retaddr, int size)
221
+ target_ulong addr, uintptr_t retaddr,
222
+ bool recheck, int size)
223
{
224
CPUState *cpu = ENV_GET_CPU(env);
225
hwaddr mr_offset;
226
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
227
bool locked = false;
228
MemTxResult r;
229
230
+ if (recheck) {
231
+ /*
232
+ * This is a TLB_RECHECK access, where the MMU protection
233
+ * covers a smaller range than a target page, and we must
234
+ * repeat the MMU check here. This tlb_fill() call might
235
+ * longjump out if this access should cause a guest exception.
236
+ */
237
+ int index;
238
+ target_ulong tlb_addr;
239
+
240
+ tlb_fill(cpu, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
241
+
242
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
243
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_read;
244
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
245
+ /* RAM access */
246
+ uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
247
+
248
+ return ldn_p((void *)haddr, size);
249
+ }
250
+ /* Fall through for handling IO accesses */
251
+ }
37
+ }
252
+
38
+
253
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
254
mr = section->mr;
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
255
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
41
* we pick which FAULTMASK to clear.
256
@@ -XXX,XX +XXX,XX @@ static uint64_t io_readx(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
257
static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
43
*/
258
int mmu_idx,
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
259
uint64_t val, target_ulong addr,
45
260
- uintptr_t retaddr, int size)
46
+ /*
261
+ uintptr_t retaddr, bool recheck, int size)
47
+ * Clear scratch FP values left in caller saved registers; this
262
{
48
+ * must happen before any kind of tail chaining.
263
CPUState *cpu = ENV_GET_CPU(env);
49
+ */
264
hwaddr mr_offset;
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
265
@@ -XXX,XX +XXX,XX @@ static void io_writex(CPUArchState *env, CPUIOTLBEntry *iotlbentry,
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
266
bool locked = false;
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
267
MemTxResult r;
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
268
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
269
+ if (recheck) {
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
270
+ /*
56
+ "stackframe: error during lazy state deactivation\n");
271
+ * This is a TLB_RECHECK access, where the MMU protection
57
+ v7m_exception_taken(cpu, excret, true, false);
272
+ * covers a smaller range than a target page, and we must
58
+ return;
273
+ * repeat the MMU check here. This tlb_fill() call might
59
+ } else {
274
+ * longjump out if this access should cause a guest exception.
60
+ /* Clear s0..s15 and FPSCR */
275
+ */
61
+ int i;
276
+ int index;
277
+ target_ulong tlb_addr;
278
+
62
+
279
+ tlb_fill(cpu, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
63
+ for (i = 0; i < 16; i += 2) {
280
+
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
281
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
65
+ }
282
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_write;
66
+ vfp_set_fpscr(env, 0);
283
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
284
+ /* RAM access */
285
+ uintptr_t haddr = addr + env->tlb_table[mmu_idx][index].addend;
286
+
287
+ stn_p((void *)haddr, size, val);
288
+ return;
289
+ }
67
+ }
290
+ /* Fall through for handling IO accesses */
291
+ }
68
+ }
292
+
69
+
293
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
70
if (sfault) {
294
mr = section->mr;
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
295
mr_offset = (iotlbentry->addr & TARGET_PAGE_MASK) + addr;
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
296
@@ -XXX,XX +XXX,XX @@ tb_page_addr_t get_page_addr_code(CPUArchState *env, target_ulong addr)
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
297
tlb_fill(ENV_GET_CPU(env), addr, 0, MMU_INST_FETCH, mmu_idx, 0);
74
}
298
}
75
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
299
}
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));
300
+
185
+
301
+ if (unlikely(env->tlb_table[mmu_idx][index].addr_code & TLB_RECHECK)) {
186
+ if (env->v7m.secure) {
302
+ /*
187
+ bool sfpa = xpsr & XPSR_SFPA;
303
+ * This is a TLB_RECHECK access, where the MMU protection
304
+ * covers a smaller range than a target page, and we must
305
+ * repeat the MMU check here. This tlb_fill() call might
306
+ * longjump out if this access should cause a guest exception.
307
+ */
308
+ int index;
309
+ target_ulong tlb_addr;
310
+
188
+
311
+ tlb_fill(cpu, addr, 0, MMU_INST_FETCH, mmu_idx, 0);
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
312
+
190
+ V7M_CONTROL, SFPA, sfpa);
313
+ index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
314
+ tlb_addr = env->tlb_table[mmu_idx][index].addr_code;
315
+ if (!(tlb_addr & ~(TARGET_PAGE_MASK | TLB_RECHECK))) {
316
+ /* RAM access. We can't handle this, so for now just stop */
317
+ cpu_abort(cpu, "Unable to handle guest executing from RAM within "
318
+ "a small MPU region at 0x" TARGET_FMT_lx, addr);
319
+ }
320
+ /*
321
+ * Fall through to handle IO accesses (which will almost certainly
322
+ * also result in failure)
323
+ */
324
+ }
191
+ }
325
+
192
326
iotlbentry = &env->iotlb[mmu_idx][index];
193
/* The restored xPSR exception field will be zero if we're
327
section = iotlb_to_section(cpu, iotlbentry->addr, iotlbentry->attrs);
194
* resuming in Thread mode. If that doesn't match what the
328
mr = section->mr;
329
@@ -XXX,XX +XXX,XX @@ static void *atomic_mmu_lookup(CPUArchState *env, target_ulong addr,
330
tlb_addr = tlbe->addr_write & ~TLB_INVALID_MASK;
331
}
332
333
- /* Notice an IO access */
334
- if (unlikely(tlb_addr & TLB_MMIO)) {
335
+ /* Notice an IO access or a needs-MMU-lookup access */
336
+ if (unlikely(tlb_addr & (TLB_MMIO | TLB_RECHECK))) {
337
/* There's really nothing that can be done to
338
support this apart from stop-the-world. */
339
goto stop_the_world;
340
--
195
--
341
2.17.1
196
2.20.1
342
197
343
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
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
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Implement this by adding a new TB flag which tracks whether
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
FPCCR.S is different from the current security state, so
5
Message-id: 20180624040609.17572-6-f4bug@amsat.org
9
that we only need to emit the code to update it in the
10
less-common case when it is not already set correctly.
11
12
Note that we will add the handling for the other work done
13
by ExecuteFPCheck() in later commits.
14
6
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
7
---
18
---
8
hw/ssi/omap_spi.c | 15 ++++++++++-----
19
target/arm/cpu.h | 2 ++
9
1 file changed, 10 insertions(+), 5 deletions(-)
20
target/arm/translate.h | 1 +
21
target/arm/helper.c | 5 +++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
10
24
11
diff --git a/hw/ssi/omap_spi.c b/hw/ssi/omap_spi.c
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/ssi/omap_spi.c
27
--- a/target/arm/cpu.h
14
+++ b/hw/ssi/omap_spi.c
28
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
16
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
17
*/
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
18
#include "qemu/osdep.h"
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
19
+#include "qemu/log.h"
33
+/* For M profile only, set if FPCCR.S does not match current security state */
20
#include "hw/hw.h"
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
21
#include "hw/arm/omap.h"
35
/* For M profile only, Handler (ie not Thread) mode */
22
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
23
@@ -XXX,XX +XXX,XX @@ static void omap_mcspi_write(void *opaque, hwaddr addr,
37
/* For M profile only, whether we should generate stack-limit checks */
24
case 0x2c:    /* MCSPI_CHCONF */
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
25
if ((value ^ s->ch[ch].config) & (3 << 14))    /* DMAR | DMAW */
39
index XXXXXXX..XXXXXXX 100644
26
omap_mcspi_dmarequest_update(s->ch + ch);
40
--- a/target/arm/translate.h
27
- if (((value >> 12) & 3) == 3)            /* TRM */
41
+++ b/target/arm/translate.h
28
- fprintf(stderr, "%s: invalid TRM value (3)\n", __func__);
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
29
- if (((value >> 7) & 0x1f) < 3)            /* WL */
43
bool v7m_handler_mode;
30
- fprintf(stderr, "%s: invalid WL value (%" PRIx64 ")\n",
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
31
- __func__, (value >> 7) & 0x1f);
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
32
+ if (((value >> 12) & 3) == 3) { /* TRM */
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
33
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid TRM value (3)\n",
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
34
+ __func__);
48
* so that top level loop can generate correct syndrome information.
49
*/
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/helper.c
53
+++ b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
56
}
57
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
61
+ }
62
+
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 */
76
+
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
78
+ if (s->v8m_fpccr_s_wrong) {
79
+ TCGv_i32 tmp;
80
+
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
82
+ if (s->v8m_secure) {
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
84
+ } else {
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
86
+ }
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
88
+ /* Don't need to do this for any further FP insns in this TB */
89
+ s->v8m_fpccr_s_wrong = false;
35
+ }
90
+ }
36
+ if (((value >> 7) & 0x1f) < 3) { /* WL */
91
+ }
37
+ qemu_log_mask(LOG_GUEST_ERROR,
92
+
38
+ "%s: invalid WL value (%" PRIx64 ")\n",
93
if (extract32(insn, 28, 4) == 0xf) {
39
+ __func__, (value >> 7) & 0x1f);
94
/*
40
+ }
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
41
s->ch[ch].config = value & 0x7fffff;
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
42
break;
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
98
regime_is_secure(env, dc->mmu_idx);
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
101
dc->cp_regs = cpu->cp_regs;
102
dc->features = env->features;
43
103
44
--
104
--
45
2.17.1
105
2.20.1
46
106
47
107
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
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().
2
8
3
Only the flash type is strapped by HW. The 4BYTE mode is set by
9
Implement this with a new TB flag which tracks whether we
4
firmware when the flash device is detected.
10
need to create a new FP context.
5
11
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
8
Message-id: 20180612065716.10587-3-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
10
---
15
---
11
hw/ssi/aspeed_smc.c | 8 +-------
16
target/arm/cpu.h | 2 ++
12
1 file changed, 1 insertion(+), 7 deletions(-)
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
13
21
14
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/aspeed_smc.c
24
--- a/target/arm/cpu.h
17
+++ b/hw/ssi/aspeed_smc.c
25
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
19
aspeed_smc_segment_to_reg(&s->ctrl->segments[i]);
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);
20
}
53
}
21
54
22
- /* HW strapping for AST2500 FMC controllers */
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
23
+ /* HW strapping flash type for FMC controllers */
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
24
if (s->ctrl->segments == aspeed_segments_ast2500_fmc) {
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
25
/* flash type is fixed to SPI for CE0 and CE1 */
58
+ (env->v7m.secure &&
26
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
27
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE1);
60
+ /*
28
-
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
29
- /* 4BYTE mode is autodetected for CE0. Let's force it to 1 for
62
+ * FP context; we must create a new FP context before executing
30
- * now */
63
+ * any FP insn.
31
- s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
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
+ }
32
}
106
}
33
107
34
/* HW strapping for AST2400 FMC controllers (SCU70). Let's use the
108
if (extract32(insn, 28, 4) == 0xf) {
35
* configuration of the palmetto-bmc machine */
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
36
if (s->ctrl->segments == aspeed_segments_fmc) {
110
regime_is_secure(env, dc->mmu_idx);
37
s->regs[s->r_conf] |= (CONF_FLASH_TYPE_SPI << CONF_FLASH_TYPE0);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
38
-
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
39
- s->regs[s->r_ce_ctrl] |= (1 << (CTRL_EXTENDED0));
113
+ dc->v7m_new_fp_ctxt_needed =
40
}
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
41
}
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
42
117
43
--
118
--
44
2.17.1
119
2.20.1
45
120
46
121
diff view generated by jsdifflib
1
From: Jia He <hejianet@gmail.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
In case the STE's config is "Bypass" we currently don't set the
7
We are going to need this for the lazy-FP-stacking code.
4
IOMMUTLBEntry perm flags and the access does not succeed. Also
5
if the config is 0b0xx (Aborted/Reserved), decode_ste and
6
smmuv3_decode_config currently returns -EINVAL and we don't enter
7
the expected code path: we record an event whereas we should not.
8
8
9
This patch fixes those bugs and simplifies the error handling.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
decode_ste and smmuv3_decode_config now return 0 if aborted or
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
bypassed config was found. Only bad config info produces negative
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
12
error values. In smmuv3_translate we more clearly differentiate
12
---
13
errors, bypass/smmu disabled, aborted and success cases. Also
13
target/arm/cpu.h | 7 +++++++
14
trace points are differentiated.
14
target/arm/helper.c | 14 +++++++++++---
15
2 files changed, 18 insertions(+), 3 deletions(-)
15
16
16
Fixes: 9bde7f0674fe ("hw/arm/smmuv3: Implement translate callback")
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
Reported-by: jia.he@hxt-semitech.com
18
Signed-off-by: jia.he@hxt-semitech.com
19
Signed-off-by: Eric Auger <eric.auger@redhat.com>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 1529653501-15358-2-git-send-email-eric.auger@redhat.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
hw/arm/smmuv3-internal.h | 12 ++++-
25
hw/arm/smmuv3.c | 96 +++++++++++++++++++++++++++-------------
26
hw/arm/trace-events | 7 +--
27
3 files changed, 80 insertions(+), 35 deletions(-)
28
29
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/smmuv3-internal.h
19
--- a/target/arm/cpu.h
32
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
34
22
}
35
#include "hw/arm/smmu-common.h"
23
}
36
24
37
+typedef enum SMMUTranslationStatus {
25
+/*
38
+ SMMU_TRANS_DISABLE,
26
+ * Return the MMU index for a v7M CPU with all relevant information
39
+ SMMU_TRANS_ABORT,
27
+ * manually specified.
40
+ SMMU_TRANS_BYPASS,
28
+ */
41
+ SMMU_TRANS_ERROR,
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
42
+ SMMU_TRANS_SUCCESS,
30
+ bool secstate, bool priv, bool negpri);
43
+} SMMUTranslationStatus;
44
+
31
+
45
/* MMIO Registers */
32
/* Return the MMU index for a v7M CPU in the specified security and
46
33
* privilege state.
47
REG32(IDR0, 0x0)
34
*/
48
@@ -XXX,XX +XXX,XX @@ enum { /* Command completion notification */
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
/* Events */
50
51
typedef enum SMMUEventType {
52
- SMMU_EVT_OK = 0x00,
53
+ SMMU_EVT_NONE = 0x00,
54
SMMU_EVT_F_UUT ,
55
SMMU_EVT_C_BAD_STREAMID ,
56
SMMU_EVT_F_STE_FETCH ,
57
@@ -XXX,XX +XXX,XX @@ typedef enum SMMUEventType {
58
} SMMUEventType;
59
60
static const char *event_stringify[] = {
61
- [SMMU_EVT_OK] = "SMMU_EVT_OK",
62
+ [SMMU_EVT_NONE] = "no recorded event",
63
[SMMU_EVT_F_UUT] = "SMMU_EVT_F_UUT",
64
[SMMU_EVT_C_BAD_STREAMID] = "SMMU_EVT_C_BAD_STREAMID",
65
[SMMU_EVT_F_STE_FETCH] = "SMMU_EVT_F_STE_FETCH",
66
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
67
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/smmuv3.c
37
--- a/target/arm/helper.c
69
+++ b/hw/arm/smmuv3.c
38
+++ b/target/arm/helper.c
70
@@ -XXX,XX +XXX,XX @@
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
71
#include "hw/qdev-core.h"
72
#include "hw/pci/pci.h"
73
#include "exec/address-spaces.h"
74
+#include "cpu.h"
75
#include "trace.h"
76
#include "qemu/log.h"
77
#include "qemu/error-report.h"
78
@@ -XXX,XX +XXX,XX @@ void smmuv3_record_event(SMMUv3State *s, SMMUEventInfo *info)
79
EVT_SET_SID(&evt, info->sid);
80
81
switch (info->type) {
82
- case SMMU_EVT_OK:
83
+ case SMMU_EVT_NONE:
84
return;
85
case SMMU_EVT_F_UUT:
86
EVT_SET_SSID(&evt, info->u.f_uut.ssid);
87
@@ -XXX,XX +XXX,XX @@ static int smmu_get_cd(SMMUv3State *s, STE *ste, uint32_t ssid,
88
return 0;
40
return 0;
89
}
41
}
90
42
91
-/* Returns <0 if the caller has no need to continue the translation */
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
92
+/* Returns < 0 in case of invalid STE, 0 otherwise */
44
- bool secstate, bool priv)
93
static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
94
STE *ste, SMMUEventInfo *event)
46
+ bool secstate, bool priv, bool negpri)
95
{
47
{
96
uint32_t config;
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
97
- int ret = -EINVAL;
49
98
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
99
if (!STE_VALID(ste)) {
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
100
goto bad_ste;
101
@@ -XXX,XX +XXX,XX @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
102
config = STE_CONFIG(ste);
103
104
if (STE_CFG_ABORT(config)) {
105
- cfg->aborted = true; /* abort but don't record any event */
106
- return ret;
107
+ cfg->aborted = true;
108
+ return 0;
109
}
52
}
110
53
111
if (STE_CFG_BYPASS(config)) {
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
112
cfg->bypassed = true;
55
+ if (negpri) {
113
- return ret;
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
114
+ return 0;
115
}
57
}
116
58
117
if (STE_CFG_S2_ENABLED(config)) {
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
118
@@ -XXX,XX +XXX,XX @@ bad_cd:
60
return mmu_idx;
119
* the different configuration decoding steps
61
}
120
* @event: must be zero'ed by the caller
62
121
*
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
122
- * return < 0 if the translation needs to be aborted (@event is filled
64
+ bool secstate, bool priv)
123
+ * return < 0 in case of config decoding error (@event is filled
65
+{
124
* accordingly). Return 0 otherwise.
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
125
*/
126
static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
127
@@ -XXX,XX +XXX,XX @@ static int smmuv3_decode_config(IOMMUMemoryRegion *mr, SMMUTransCfg *cfg,
128
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
129
uint32_t sid = smmu_get_sid(sdev);
130
SMMUv3State *s = sdev->smmu;
131
- int ret = -EINVAL;
132
+ int ret;
133
STE ste;
134
CD cd;
135
136
- if (smmu_find_ste(s, sid, &ste, event)) {
137
+ ret = smmu_find_ste(s, sid, &ste, event);
138
+ if (ret) {
139
return ret;
140
}
141
142
- if (decode_ste(s, cfg, &ste, event)) {
143
+ ret = decode_ste(s, cfg, &ste, event);
144
+ if (ret) {
145
return ret;
146
}
147
148
- if (smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event)) {
149
+ if (cfg->aborted || cfg->bypassed) {
150
+ return 0;
151
+ }
152
+
67
+
153
+ ret = smmu_get_cd(s, &ste, 0 /* ssid */, &cd, event);
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
154
+ if (ret) {
69
+}
155
return ret;
156
}
157
158
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
159
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
160
SMMUv3State *s = sdev->smmu;
161
uint32_t sid = smmu_get_sid(sdev);
162
- SMMUEventInfo event = {.type = SMMU_EVT_OK, .sid = sid};
163
+ SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
164
SMMUPTWEventInfo ptw_info = {};
165
+ SMMUTranslationStatus status;
166
SMMUTransCfg cfg = {};
167
IOMMUTLBEntry entry = {
168
.target_as = &address_space_memory,
169
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
170
.addr_mask = ~(hwaddr)0,
171
.perm = IOMMU_NONE,
172
};
173
- int ret = 0;
174
175
if (!smmu_enabled(s)) {
176
- goto out;
177
+ status = SMMU_TRANS_DISABLE;
178
+ goto epilogue;
179
}
180
181
- ret = smmuv3_decode_config(mr, &cfg, &event);
182
- if (ret) {
183
- goto out;
184
+ if (smmuv3_decode_config(mr, &cfg, &event)) {
185
+ status = SMMU_TRANS_ERROR;
186
+ goto epilogue;
187
}
188
189
if (cfg.aborted) {
190
- goto out;
191
+ status = SMMU_TRANS_ABORT;
192
+ goto epilogue;
193
}
194
195
- ret = smmu_ptw(&cfg, addr, flag, &entry, &ptw_info);
196
- if (ret) {
197
+ if (cfg.bypassed) {
198
+ status = SMMU_TRANS_BYPASS;
199
+ goto epilogue;
200
+ }
201
+
70
+
202
+ if (smmu_ptw(&cfg, addr, flag, &entry, &ptw_info)) {
71
/* Return the MMU index for a v7M CPU in the specified security state */
203
switch (ptw_info.type) {
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
204
case SMMU_PTW_ERR_WALK_EABT:
73
{
205
event.type = SMMU_EVT_F_WALK_EABT;
206
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
207
default:
208
g_assert_not_reached();
209
}
210
+ status = SMMU_TRANS_ERROR;
211
+ } else {
212
+ status = SMMU_TRANS_SUCCESS;
213
}
214
-out:
215
- if (ret) {
216
- qemu_log_mask(LOG_GUEST_ERROR,
217
- "%s translation failed for iova=0x%"PRIx64"(%d)\n",
218
- mr->parent_obj.name, addr, ret);
219
- entry.perm = IOMMU_NONE;
220
- smmuv3_record_event(s, &event);
221
- } else if (!cfg.aborted) {
222
+
223
+epilogue:
224
+ switch (status) {
225
+ case SMMU_TRANS_SUCCESS:
226
entry.perm = flag;
227
- trace_smmuv3_translate(mr->parent_obj.name, sid, addr,
228
- entry.translated_addr, entry.perm);
229
+ trace_smmuv3_translate_success(mr->parent_obj.name, sid, addr,
230
+ entry.translated_addr, entry.perm);
231
+ break;
232
+ case SMMU_TRANS_DISABLE:
233
+ entry.perm = flag;
234
+ entry.addr_mask = ~TARGET_PAGE_MASK;
235
+ trace_smmuv3_translate_disable(mr->parent_obj.name, sid, addr,
236
+ entry.perm);
237
+ break;
238
+ case SMMU_TRANS_BYPASS:
239
+ entry.perm = flag;
240
+ entry.addr_mask = ~TARGET_PAGE_MASK;
241
+ trace_smmuv3_translate_bypass(mr->parent_obj.name, sid, addr,
242
+ entry.perm);
243
+ break;
244
+ case SMMU_TRANS_ABORT:
245
+ /* no event is recorded on abort */
246
+ trace_smmuv3_translate_abort(mr->parent_obj.name, sid, addr,
247
+ entry.perm);
248
+ break;
249
+ case SMMU_TRANS_ERROR:
250
+ qemu_log_mask(LOG_GUEST_ERROR,
251
+ "%s translation failed for iova=0x%"PRIx64"(%s)\n",
252
+ mr->parent_obj.name, addr, smmu_event_string(event.type));
253
+ smmuv3_record_event(s, &event);
254
+ break;
255
}
256
257
return entry;
258
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
259
index XXXXXXX..XXXXXXX 100644
260
--- a/hw/arm/trace-events
261
+++ b/hw/arm/trace-events
262
@@ -XXX,XX +XXX,XX @@ smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
263
smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
264
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%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
265
smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
266
-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"
267
-smmuv3_translate_in(uint16_t sid, int pci_bus_num, uint64_t strtab_base) "SID:0x%x bus:%d strtab_base:0x%"PRIx64
268
+smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
269
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d STE bypass iova:0x%"PRIx64" is_write=%d"
270
+smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d abort on iova:0x%"PRIx64" is_write=%d"
271
+smmuv3_translate_success(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"
272
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
273
-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"
274
smmuv3_decode_cd(uint32_t oas) "oas=%d"
275
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"
276
--
74
--
277
2.17.1
75
2.20.1
278
76
279
77
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
In the v7M architecture, if an exception is generated in the process
2
of doing the lazy stacking of FP registers, the handling of
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.
2
9
3
All Aspeed SoC clocks are driven by an input source clock which can
10
This corresponds to the pseudocode TakePreserveFPException().
4
have different frequencies : 24MHz or 25MHz, and also, on the Aspeed
5
AST2400 SoC, 48MHz. The H-PLL (CPU) clock is defined from a
6
calculation using parameters in the H-PLL Parameter register or from a
7
predefined set of frequencies if the setting is strapped by hardware
8
(Aspeed AST2400 SoC). The other clocks of the SoC are then defined
9
from the H-PLL using dividers.
10
11
11
We introduce first the APB clock because it should be used to drive
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
the Aspeed timer model.
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 12 ++++++
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
18
2 files changed, 108 insertions(+)
13
19
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
16
Message-id: 20180622075700.5923-2-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/misc/aspeed_scu.h | 70 +++++++++++++++++++++--
20
hw/misc/aspeed_scu.c | 106 +++++++++++++++++++++++++++++++++++
21
2 files changed, 172 insertions(+), 4 deletions(-)
22
23
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
24
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/misc/aspeed_scu.h
22
--- a/target/arm/cpu.h
26
+++ b/include/hw/misc/aspeed_scu.h
23
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
28
uint32_t hw_strap1;
25
* a different exception).
29
uint32_t hw_strap2;
26
*/
30
uint32_t hw_prot_key;
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);
49
}
50
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
52
+{
53
+ /*
54
+ * Pend an exception during lazy FP stacking. This differs
55
+ * from the usual exception pending because the logic for
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
59
+ NVICState *s = (NVICState *)opaque;
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
31
+
71
+
32
+ uint32_t clkin;
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
33
+ uint32_t hpll;
73
+ assert(!secure || banked);
34
+ uint32_t apb_freq;
35
} AspeedSCUState;
36
37
#define AST2400_A0_SILICON_REV 0x02000303U
38
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
39
* 1. 2012/12/29 Ryan Chen Create
40
*/
41
42
-/* Hardware Strapping Register definition (for Aspeed AST2400 SOC)
43
+/* SCU08 Clock Selection Register
44
+ *
45
+ * 31 Enable Video Engine clock dynamic slow down
46
+ * 30:28 Video Engine clock slow down setting
47
+ * 27 2D Engine GCLK clock source selection
48
+ * 26 2D Engine GCLK clock throttling enable
49
+ * 25:23 APB PCLK divider selection
50
+ * 22:20 LPC Host LHCLK divider selection
51
+ * 19 LPC Host LHCLK clock generation/output enable control
52
+ * 18:16 MAC AHB bus clock divider selection
53
+ * 15 SD/SDIO clock running enable
54
+ * 14:12 SD/SDIO divider selection
55
+ * 11 Reserved
56
+ * 10:8 Video port output clock delay control bit
57
+ * 7 ARM CPU/AHB clock slow down enable
58
+ * 6:4 ARM CPU/AHB clock slow down setting
59
+ * 3:2 ECLK clock source selection
60
+ * 1 CPU/AHB clock slow down idle timer
61
+ * 0 CPU/AHB clock dynamic slow down enable (defined in bit[6:4])
62
+ */
63
+#define SCU_CLK_GET_PCLK_DIV(x) (((x) >> 23) & 0x7)
64
+
74
+
65
+/* SCU24 H-PLL Parameter Register (for Aspeed AST2400 SOC)
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
66
+ *
67
+ * 18 H-PLL parameter selection
68
+ * 0: Select H-PLL by strapping resistors
69
+ * 1: Select H-PLL by the programmed registers (SCU24[17:0])
70
+ * 17 Enable H-PLL bypass mode
71
+ * 16 Turn off H-PLL
72
+ * 10:5 H-PLL Numerator
73
+ * 4 H-PLL Output Divider
74
+ * 3:0 H-PLL Denumerator
75
+ *
76
+ * (Output frequency) = 24MHz * (2-OD) * [(Numerator+2) / (Denumerator+1)]
77
+ */
78
+
76
+
79
+#define SCU_AST2400_H_PLL_PROGRAMMED (0x1 << 18)
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
80
+#define SCU_AST2400_H_PLL_BYPASS_EN (0x1 << 17)
81
+#define SCU_AST2400_H_PLL_OFF (0x1 << 16)
82
+
78
+
83
+/* SCU24 H-PLL Parameter Register (for Aspeed AST2500 SOC)
79
+ switch (irq) {
84
+ *
80
+ case ARMV7M_EXCP_DEBUG:
85
+ * 21 Enable H-PLL reset
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
86
+ * 20 Enable H-PLL bypass mode
82
+ /* Ignore DebugMonitor exception */
87
+ * 19 Turn off H-PLL
83
+ return;
88
+ * 18:13 H-PLL Post Divider
84
+ }
89
+ * 12:5 H-PLL Numerator (M)
90
+ * 4:0 H-PLL Denumerator (N)
91
+ *
92
+ * (Output frequency) = CLKIN(24MHz) * [(M+1) / (N+1)] / (P+1)
93
+ *
94
+ * The default frequency is 792Mhz when CLKIN = 24MHz
95
+ */
96
+
97
+#define SCU_H_PLL_BYPASS_EN (0x1 << 20)
98
+#define SCU_H_PLL_OFF (0x1 << 19)
99
+
100
+/* SCU70 Hardware Strapping Register definition (for Aspeed AST2400 SOC)
101
*
102
* 31:29 Software defined strapping registers
103
* 28:27 DRAM size setting (for VGA driver use)
104
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
105
#define SCU_AST2400_HW_STRAP_GET_CLK_SOURCE(x) (((((x) >> 23) & 0x1) << 1) \
106
| (((x) >> 18) & 0x1))
107
#define SCU_AST2400_HW_STRAP_CLK_SOURCE_MASK ((0x1 << 23) | (0x1 << 18))
108
-#define AST2400_CLK_25M_IN (0x1 << 23)
109
+#define SCU_HW_STRAP_CLK_25M_IN (0x1 << 23)
110
#define AST2400_CLK_24M_IN 0
111
#define AST2400_CLK_48M_IN 1
112
#define AST2400_CLK_25M_IN_24M_USB_CKI 2
113
#define AST2400_CLK_25M_IN_48M_USB_CKI 3
114
115
+#define SCU_HW_STRAP_CLK_48M_IN (0x1 << 18)
116
#define SCU_HW_STRAP_2ND_BOOT_WDT (0x1 << 17)
117
#define SCU_HW_STRAP_SUPER_IO_CONFIG (0x1 << 16)
118
#define SCU_HW_STRAP_VGA_CLASS_CODE (0x1 << 15)
119
@@ -XXX,XX +XXX,XX @@ extern bool is_supported_silicon_rev(uint32_t silicon_rev);
120
#define AST2400_DIS_BOOT 3
121
122
/*
123
- * Hardware strapping register definition (for Aspeed AST2500 SoC and
124
- * higher)
125
+ * SCU70 Hardware strapping register definition (for Aspeed AST2500
126
+ * SoC and higher)
127
*
128
* 31 Enable SPI Flash Strap Auto Fetch Mode
129
* 30 Enable GPIO Strap Mode
130
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/hw/misc/aspeed_scu.c
133
+++ b/hw/misc/aspeed_scu.c
134
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_get_random(void)
135
return num;
136
}
137
138
+static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
139
+{
140
+ uint32_t apb_divider;
141
+
142
+ switch (s->silicon_rev) {
143
+ case AST2400_A0_SILICON_REV:
144
+ case AST2400_A1_SILICON_REV:
145
+ apb_divider = 2;
146
+ break;
85
+ break;
147
+ case AST2500_A0_SILICON_REV:
86
+ case ARMV7M_EXCP_MEM:
148
+ case AST2500_A1_SILICON_REV:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
149
+ apb_divider = 4;
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
150
+ break;
97
+ break;
151
+ default:
98
+ default:
152
+ g_assert_not_reached();
99
+ g_assert_not_reached();
153
+ }
100
+ }
154
+
101
+
155
+ s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
102
+ if (escalate) {
156
+ / apb_divider;
103
+ /*
157
+}
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
+ }
158
+
116
+
159
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
117
+ if (!vec->enabled ||
160
{
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
161
AspeedSCUState *s = ASPEED_SCU(opaque);
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
162
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
120
+ /*
163
case PROT_KEY:
121
+ * We want to escalate to HardFault but the context the
164
s->regs[reg] = (data == ASPEED_SCU_PROT_KEY) ? 1 : 0;
122
+ * FP state belongs to prevents the exception pre-empting.
165
return;
123
+ */
166
+ case CLK_SEL:
124
+ cpu_abort(&s->cpu->parent_obj,
167
+ s->regs[reg] = data;
125
+ "Lockup: can't escalate to HardFault during "
168
+ aspeed_scu_set_apb_freq(s);
126
+ "lazy FP register stacking\n");
169
+ break;
127
+ }
170
128
+ }
171
case FREQ_CNTR_EVAL:
129
+
172
case VGA_SCRATCH1 ... VGA_SCRATCH8:
130
+ if (escalate) {
173
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_scu_ops = {
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
174
.valid.unaligned = false,
132
+ }
175
};
133
+ if (!vec->pending) {
176
134
+ vec->pending = 1;
177
+static uint32_t aspeed_scu_get_clkin(AspeedSCUState *s)
135
+ /*
178
+{
136
+ * We do not call nvic_irq_update(), because we know our caller
179
+ if (s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN) {
137
+ * is going to handle causing us to take the exception by
180
+ return 25000000;
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
181
+ } else if (s->hw_strap1 & SCU_HW_STRAP_CLK_48M_IN) {
139
+ * pointless extra work. We just need to recompute the
182
+ return 48000000;
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
183
+ } else {
141
+ * returns the right answer.
184
+ return 24000000;
142
+ */
143
+ nvic_recompute_state(s);
185
+ }
144
+ }
186
+}
145
+}
187
+
146
+
188
+/*
147
/* Make pending IRQ active. */
189
+ * Strapped frequencies for the AST2400 in MHz. They depend on the
148
void armv7m_nvic_acknowledge_irq(void *opaque)
190
+ * clkin frequency.
191
+ */
192
+static const uint32_t hpll_ast2400_freqs[][4] = {
193
+ { 384, 360, 336, 408 }, /* 24MHz or 48MHz */
194
+ { 400, 375, 350, 425 }, /* 25MHz */
195
+};
196
+
197
+static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
198
+{
199
+ uint32_t hpll_reg = s->regs[HPLL_PARAM];
200
+ uint8_t freq_select;
201
+ bool clk_25m_in;
202
+
203
+ if (hpll_reg & SCU_AST2400_H_PLL_OFF) {
204
+ return 0;
205
+ }
206
+
207
+ if (hpll_reg & SCU_AST2400_H_PLL_PROGRAMMED) {
208
+ uint32_t multiplier = 1;
209
+
210
+ if (!(hpll_reg & SCU_AST2400_H_PLL_BYPASS_EN)) {
211
+ uint32_t n = (hpll_reg >> 5) & 0x3f;
212
+ uint32_t od = (hpll_reg >> 4) & 0x1;
213
+ uint32_t d = hpll_reg & 0xf;
214
+
215
+ multiplier = (2 - od) * ((n + 2) / (d + 1));
216
+ }
217
+
218
+ return s->clkin * multiplier;
219
+ }
220
+
221
+ /* HW strapping */
222
+ clk_25m_in = !!(s->hw_strap1 & SCU_HW_STRAP_CLK_25M_IN);
223
+ freq_select = SCU_AST2400_HW_STRAP_GET_H_PLL_CLK(s->hw_strap1);
224
+
225
+ return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
226
+}
227
+
228
+static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
229
+{
230
+ uint32_t hpll_reg = s->regs[HPLL_PARAM];
231
+ uint32_t multiplier = 1;
232
+
233
+ if (hpll_reg & SCU_H_PLL_OFF) {
234
+ return 0;
235
+ }
236
+
237
+ if (!(hpll_reg & SCU_H_PLL_BYPASS_EN)) {
238
+ uint32_t p = (hpll_reg >> 13) & 0x3f;
239
+ uint32_t m = (hpll_reg >> 5) & 0xff;
240
+ uint32_t n = hpll_reg & 0x1f;
241
+
242
+ multiplier = ((m + 1) / (n + 1)) / (p + 1);
243
+ }
244
+
245
+ return s->clkin * multiplier;
246
+}
247
+
248
static void aspeed_scu_reset(DeviceState *dev)
249
{
149
{
250
AspeedSCUState *s = ASPEED_SCU(dev);
251
const uint32_t *reset;
252
+ uint32_t (*calc_hpll)(AspeedSCUState *s);
253
254
switch (s->silicon_rev) {
255
case AST2400_A0_SILICON_REV:
256
case AST2400_A1_SILICON_REV:
257
reset = ast2400_a0_resets;
258
+ calc_hpll = aspeed_scu_calc_hpll_ast2400;
259
break;
260
case AST2500_A0_SILICON_REV:
261
case AST2500_A1_SILICON_REV:
262
reset = ast2500_a1_resets;
263
+ calc_hpll = aspeed_scu_calc_hpll_ast2500;
264
break;
265
default:
266
g_assert_not_reached();
267
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_reset(DeviceState *dev)
268
s->regs[HW_STRAP1] = s->hw_strap1;
269
s->regs[HW_STRAP2] = s->hw_strap2;
270
s->regs[PROT_KEY] = s->hw_prot_key;
271
+
272
+ /*
273
+ * All registers are set. Now compute the frequencies of the main clocks
274
+ */
275
+ s->clkin = aspeed_scu_get_clkin(s);
276
+ s->hpll = calc_hpll(s);
277
+ aspeed_scu_set_apb_freq(s);
278
}
279
280
static uint32_t aspeed_silicon_revs[] = {
281
--
150
--
282
2.17.1
151
2.20.1
283
152
284
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
New patch
1
1
The M-profile architecture floating point system supports
2
lazy FP state preservation, where FP registers are not
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
11
---
12
target/arm/cpu.h | 3 ++
13
target/arm/helper.h | 2 +
14
target/arm/translate.h | 1 +
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
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();
71
}
72
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
74
+{
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)
80
{
81
/* The TT instructions can be used by unprivileged code, but in
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
83
return false;
84
}
85
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
87
+{
88
+ /*
89
+ * Preserve FP state (because LSPACT was set and we are about
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
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;
215
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
217
index XXXXXXX..XXXXXXX 100644
218
--- a/target/arm/translate.c
219
+++ b/target/arm/translate.c
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
222
/* Handle M-profile lazy FP state mechanics */
223
224
+ /* Trigger lazy-state preservation if necessary */
225
+ if (s->v7m_lspact) {
226
+ /*
227
+ * Lazy state saving affects external memory and also the NVIC,
228
+ * so we must mark it as an IO operation for icount.
229
+ */
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
231
+ gen_io_start();
232
+ }
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
235
+ gen_io_end();
236
+ }
237
+ /*
238
+ * If the preserve_fp_state helper doesn't throw an exception
239
+ * then it will clear LSPACT; we don't need to repeat this for
240
+ * any further FP insns in this TB.
241
+ */
242
+ s->v7m_lspact = false;
243
+ }
244
+
245
/* Update ownership of FP context: set FPCCR.S to match current state */
246
if (s->v8m_fpccr_s_wrong) {
247
TCGv_i32 tmp;
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
250
dc->v7m_new_fp_ctxt_needed =
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
253
dc->cp_regs = cpu->cp_regs;
254
dc->features = env->features;
255
256
--
257
2.20.1
258
259
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Implement the VLSTM instruction for v7M for the FPU present case.
2
2
3
The timer controller can be driven by either an external 1MHz clock or
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
by the APB clock. Today, the model makes the assumption that the APB
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
frequency is always set to 24MHz but this is incorrect.
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 AST2400 SoC on the palmetto machines uses a 48MHz input clock
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
8
source and the APB can be set to 48MHz. The consequence is a general
9
system slowdown. The QEMU machines using the AST2500 SoC do not seem
10
impacted today because the APB frequency is still set to 24MHz.
11
12
We fix the timer frequency for all SoCs by linking the Timer model to
13
the SCU model. The APB frequency driving the timers is now the one
14
configured for the SoC.
15
16
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
Reviewed-by: Joel Stanley <joel@jms.id.au>
18
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
19
Message-id: 20180622075700.5923-4-clg@kaod.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
include/hw/timer/aspeed_timer.h | 4 ++++
23
hw/arm/aspeed_soc.c | 2 ++
24
hw/timer/aspeed_timer.c | 19 +++++++++++++++----
25
3 files changed, 21 insertions(+), 4 deletions(-)
26
27
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
28
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/timer/aspeed_timer.h
15
--- a/target/arm/cpu.h
30
+++ b/include/hw/timer/aspeed_timer.h
16
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
32
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
33
#include "qemu/timer.h"
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
34
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
35
+typedef struct AspeedSCUState AspeedSCUState;
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)
36
+
35
+
37
#define ASPEED_TIMER(obj) \
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
38
OBJECT_CHECK(AspeedTimerCtrlState, (obj), TYPE_ASPEED_TIMER);
37
39
#define TYPE_ASPEED_TIMER "aspeed.timer"
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedTimerCtrlState {
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
uint32_t ctrl;
40
index XXXXXXX..XXXXXXX 100644
42
uint32_t ctrl2;
41
--- a/target/arm/helper.c
43
AspeedTimer timers[ASPEED_TIMER_NR_TIMERS];
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
44
g_assert_not_reached();
45
}
46
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
48
+{
49
+ /* translate.c should never generate calls here in user-only mode */
50
+ g_assert_not_reached();
51
+}
44
+
52
+
45
+ AspeedSCUState *scu;
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
46
} AspeedTimerCtrlState;
54
{
47
55
/* The TT instructions can be used by unprivileged code, but in
48
#endif /* ASPEED_TIMER_H */
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
49
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
57
}
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed_soc.c
52
+++ b/hw/arm/aspeed_soc.c
53
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
54
55
object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
56
object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
57
+ object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
58
+ OBJECT(&s->scu), &error_abort);
59
qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
60
61
object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
62
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/timer/aspeed_timer.c
65
+++ b/hw/timer/aspeed_timer.c
66
@@ -XXX,XX +XXX,XX @@
67
*/
68
69
#include "qemu/osdep.h"
70
+#include "qapi/error.h"
71
#include "hw/sysbus.h"
72
#include "hw/timer/aspeed_timer.h"
73
+#include "hw/misc/aspeed_scu.h"
74
#include "qemu-common.h"
75
#include "qemu/bitops.h"
76
#include "qemu/timer.h"
77
@@ -XXX,XX +XXX,XX @@
78
#define TIMER_CLOCK_USE_EXT true
79
#define TIMER_CLOCK_EXT_HZ 1000000
80
#define TIMER_CLOCK_USE_APB false
81
-#define TIMER_CLOCK_APB_HZ 24000000
82
83
#define TIMER_REG_STATUS 0
84
#define TIMER_REG_RELOAD 1
85
@@ -XXX,XX +XXX,XX @@ static inline bool timer_external_clock(AspeedTimer *t)
86
return timer_ctrl_status(t, op_external_clock);
87
}
58
}
88
59
89
-static uint32_t clock_rates[] = { TIMER_CLOCK_APB_HZ, TIMER_CLOCK_EXT_HZ };
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
90
-
61
+{
91
static inline uint32_t calculate_rate(struct AspeedTimer *t)
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
92
{
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
93
- return clock_rates[timer_external_clock(t)];
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
94
+ AspeedTimerCtrlState *s = timer_to_ctrl(t);
95
+
65
+
96
+ return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
66
+ assert(env->v7m.secure);
97
}
98
99
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
100
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
101
int i;
102
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
103
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
104
+ Object *obj;
105
+ Error *err = NULL;
106
+
67
+
107
+ obj = object_property_get_link(OBJECT(dev), "scu", &err);
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
108
+ if (!obj) {
109
+ error_propagate(errp, err);
110
+ error_prepend(errp, "required link 'scu' not found: ");
111
+ return;
69
+ return;
112
+ }
70
+ }
113
+ s->scu = ASPEED_SCU(obj);
71
+
114
72
+ /* Check access to the coprocessor is permitted */
115
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
116
aspeed_init_one_timer(s, i);
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
85
+
86
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
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.
92
+ */
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;
96
+
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;
126
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
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
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
117
--
181
--
118
2.17.1
182
2.20.1
119
183
120
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
On TLB invalidation commands, let's call registered
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
IOMMU notifiers. Those can only be UNMAP notifiers.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
SMMUv3 does not support notification on MAP (VFIO).
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(-)
6
11
7
This patch allows vhost use case where IOTLB API is notified
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
8
on each guest IOTLB invalidation.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1529653501-15358-5-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/smmu-common.h | 6 +++
16
hw/arm/smmu-common.c | 34 +++++++++++++
17
hw/arm/smmuv3.c | 99 +++++++++++++++++++++++++++++++++++-
18
hw/arm/trace-events | 5 ++
19
4 files changed, 142 insertions(+), 2 deletions(-)
20
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
14
--- a/target/arm/helper.h
24
+++ b/include/hw/arm/smmu-common.h
15
+++ b/target/arm/helper.h
25
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_all(SMMUState *s);
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
26
void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid);
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
27
void smmu_iotlb_inv_iova(SMMUState *s, uint16_t asid, dma_addr_t iova);
18
28
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
29
+/* Unmap the range of all the notifiers registered to any IOMMU mr */
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
30
+void smmu_inv_notifiers_all(SMMUState *s);
21
31
+
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
32
+/* Unmap the range of all the notifiers registered to @mr */
23
33
+void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr);
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
+
35
#endif /* HW_ARM_SMMU_COMMON */
36
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
37
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/smmu-common.c
26
--- a/target/arm/helper.c
39
+++ b/hw/arm/smmu-common.c
27
+++ b/target/arm/helper.c
40
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_iotlb_key_equal(gconstpointer v1, gconstpointer v2)
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
41
return (k1->asid == k2->asid) && (k1->iova == k2->iova);
29
g_assert_not_reached();
42
}
30
}
43
31
44
+/* Unmap the whole notifier's range */
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
45
+static void smmu_unmap_notifier_range(IOMMUNotifier *n)
46
+{
33
+{
47
+ IOMMUTLBEntry entry;
34
+ /* translate.c should never generate calls here in user-only mode */
48
+
35
+ g_assert_not_reached();
49
+ entry.target_as = &address_space_memory;
50
+ entry.iova = n->start;
51
+ entry.perm = IOMMU_NONE;
52
+ entry.addr_mask = n->end - n->start;
53
+
54
+ memory_region_notify_one(n, &entry);
55
+}
36
+}
56
+
37
+
57
+/* Unmap all notifiers attached to @mr */
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
58
+inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
59
+{
46
+{
60
+ IOMMUNotifier *n;
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
48
+ assert(env->v7m.secure);
61
+
49
+
62
+ trace_smmu_inv_notifiers_mr(mr->parent_obj.name);
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
63
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
64
+ smmu_unmap_notifier_range(n);
65
+ }
66
+}
67
+
68
+/* Unmap all notifiers of all mr's */
69
+void smmu_inv_notifiers_all(SMMUState *s)
70
+{
71
+ SMMUNotifierNode *node;
72
+
73
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
74
+ smmu_inv_notifiers_mr(&node->sdev->iommu);
75
+ }
76
+}
77
+
78
static void smmu_base_realize(DeviceState *dev, Error **errp)
79
{
80
SMMUState *s = ARM_SMMU(dev);
81
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/smmuv3.c
84
+++ b/hw/arm/smmuv3.c
85
@@ -XXX,XX +XXX,XX @@ epilogue:
86
return entry;
87
}
88
89
+/**
90
+ * smmuv3_notify_iova - call the notifier @n for a given
91
+ * @asid and @iova tuple.
92
+ *
93
+ * @mr: IOMMU mr region handle
94
+ * @n: notifier to be called
95
+ * @asid: address space ID or negative value if we don't care
96
+ * @iova: iova
97
+ */
98
+static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
99
+ IOMMUNotifier *n,
100
+ int asid,
101
+ dma_addr_t iova)
102
+{
103
+ SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
104
+ SMMUEventInfo event = {};
105
+ SMMUTransTableInfo *tt;
106
+ SMMUTransCfg *cfg;
107
+ IOMMUTLBEntry entry;
108
+
109
+ cfg = smmuv3_get_config(sdev, &event);
110
+ if (!cfg) {
111
+ qemu_log_mask(LOG_GUEST_ERROR,
112
+ "%s error decoding the configuration for iommu mr=%s\n",
113
+ __func__, mr->parent_obj.name);
114
+ return;
51
+ return;
115
+ }
52
+ }
116
+
53
+
117
+ if (asid >= 0 && cfg->asid != asid) {
54
+ /* Check access to the coprocessor is permitted */
118
+ return;
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
119
+ }
57
+ }
120
+
58
+
121
+ tt = select_tt(cfg, iova);
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
122
+ if (!tt) {
60
+ /* State in FP is still valid */
123
+ return;
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);
124
+ }
88
+ }
125
+
89
+
126
+ entry.target_as = &address_space_memory;
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
127
+ entry.iova = iova;
128
+ entry.addr_mask = (1 << tt->granule_sz) - 1;
129
+ entry.perm = IOMMU_NONE;
130
+
131
+ memory_region_notify_one(n, &entry);
132
+}
91
+}
133
+
92
+
134
+/* invalidate an asid/iova tuple in all mr's */
93
static bool v7m_push_stack(ARMCPU *cpu)
135
+static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
136
+{
137
+ SMMUNotifierNode *node;
138
+
139
+ QLIST_FOREACH(node, &s->notifiers_list, next) {
140
+ IOMMUMemoryRegion *mr = &node->sdev->iommu;
141
+ IOMMUNotifier *n;
142
+
143
+ trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
144
+
145
+ IOMMU_NOTIFIER_FOREACH(n, mr) {
146
+ smmuv3_notify_iova(mr, n, asid, iova);
147
+ }
148
+ }
149
+}
150
+
151
static int smmuv3_cmdq_consume(SMMUv3State *s)
152
{
94
{
153
SMMUState *bs = ARM_SMMU(s);
95
/* Do the "set up stack frame" part of exception entry,
154
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
155
uint16_t asid = CMD_ASID(&cmd);
156
157
trace_smmuv3_cmdq_tlbi_nh_asid(asid);
158
+ smmu_inv_notifiers_all(&s->smmu_state);
159
smmu_iotlb_inv_asid(bs, asid);
160
break;
161
}
162
case SMMU_CMD_TLBI_NH_ALL:
163
case SMMU_CMD_TLBI_NSNH_ALL:
164
trace_smmuv3_cmdq_tlbi_nh();
165
+ smmu_inv_notifiers_all(&s->smmu_state);
166
smmu_iotlb_inv_all(bs);
167
break;
168
case SMMU_CMD_TLBI_NH_VAA:
169
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
170
uint16_t vmid = CMD_VMID(&cmd);
171
172
trace_smmuv3_cmdq_tlbi_nh_vaa(vmid, addr);
173
+ smmuv3_inv_notifiers_iova(bs, -1, addr);
174
smmu_iotlb_inv_all(bs);
175
break;
176
}
177
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
178
bool leaf = CMD_LEAF(&cmd);
179
180
trace_smmuv3_cmdq_tlbi_nh_va(vmid, asid, addr, leaf);
181
+ smmuv3_inv_notifiers_iova(bs, asid, addr);
182
smmu_iotlb_inv_iova(bs, asid, addr);
183
break;
184
}
185
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
186
IOMMUNotifierFlag old,
187
IOMMUNotifierFlag new)
188
{
189
+ SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
190
+ SMMUv3State *s3 = sdev->smmu;
191
+ SMMUState *s = &(s3->smmu_state);
192
+ SMMUNotifierNode *node = NULL;
193
+ SMMUNotifierNode *next_node = NULL;
194
+
195
+ if (new & IOMMU_NOTIFIER_MAP) {
196
+ int bus_num = pci_bus_num(sdev->bus);
197
+ PCIDevice *pcidev = pci_find_device(sdev->bus, bus_num, sdev->devfn);
198
+
199
+ warn_report("SMMUv3 does not support notification on MAP: "
200
+ "device %s will not function properly", pcidev->name);
201
+ }
202
+
203
if (old == IOMMU_NOTIFIER_NONE) {
204
- warn_report("SMMUV3 does not support vhost/vfio integration yet: "
205
- "devices of those types will not function properly");
206
+ trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
207
+ node = g_malloc0(sizeof(*node));
208
+ node->sdev = sdev;
209
+ QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
210
+ return;
211
+ }
212
+
213
+ /* update notifier node with new flags */
214
+ QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
215
+ if (node->sdev == sdev) {
216
+ if (new == IOMMU_NOTIFIER_NONE) {
217
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
218
+ QLIST_REMOVE(node, next);
219
+ g_free(node);
220
+ }
221
+ return;
222
+ }
223
}
224
}
225
226
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
227
index XXXXXXX..XXXXXXX 100644
97
index XXXXXXX..XXXXXXX 100644
228
--- a/hw/arm/trace-events
98
--- a/target/arm/translate.c
229
+++ b/hw/arm/trace-events
99
+++ b/target/arm/translate.c
230
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_cache_miss(uint16_t asid, uint64_t addr, uint32_t hit, uint32_t miss,
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
231
smmu_iotlb_inv_all(void) "IOTLB invalidate all"
101
TCGv_i32 fptr = load_reg(s, rn);
232
smmu_iotlb_inv_asid(uint16_t asid) "IOTLB invalidate asid=%d"
102
233
smmu_iotlb_inv_iova(uint16_t asid, uint64_t addr) "IOTLB invalidate asid=%d addr=0x%"PRIx64
103
if (extract32(insn, 20, 1)) {
234
+smmu_inv_notifiers_mr(const char *name) "iommu mr=%s"
104
- /* VLLDM */
235
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
236
#hw/arm/smmuv3.c
106
} else {
237
smmuv3_read_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
107
gen_helper_v7m_vlstm(cpu_env, fptr);
238
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_tlbi_nh_vaa(int vmid, uint64_t addr) "vmid =%d addr=0x%"PRIx64
108
}
239
smmuv3_cmdq_tlbi_nh(void) ""
240
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
241
smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
242
+smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
243
+smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
244
+smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova) "iommu mr=%s asid=%d iova=0x%"PRIx64
245
+
246
--
109
--
247
2.17.1
110
2.20.1
248
111
249
112
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-15-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
6
---
8
hw/net/smc91c111.c | 12 ++++++++----
7
target/arm/cpu.c | 8 ++++++++
9
1 file changed, 8 insertions(+), 4 deletions(-)
8
1 file changed, 8 insertions(+)
10
9
11
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/net/smc91c111.c
12
--- a/target/arm/cpu.c
14
+++ b/hw/net/smc91c111.c
13
+++ b/target/arm/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
16
SET_HIGH(gpr, value);
15
set_feature(&cpu->env, ARM_FEATURE_M);
17
return;
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
18
case 12: /* Control */
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
19
- if (value & 1)
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
20
- fprintf(stderr, "smc91c111:EEPROM store not implemented\n");
19
cpu->midr = 0x410fc240; /* r0p0 */
21
- if (value & 2)
20
cpu->pmsav7_dregion = 8;
22
- fprintf(stderr, "smc91c111:EEPROM reload not implemented\n");
21
+ cpu->isar.mvfr0 = 0x10110021;
23
+ if (value & 1) {
22
+ cpu->isar.mvfr1 = 0x11000011;
24
+ qemu_log_mask(LOG_UNIMP,
23
+ cpu->isar.mvfr2 = 0x00000000;
25
+ "smc91c111: EEPROM store not implemented\n");
24
cpu->id_pfr0 = 0x00000030;
26
+ }
25
cpu->id_pfr1 = 0x00000200;
27
+ if (value & 2) {
26
cpu->id_dfr0 = 0x00100000;
28
+ qemu_log_mask(LOG_UNIMP,
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
29
+ "smc91c111: EEPROM reload not implemented\n");
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
30
+ }
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
31
value &= ~3;
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
32
SET_LOW(ctr, value);
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
33
return;
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;
34
--
41
--
35
2.17.1
42
2.20.1
36
43
37
44
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Missed in df3692e04b2.
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
5
Move it to common object, so we build it once for all targets.
4
6
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20180624040609.17572-16-f4bug@amsat.org
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
hw/arm/stellaris.c | 2 +-
12
hw/dma/Makefile.objs | 2 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
14
13
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/stellaris.c
17
--- a/hw/dma/Makefile.objs
16
+++ b/hw/arm/stellaris.c
18
+++ b/hw/dma/Makefile.objs
17
@@ -XXX,XX +XXX,XX @@ static void gptm_write(void *opaque, hwaddr offset,
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
18
break;
20
19
default:
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
20
qemu_log_mask(LOG_GUEST_ERROR,
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
21
- "GPTM: read at bad offset 0x%x\n", (int)offset);
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
22
+ "GPTM: write at bad offset 0x%x\n", (int)offset);
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
23
}
24
gptm_update_irq(s);
25
}
26
--
25
--
27
2.17.1
26
2.20.1
28
27
29
28
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-3-f4bug@amsat.org
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
hw/input/tsc2005.c | 13 ++++++++-----
10
hw/arm/aspeed.c | 13 +++++++++----
9
1 file changed, 8 insertions(+), 5 deletions(-)
11
1 file changed, 9 insertions(+), 4 deletions(-)
10
12
11
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/input/tsc2005.c
15
--- a/hw/arm/aspeed.c
14
+++ b/hw/input/tsc2005.c
16
+++ b/hw/arm/aspeed.c
15
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
16
*/
18
#include "hw/arm/aspeed_soc.h"
17
19
#include "hw/boards.h"
18
#include "qemu/osdep.h"
20
#include "hw/i2c/smbus_eeprom.h"
19
+#include "qemu/log.h"
21
+#include "hw/misc/pca9552.h"
20
#include "hw/hw.h"
22
+#include "hw/misc/tmp105.h"
21
#include "qemu/timer.h"
23
#include "qemu/log.h"
22
#include "ui/console.h"
24
#include "sysemu/block-backend.h"
23
@@ -XXX,XX +XXX,XX @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
25
#include "hw/loader.h"
24
}
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
25
s->nextprecision = (data >> 13) & 1;
27
eeprom_buf);
26
s->timing[0] = data & 0x1fff;
28
27
- if ((s->timing[0] >> 11) == 3)
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
28
- fprintf(stderr, "%s: illegal conversion clock setting\n",
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
29
- __func__);
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
30
+ if ((s->timing[0] >> 11) == 3) {
32
+ TYPE_TMP105, 0x4d);
31
+ qemu_log_mask(LOG_GUEST_ERROR,
33
32
+ "tsc2005_write: illegal conversion clock setting\n");
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
33
+ }
35
* plugged on the I2C bus header */
34
break;
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
35
case 0xd:    /* CFR1 */
37
AspeedSoCState *soc = &bmc->soc;
36
s->timing[1] = data & 0xf07;
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
37
@@ -XXX,XX +XXX,XX @@ static void tsc2005_write(TSC2005State *s, int reg, uint16_t data)
39
38
break;
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
39
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
40
default:
42
+ 0x60);
41
- fprintf(stderr, "%s: write into read-only register %x\n",
43
42
- __func__, reg);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
43
+ qemu_log_mask(LOG_GUEST_ERROR,
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
44
+ "%s: write into read-only register 0x%x\n",
46
45
+ __func__, reg);
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
46
}
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);
47
}
61
}
48
62
49
--
63
--
50
2.17.1
64
2.20.1
51
65
52
66
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
hw_error() finally calls abort(), but there is no need to abort here.
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
4
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
6
Message-id: 20180624040609.17572-13-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/net/stellaris_enet.c | 9 +++++++--
9
hw/arm/nseries.c | 3 ++-
11
1 file changed, 7 insertions(+), 2 deletions(-)
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
11
13
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/stellaris_enet.c
14
--- a/hw/arm/nseries.c
16
+++ b/hw/net/stellaris_enet.c
15
+++ b/hw/arm/nseries.c
17
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
18
#include "qemu/osdep.h"
17
#include "hw/boards.h"
19
#include "hw/sysbus.h"
18
#include "hw/i2c/i2c.h"
20
#include "net/net.h"
19
#include "hw/devices.h"
21
+#include "qemu/log.h"
20
+#include "hw/misc/tmp105.h"
22
#include <zlib.h>
21
#include "hw/block/flash.h"
23
22
#include "hw/hw.h"
24
//#define DEBUG_STELLARIS_ENET 1
23
#include "hw/bt.h"
25
@@ -XXX,XX +XXX,XX @@ static uint64_t stellaris_enet_read(void *opaque, hwaddr offset,
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
26
case 0x3c: /* Undocumented: Timestamp? */
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
27
return 0;
26
28
default:
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
29
- hw_error("stellaris_enet_read: Bad offset %x\n", (int)offset);
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
30
+ qemu_log_mask(LOG_GUEST_ERROR, "stellaris_enet_rd%d: Illegal register"
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
31
+ " 0x02%" HWADDR_PRIx "\n",
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
32
+ size * 8, offset);
33
return 0;
34
}
35
}
31
}
36
@@ -XXX,XX +XXX,XX @@ static void stellaris_enet_write(void *opaque, hwaddr offset,
37
/* Ignored. */
38
break;
39
default:
40
- hw_error("stellaris_enet_write: Bad offset %x\n", (int)offset);
41
+ qemu_log_mask(LOG_GUEST_ERROR, "stellaris_enet_wr%d: Illegal register "
42
+ "0x02%" HWADDR_PRIx " = 0x%" PRIx64 "\n",
43
+ size * 8, offset, value);
44
}
45
}
46
32
47
--
33
--
48
2.17.1
34
2.20.1
49
35
50
36
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
The System Control Unit should be initialized first as it drives all
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
4
the configuration of the SoC and other device models.
4
functions since their introduction in commit 88d2c950b002. Time to
5
remove them.
5
6
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Acked-by: Andrew Jeffery <andrew@aj.id.au>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
9
Message-id: 20180622075700.5923-3-clg@kaod.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/arm/aspeed_soc.c | 40 ++++++++++++++++++++--------------------
13
include/hw/devices.h | 3 ---
13
1 file changed, 20 insertions(+), 20 deletions(-)
14
hw/display/tc6393xb.c | 16 ----------------
15
2 files changed, 19 deletions(-)
14
16
15
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/aspeed_soc.c
19
--- a/include/hw/devices.h
18
+++ b/hw/arm/aspeed_soc.c
20
+++ b/include/hw/devices.h
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
20
object_initialize(&s->cpu, sizeof(s->cpu), sc->info->cpu_type);
22
typedef struct TC6393xbState TC6393xbState;
21
object_property_add_child(obj, "cpu", OBJECT(&s->cpu), NULL);
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
22
24
uint32_t base, qemu_irq irq);
23
- object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
24
- object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
26
- qemu_irq handler);
25
- qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
30
#endif
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
34
+++ b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
41
- return s->gpio_in;
42
-}
26
-
43
-
27
- object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
28
- object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
45
{
29
- qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
46
// TC6393xbState *s = opaque;
30
-
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
31
- object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
48
// FIXME: how does the chip reflect the GPIO input level change?
32
- object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
49
}
33
- qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
50
34
-
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
35
object_initialize(&s->scu, sizeof(s->scu), TYPE_ASPEED_SCU);
52
- qemu_irq handler)
36
object_property_add_child(obj, "scu", OBJECT(&s->scu), NULL);
53
-{
37
qdev_set_parent_bus(DEVICE(&s->scu), sysbus_get_default());
54
- if (line >= TC6393XB_GPIOS) {
38
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
39
object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu),
40
"hw-prot-key", &error_abort);
41
42
+ object_initialize(&s->vic, sizeof(s->vic), TYPE_ASPEED_VIC);
43
+ object_property_add_child(obj, "vic", OBJECT(&s->vic), NULL);
44
+ qdev_set_parent_bus(DEVICE(&s->vic), sysbus_get_default());
45
+
46
+ object_initialize(&s->timerctrl, sizeof(s->timerctrl), TYPE_ASPEED_TIMER);
47
+ object_property_add_child(obj, "timerctrl", OBJECT(&s->timerctrl), NULL);
48
+ qdev_set_parent_bus(DEVICE(&s->timerctrl), sysbus_get_default());
49
+
50
+ object_initialize(&s->i2c, sizeof(s->i2c), TYPE_ASPEED_I2C);
51
+ object_property_add_child(obj, "i2c", OBJECT(&s->i2c), NULL);
52
+ qdev_set_parent_bus(DEVICE(&s->i2c), sysbus_get_default());
53
+
54
object_initialize(&s->fmc, sizeof(s->fmc), sc->info->fmc_typename);
55
object_property_add_child(obj, "fmc", OBJECT(&s->fmc), NULL);
56
qdev_set_parent_bus(DEVICE(&s->fmc), sysbus_get_default());
57
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
58
memory_region_add_subregion(get_system_memory(), ASPEED_SOC_SRAM_BASE,
59
&s->sram);
60
61
+ /* SCU */
62
+ object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
63
+ if (err) {
64
+ error_propagate(errp, err);
65
+ return;
66
+ }
67
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
68
+
69
/* VIC */
70
object_property_set_bool(OBJECT(&s->vic), true, "realized", &err);
71
if (err) {
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
73
sysbus_connect_irq(SYS_BUS_DEVICE(&s->timerctrl), i, irq);
74
}
75
76
- /* SCU */
77
- object_property_set_bool(OBJECT(&s->scu), true, "realized", &err);
78
- if (err) {
79
- error_propagate(errp, err);
80
- return;
56
- return;
81
- }
57
- }
82
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->scu), 0, ASPEED_SOC_SCU_BASE);
83
-
58
-
84
/* UART - attach an 8250 to the IO space as our UART5 */
59
- s->handler[line] = handler;
85
if (serial_hd(0)) {
60
-}
86
qemu_irq uart5 = qdev_get_gpio_in(DEVICE(&s->vic), uart_irqs[4]);
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
87
--
65
--
88
2.17.1
66
2.20.1
89
67
90
68
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180624040609.17572-7-f4bug@amsat.org
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/sd/omap_mmc.c | 13 +++++++++----
8
include/hw/devices.h | 6 ------
9
1 file changed, 9 insertions(+), 4 deletions(-)
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
10
15
11
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/sd/omap_mmc.c
18
--- a/include/hw/devices.h
14
+++ b/hw/sd/omap_mmc.c
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
15
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
37
+/*
17
*/
38
+ * Toshiba TC6393XB I/O Controller.
18
#include "qemu/osdep.h"
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
19
+#include "qemu/log.h"
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 @@
20
#include "hw/hw.h"
66
#include "hw/hw.h"
21
#include "hw/arm/omap.h"
67
#include "hw/arm/pxa.h"
22
#include "hw/sd/sd.h"
68
#include "hw/arm/arm.h"
23
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_write(void *opaque, hwaddr offset,
69
-#include "hw/devices.h"
24
s->enable = (value >> 11) & 1;
70
#include "hw/arm/sharpsl.h"
25
s->be = (value >> 10) & 1;
71
#include "hw/pcmcia.h"
26
s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff);
72
#include "hw/boards.h"
27
- if (s->mode != 0)
73
+#include "hw/display/tc6393xb.h"
28
- printf("SD mode %i unimplemented!\n", s->mode);
74
#include "hw/i2c/i2c.h"
29
- if (s->be != 0)
75
#include "hw/ssi/ssi.h"
30
- printf("SD FIFO byte sex unimplemented!\n");
76
#include "hw/sysbus.h"
31
+ if (s->mode != 0) {
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
+ qemu_log_mask(LOG_UNIMP,
78
index XXXXXXX..XXXXXXX 100644
33
+ "omap_mmc_wr: mode #%i unimplemented\n", s->mode);
79
--- a/hw/display/tc6393xb.c
34
+ }
80
+++ b/hw/display/tc6393xb.c
35
+ if (s->be != 0) {
81
@@ -XXX,XX +XXX,XX @@
36
+ qemu_log_mask(LOG_UNIMP,
82
#include "qapi/error.h"
37
+ "omap_mmc_wr: Big Endian not implemented\n");
83
#include "qemu/host-utils.h"
38
+ }
84
#include "hw/hw.h"
39
if (s->dw != 0 && s->lines < 4)
85
-#include "hw/devices.h"
40
printf("4-bit SD bus enabled\n");
86
+#include "hw/display/tc6393xb.h"
41
if (!s->enable)
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>
42
--
102
--
43
2.17.1
103
2.20.1
44
104
45
105
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
This adds Cedric as the maintainer, with Andrew and I as reviewers, for
3
Add an entries the Blizzard device in MAINTAINERS.
4
the ASPEED boards and the peripherals we have developed.
5
4
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
Acked-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
10
Message-id: 20180625140055.32223-1-joel@jms.id.au
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
MAINTAINERS | 11 +++++++++++
11
include/hw/devices.h | 7 -------
14
1 file changed, 11 insertions(+)
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
15
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);
16
diff --git a/MAINTAINERS b/MAINTAINERS
90
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
92
--- a/MAINTAINERS
19
+++ b/MAINTAINERS
93
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
21
S: Maintained
95
L: qemu-arm@nongnu.org
22
F: hw/arm/msf2-som.c
96
S: Odd Fixes
23
97
F: hw/arm/nseries.c
24
+ASPEED BMCs
98
+F: hw/display/blizzard.c
25
+M: Cédric Le Goater <clg@kaod.org>
99
F: hw/input/lm832x.c
26
+R: Andrew Jeffery <andrew@aj.id.au>
100
F: hw/input/tsc2005.c
27
+R: Joel Stanley <joel@jms.id.au>
101
F: hw/misc/cbus.c
28
+L: qemu-arm@nongnu.org
102
F: hw/timer/twl92230.c
29
+S: Maintained
103
+F: include/hw/display/blizzard.h
30
+F: hw/*/*aspeed*
104
31
+F: include/hw/*/*aspeed*
105
Palm
32
+F: hw/net/ftgmac100.c
106
M: Andrzej Zaborowski <balrogg@gmail.com>
33
+F: include/hw/net/ftgmac100.h
34
+
35
CRIS Machines
36
-------------
37
Axis Dev88
38
--
107
--
39
2.17.1
108
2.20.1
40
109
41
110
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
These COMs are hard to find, and the companie dropped the support
4
few years ago.
5
6
Per the "Gumstix Product Changes, Known Issues, and EOL" pdf:
7
8
- Phasing out: PXA270-based Verdex product line
9
September 2012
10
11
- Phasing out: PXA255-based Basix & Connex
12
September 2009
13
14
However there are still booting SD card image availables, very
15
convenient to stress test the QEMU SD card implementation.
16
Therefore I volunteer to keep an eye on this file, while it
17
is useful for testing.
18
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
21
Message-id: 20180606144706.29732-1-f4bug@amsat.org
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
8
---
24
MAINTAINERS | 3 ++-
9
include/hw/devices.h | 14 --------------
25
1 file changed, 2 insertions(+), 1 deletion(-)
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
11
hw/arm/nseries.c | 1 +
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
26
16
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
20
+++ b/include/hw/devices.h
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
49
+ * Based on reverse-engineering of a linux driver.
50
+ *
51
+ * Copyright (C) 2008 Nokia Corporation
52
+ * Written by Andrzej Zaborowski
53
+ *
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
56
+ */
57
+
58
+#ifndef HW_MISC_CBUS_H
59
+#define HW_MISC_CBUS_H
60
+
61
+#include "hw/irq.h"
62
+
63
+typedef struct {
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
81
+++ b/hw/arm/nseries.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "hw/i2c/i2c.h"
84
#include "hw/devices.h"
85
#include "hw/display/blizzard.h"
86
+#include "hw/misc/cbus.h"
87
#include "hw/misc/tmp105.h"
88
#include "hw/block/flash.h"
89
#include "hw/hw.h"
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/misc/cbus.c
93
+++ b/hw/misc/cbus.c
94
@@ -XXX,XX +XXX,XX @@
95
#include "qemu/osdep.h"
96
#include "hw/hw.h"
97
#include "hw/irq.h"
98
-#include "hw/devices.h"
99
+#include "hw/misc/cbus.h"
100
#include "sysemu/sysemu.h"
101
102
//#define DEBUG
27
diff --git a/MAINTAINERS b/MAINTAINERS
103
diff --git a/MAINTAINERS b/MAINTAINERS
28
index XXXXXXX..XXXXXXX 100644
104
index XXXXXXX..XXXXXXX 100644
29
--- a/MAINTAINERS
105
--- a/MAINTAINERS
30
+++ b/MAINTAINERS
106
+++ b/MAINTAINERS
31
@@ -XXX,XX +XXX,XX @@ F: include/hw/arm/digic.h
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
32
F: hw/*/digic*
108
F: hw/misc/cbus.c
33
109
F: hw/timer/twl92230.c
34
Gumstix
110
F: include/hw/display/blizzard.h
35
+M: Philippe Mathieu-Daudé <f4bug@amsat.org>
111
+F: include/hw/misc/cbus.h
36
L: qemu-devel@nongnu.org
112
37
L: qemu-arm@nongnu.org
113
Palm
38
-S: Orphan
114
M: Andrzej Zaborowski <balrogg@gmail.com>
39
+S: Odd Fixes
40
F: hw/arm/gumstix.c
41
42
i.MX31
43
--
115
--
44
2.17.1
116
2.20.1
45
117
46
118
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180624040609.17572-11-f4bug@amsat.org
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/arm/stellaris.c | 2 +-
8
include/hw/devices.h | 3 ---
9
1 file changed, 1 insertion(+), 1 deletion(-)
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
10
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 *tsc2005_init(qemu_irq pintdav);
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
23
24
-/* stellaris_input.c */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
44
+#ifndef HW_INPUT_GAMEPAD_H
45
+#define HW_INPUT_GAMEPAD_H
46
+
47
+#include "hw/irq.h"
48
+
49
+/* stellaris_input.c */
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
51
+
52
+#endif
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
12
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/stellaris.c
55
--- a/hw/arm/stellaris.c
14
+++ b/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
15
@@ -XXX,XX +XXX,XX @@ static void ssys_write(void *opaque, hwaddr offset,
57
@@ -XXX,XX +XXX,XX @@
16
case 0x040: /* SRCR0 */
58
#include "hw/sysbus.h"
17
case 0x044: /* SRCR1 */
59
#include "hw/ssi/ssi.h"
18
case 0x048: /* SRCR2 */
60
#include "hw/arm/arm.h"
19
- fprintf(stderr, "Peripheral reset not implemented\n");
61
-#include "hw/devices.h"
20
+ qemu_log_mask(LOG_UNIMP, "Peripheral reset not implemented\n");
62
#include "qemu/timer.h"
21
break;
63
#include "hw/i2c/i2c.h"
22
case 0x054: /* IMC */
64
#include "net/net.h"
23
s->int_mask = value & 0x7f;
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
92
S: Maintained
93
F: hw/*/stellaris*
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
24
--
98
--
25
2.17.1
99
2.20.1
26
100
27
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Since uWireSlave is only used in this new header, there is no
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
need to expose it via "qemu/typedefs.h".
5
Message-id: 20180624040609.17572-10-f4bug@amsat.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/arm/omap.h | 12 ++++++------
11
include/hw/arm/omap.h | 6 +-----
9
1 file changed, 6 insertions(+), 6 deletions(-)
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
10
22
11
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/arm/omap.h
25
--- a/include/hw/arm/omap.h
14
+++ b/include/hw/arm/omap.h
26
+++ b/include/hw/arm/omap.h
15
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
16
# define hw_omap_h        "omap.h"
29
# define hw_omap_h        "omap.h"
17
#include "hw/irq.h"
30
#include "hw/irq.h"
31
+#include "hw/input/tsc2xxx.h"
18
#include "target/arm/cpu-qom.h"
32
#include "target/arm/cpu-qom.h"
19
+#include "qemu/log.h"
33
#include "qemu/log.h"
20
34
21
# define OMAP_EMIFS_BASE    0x00000000
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
22
# define OMAP2_Q0_BASE        0x00000000
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
23
@@ -XXX,XX +XXX,XX @@ struct omap_mpu_state_s *omap2420_mpu_init(MemoryRegion *sysmem,
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
24
unsigned long sdram_size,
38
25
const char *core);
39
-struct uWireSlave {
26
40
- uint16_t (*receive)(void *opaque);
27
-#define OMAP_FMT_plx "%#08" HWADDR_PRIx
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);
28
-
71
-
29
uint32_t omap_badwidth_read8(void *opaque, hwaddr addr);
72
-/* tsc2005.c */
30
void omap_badwidth_write8(void *opaque, hwaddr addr,
73
-void *tsc2005_init(qemu_irq pintdav);
31
uint32_t value);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
32
@@ -XXX,XX +XXX,XX @@ void omap_badwidth_write32(void *opaque, hwaddr addr,
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
33
void omap_mpu_wakeup(void *opaque, int irq, int req);
76
-
34
77
#endif
35
# define OMAP_BAD_REG(paddr)        \
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
36
- fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n",    \
79
new file mode 100644
37
- __func__, paddr)
80
index XXXXXXX..XXXXXXX
38
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad register %#08"HWADDR_PRIx"\n", \
81
--- /dev/null
39
+ __func__, paddr)
82
+++ b/include/hw/input/tsc2xxx.h
40
# define OMAP_RO_REG(paddr)        \
83
@@ -XXX,XX +XXX,XX @@
41
- fprintf(stderr, "%s: Read-only register " OMAP_FMT_plx "\n",    \
84
+/*
42
- __func__, paddr)
85
+ * TI touchscreen controller
43
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register %#08" \
86
+ *
44
+ HWADDR_PRIx "\n", \
87
+ * Copyright (c) 2006 Andrzej Zaborowski
45
+ __func__, paddr)
88
+ * Copyright (C) 2008 Nokia Corporation
46
89
+ *
47
/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
48
(Board-specifc tags are not here) */
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>
49
--
207
--
50
2.17.1
208
2.20.1
51
209
52
210
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Message-id: 20180624040609.17572-4-f4bug@amsat.org
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
7
---
8
hw/dma/omap_dma.c | 6 ++++--
8
include/hw/devices.h | 3 ---
9
1 file changed, 4 insertions(+), 2 deletions(-)
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
10
hw/arm/kzm.c | 2 +-
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
10
17
11
diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
12
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/dma/omap_dma.c
20
--- a/include/hw/devices.h
14
+++ b/hw/dma/omap_dma.c
21
+++ b/include/hw/devices.h
15
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
23
/* smc91c111.c */
17
*/
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
18
#include "qemu/osdep.h"
25
19
+#include "qemu/log.h"
26
-/* lan9118.c */
20
#include "qemu-common.h"
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
21
#include "qemu/timer.h"
28
-
22
#include "hw/arm/omap.h"
29
#endif
23
@@ -XXX,XX +XXX,XX @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
24
case 0x480:    /* DMA_PCh0_SR */
31
new file mode 100644
25
case 0x482:    /* DMA_PCh1_SR */
32
index XXXXXXX..XXXXXXX
26
case 0x4c0:    /* DMA_PChD_SR_0 */
33
--- /dev/null
27
- printf("%s: Physical Channel Status Registers not implemented.\n",
34
+++ b/include/hw/net/lan9118.h
28
- __func__);
35
@@ -XXX,XX +XXX,XX @@
29
+ qemu_log_mask(LOG_UNIMP,
36
+/*
30
+ "%s: Physical Channel Status Registers not implemented\n",
37
+ * SMSC LAN9118 Ethernet interface emulation
31
+ __func__);
38
+ *
32
*ret = 0xff;
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
33
break;
40
+ * Written by Paul Brook
34
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
44
+ */
45
+
46
+#ifndef HW_NET_LAN9118_H
47
+#define HW_NET_LAN9118_H
48
+
49
+#include "hw/irq.h"
50
+#include "net/net.h"
51
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
+
54
+#endif
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
58
+++ b/hw/arm/kzm.c
59
@@ -XXX,XX +XXX,XX @@
60
#include "qemu/error-report.h"
61
#include "exec/address-spaces.h"
62
#include "net/net.h"
63
-#include "hw/devices.h"
64
+#include "hw/net/lan9118.h"
65
#include "hw/char/serial.h"
66
#include "sysemu/qtest.h"
67
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
71
+++ b/hw/arm/mps2.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "hw/timer/cmsdk-apb-timer.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
75
#include "hw/misc/mps2-scc.h"
76
-#include "hw/devices.h"
77
+#include "hw/net/lan9118.h"
78
#include "net/net.h"
79
80
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/realview.c
84
+++ b/hw/arm/realview.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "hw/arm/arm.h"
87
#include "hw/arm/primecell.h"
88
#include "hw/devices.h"
89
+#include "hw/net/lan9118.h"
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
35
--
119
--
36
2.17.1
120
2.20.1
37
121
38
122
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Message-id: 20180624040609.17572-2-f4bug@amsat.org
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
hw/input/pckbd.c | 4 +++-
9
include/hw/net/ne2000-isa.h | 6 ++++++
9
1 file changed, 3 insertions(+), 1 deletion(-)
10
1 file changed, 6 insertions(+)
10
11
11
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/input/pckbd.c
14
--- a/include/hw/net/ne2000-isa.h
14
+++ b/hw/input/pckbd.c
15
+++ b/include/hw/net/ne2000-isa.h
15
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
16
* THE SOFTWARE.
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
18
* See the COPYING file in the top-level directory.
17
*/
19
*/
18
#include "qemu/osdep.h"
20
+
19
+#include "qemu/log.h"
21
+#ifndef HW_NET_NE2K_ISA_H
22
+#define HW_NET_NE2K_ISA_H
23
+
20
#include "hw/hw.h"
24
#include "hw/hw.h"
25
#include "hw/qdev.h"
21
#include "hw/isa/isa.h"
26
#include "hw/isa/isa.h"
22
#include "hw/i386/pc.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
23
@@ -XXX,XX +XXX,XX @@ static void kbd_write_command(void *opaque, hwaddr addr,
24
/* ignore that */
25
break;
26
default:
27
- fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val);
28
+ qemu_log_mask(LOG_GUEST_ERROR,
29
+ "unsupported keyboard cmd=0x%02" PRIx64 "\n", val);
30
break;
31
}
28
}
29
return d;
32
}
30
}
31
+
32
+#endif
33
--
33
--
34
2.17.1
34
2.20.1
35
35
36
36
diff view generated by jsdifflib
1
From: Sai Pavan Boddu <saipava@xilinx.com>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
Qspi dma has a burst length of 64 bytes, So limit the transactions w.r.t
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
dma-burst-size property.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
6
Signed-off-by: Sai Pavan Boddu <saipava@xilinx.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 1529660880-30376-1-git-send-email-sai.pavan.boddu@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
include/hw/ssi/xilinx_spips.h | 5 ++++-
8
include/hw/net/lan9118.h | 2 ++
12
hw/ssi/xilinx_spips.c | 23 ++++++++++++++++++++---
9
hw/arm/exynos4_boards.c | 3 ++-
13
2 files changed, 24 insertions(+), 4 deletions(-)
10
hw/arm/mps2-tz.c | 3 ++-
11
hw/net/lan9118.c | 1 -
12
4 files changed, 6 insertions(+), 3 deletions(-)
14
13
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
16
--- a/include/hw/net/lan9118.h
18
+++ b/include/hw/ssi/xilinx_spips.h
17
+++ b/include/hw/net/lan9118.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPS XilinxSPIPS;
18
@@ -XXX,XX +XXX,XX @@
20
/* Bite off 4k chunks at a time */
19
#include "hw/irq.h"
21
#define LQSPI_CACHE_SIZE 1024
20
#include "net/net.h"
22
21
23
+#define QSPI_DMA_MAX_BURST_SIZE 2048
22
+#define TYPE_LAN9118 "lan9118"
24
+
23
+
25
typedef enum {
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
26
READ = 0x3, READ_4 = 0x13,
25
27
FAST_READ = 0xb, FAST_READ_4 = 0x0c,
26
#endif
28
@@ -XXX,XX +XXX,XX @@ typedef struct {
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
29
XilinxQSPIPS parent_obj;
30
31
StreamSlave *dma;
32
- uint8_t dma_buf[4];
33
int gqspi_irqline;
34
35
uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX];
36
@@ -XXX,XX +XXX,XX @@ typedef struct {
37
uint8_t rx_fifo_g_align;
38
uint8_t tx_fifo_g_align;
39
bool man_start_com_g;
40
+ uint32_t dma_burst_size;
41
+ uint8_t dma_buf[QSPI_DMA_MAX_BURST_SIZE];
42
} XlnxZynqMPQSPIPS;
43
44
typedef struct XilinxSPIPSClass {
45
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
46
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/ssi/xilinx_spips.c
29
--- a/hw/arm/exynos4_boards.c
48
+++ b/hw/ssi/xilinx_spips.c
30
+++ b/hw/arm/exynos4_boards.c
49
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_notify(void *opaque)
31
@@ -XXX,XX +XXX,XX @@
50
{
32
#include "hw/arm/arm.h"
51
size_t ret;
33
#include "exec/address-spaces.h"
52
uint32_t num;
34
#include "hw/arm/exynos4210.h"
53
- const void *rxd = pop_buf(recv_fifo, 4, &num);
35
+#include "hw/net/lan9118.h"
54
+ const void *rxd;
36
#include "hw/boards.h"
55
+ int len;
37
56
+
38
#undef DEBUG
57
+ len = recv_fifo->num >= rq->dma_burst_size ? rq->dma_burst_size :
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
58
+ recv_fifo->num;
40
/* This should be a 9215 but the 9118 is close enough */
59
+ rxd = pop_buf(recv_fifo, len, &num);
41
if (nd_table[0].used) {
60
42
qemu_check_nic_model(&nd_table[0], "lan9118");
61
memcpy(rq->dma_buf, rxd, num);
43
- dev = qdev_create(NULL, "lan9118");
62
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
63
- ret = stream_push(rq->dma, rq->dma_buf, 4);
45
qdev_set_nic_properties(dev, &nd_table[0]);
64
- assert(ret == 4);
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
65
+ ret = stream_push(rq->dma, rq->dma_buf, num);
47
qdev_init_nofail(dev);
66
+ assert(ret == num);
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
67
xlnx_zynqmp_qspips_check_flush(rq);
49
index XXXXXXX..XXXXXXX 100644
68
}
50
--- a/hw/arm/mps2-tz.c
69
}
51
+++ b/hw/arm/mps2-tz.c
70
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
52
@@ -XXX,XX +XXX,XX @@
71
XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(dev);
53
#include "hw/arm/armsse.h"
72
XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
54
#include "hw/dma/pl080.h"
73
55
#include "hw/ssi/pl022.h"
74
+ if (s->dma_burst_size > QSPI_DMA_MAX_BURST_SIZE) {
56
+#include "hw/net/lan9118.h"
75
+ error_setg(errp,
57
#include "net/net.h"
76
+ "qspi dma burst size %u exceeds maximum limit %d",
58
#include "hw/core/split-irq.h"
77
+ s->dma_burst_size, QSPI_DMA_MAX_BURST_SIZE);
59
78
+ return;
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
79
+ }
61
* except that it doesn't support the checksum-offload feature.
80
xilinx_qspips_realize(dev, errp);
62
*/
81
fifo8_create(&s->rx_fifo_g, xsc->rx_fifo_size);
63
qemu_check_nic_model(nd, "lan9118");
82
fifo8_create(&s->tx_fifo_g, xsc->tx_fifo_size);
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
83
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xlnx_zynqmp_qspips = {
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 = {
84
}
74
}
85
};
75
};
86
76
87
+static Property xilinx_zynqmp_qspips_properties[] = {
77
-#define TYPE_LAN9118 "lan9118"
88
+ DEFINE_PROP_UINT32("dma-burst-size", XlnxZynqMPQSPIPS, dma_burst_size, 64),
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
89
+ DEFINE_PROP_END_OF_LIST(),
79
90
+};
80
typedef struct {
91
+
92
static Property xilinx_qspips_properties[] = {
93
/* We had to turn this off for 2.10 as it is not compatible with migration.
94
* It can be enabled but will prevent the device to be migrated.
95
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
96
dc->realize = xlnx_zynqmp_qspips_realize;
97
dc->reset = xlnx_zynqmp_qspips_reset;
98
dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
99
+ dc->props = xilinx_zynqmp_qspips_properties;
100
xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
101
xsc->rx_fifo_size = RXFF_A_Q;
102
xsc->tx_fifo_size = TXFF_A_Q;
103
--
81
--
104
2.17.1
82
2.20.1
105
83
106
84
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
2
3
hw_error() finally calls abort(), but there is no need to abort here.
3
This commit finally deletes "hw/devices.h".
4
4
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20180624040609.17572-14-f4bug@amsat.org
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
hw/net/smc91c111.c | 9 +++++++--
10
include/hw/devices.h | 11 -----------
11
1 file changed, 7 insertions(+), 2 deletions(-)
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
12
hw/arm/gumstix.c | 2 +-
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
12
21
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
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
67
+++ b/hw/arm/gumstix.c
68
@@ -XXX,XX +XXX,XX @@
69
#include "hw/arm/pxa.h"
70
#include "net/net.h"
71
#include "hw/block/flash.h"
72
-#include "hw/devices.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"
84
#include "hw/sysbus.h"
85
-#include "hw/devices.h"
86
#include "hw/boards.h"
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
13
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
14
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/smc91c111.c
135
--- a/hw/net/smc91c111.c
16
+++ b/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
17
@@ -XXX,XX +XXX,XX @@
137
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
18
#include "hw/sysbus.h"
139
#include "hw/sysbus.h"
19
#include "net/net.h"
140
#include "net/net.h"
20
#include "hw/devices.h"
141
-#include "hw/devices.h"
21
+#include "qemu/log.h"
142
+#include "hw/net/smc91c111.h"
143
#include "qemu/log.h"
22
/* For crc32 */
144
/* For crc32 */
23
#include <zlib.h>
145
#include <zlib.h>
24
25
@@ -XXX,XX +XXX,XX @@ static void smc91c111_writeb(void *opaque, hwaddr offset,
26
}
27
break;
28
}
29
- hw_error("smc91c111_write: Bad reg %d:%x\n", s->bank, (int)offset);
30
+ qemu_log_mask(LOG_GUEST_ERROR, "smc91c111_write(bank:%d) Illegal register"
31
+ " 0x%" HWADDR_PRIx " = 0x%x\n",
32
+ s->bank, offset, value);
33
}
34
35
static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
36
@@ -XXX,XX +XXX,XX @@ static uint32_t smc91c111_readb(void *opaque, hwaddr offset)
37
}
38
break;
39
}
40
- hw_error("smc91c111_read: Bad reg %d:%x\n", s->bank, (int)offset);
41
+ qemu_log_mask(LOG_GUEST_ERROR, "smc91c111_read(bank:%d) Illegal register"
42
+ " 0x%" HWADDR_PRIx "\n",
43
+ s->bank, offset);
44
return 0;
45
}
46
47
--
146
--
48
2.17.1
147
2.20.1
49
148
50
149
diff view generated by jsdifflib