1
ARM pullreq; contains some patches that arrived while I
1
target-arm queue. This has the "plumb txattrs through various
2
was on holiday, plus the series I sent off before going
2
bits of exec.c" patches, and a collection of bug fixes from
3
away, which got reviewed while I was away.
3
various people.
4
4
5
thanks
5
thanks
6
-- PMM
6
-- PMM
7
7
8
8
9
The following changes since commit c077a998eb3fcae2d048e3baeb5bc592d30fddde:
10
9
11
Merge remote-tracking branch 'remotes/riku/tags/pull-linux-user-20170531' into staging (2017-06-01 15:50:40 +0100)
10
The following changes since commit a3ac12fba028df90f7b3dbec924995c126c41022:
12
11
13
are available in the git repository at:
12
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging (2018-05-31 11:12:36 +0100)
14
13
15
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170601
14
are available in the Git repository at:
16
15
17
for you to fetch changes up to cdc58be430b0bdeaef282e2e70f8135ae531616d:
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180531
18
17
19
hw/arm/virt: fdt: generate distance-map when needed (2017-06-01 17:27:07 +0100)
18
for you to fetch changes up to 49d1dca0520ea71bc21867fab6647f474fcf857b:
19
20
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice (2018-05-31 14:52:53 +0100)
20
21
21
----------------------------------------------------------------
22
----------------------------------------------------------------
22
target-arm queue:
23
target-arm queue:
23
* virt: numa: provide ACPI distance info when needed
24
* target/arm: Honour FPCR.FZ in FRECPX
24
* aspeed: fix i2c controller bugs
25
* MAINTAINERS: Add entries for newer MPS2 boards and devices
25
* aspeed: add temperature sensor device
26
* hw/intc/arm_gicv3: Fix APxR<n> register dispatching
26
* M profile: support MPU
27
* arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel
27
* gicv3: fix mishandling of BPR1, VBPR1
28
GIC state
28
* load_uboot_image: don't assume a full header read
29
* tcg: Fix helper function vs host abi for float16
29
* libvixl: Correct build failures on NetBSD
30
* arm: fix qemu crash on startup with -bios option
31
* arm: fix malloc type mismatch
32
* xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
33
* Correct CPACR reset value for v7 cores
34
* memory.h: Improve IOMMU related documentation
35
* exec: Plumb transaction attributes through various functions in
36
preparation for allowing IOMMUs to see them
37
* vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
38
* ARM: ACPI: Fix use-after-free due to memory realloc
39
* KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
30
40
31
----------------------------------------------------------------
41
----------------------------------------------------------------
32
Andrew Jones (3):
42
Francisco Iglesias (1):
33
load_uboot_image: don't assume a full header read
43
xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
34
hw/arm/virt-acpi-build: build SLIT when needed
35
hw/arm/virt: fdt: generate distance-map when needed
36
44
37
Cédric Le Goater (6):
45
Igor Mammedov (1):
38
aspeed/i2c: improve command handling
46
arm: fix qemu crash on startup with -bios option
39
aspeed/i2c: handle LAST command under the RX command
40
aspeed/i2c: introduce a state machine
41
aspeed: add some I2C devices to the Aspeed machines
42
hw/misc: add a TMP42{1,2,3} device model
43
aspeed: add a temp sensor device on I2C bus 3
44
47
45
Kamil Rytarowski (1):
48
Jan Kiszka (1):
46
libvixl: Correct build failures on NetBSD
49
hw/intc/arm_gicv3: Fix APxR<n> register dispatching
47
50
48
Michael Davidsaver (4):
51
Paolo Bonzini (1):
49
armv7m: Improve "-d mmu" tracing for PMSAv7 MPU
52
arm: fix malloc type mismatch
50
armv7m: Implement M profile default memory map
51
armv7m: Classify faults as MemManage or BusFault
52
arm: add MPU support to M profile CPUs
53
53
54
Peter Maydell (12):
54
Peter Maydell (17):
55
hw/intc/arm_gicv3_cpuif: Fix reset value for VMCR_EL2.VBPR1
55
target/arm: Honour FPCR.FZ in FRECPX
56
hw/intc/arm_gicv3_cpuif: Don't let BPR be set below its minimum
56
MAINTAINERS: Add entries for newer MPS2 boards and devices
57
hw/intc/arm_gicv3_cpuif: Fix priority masking for NS BPR1
57
Correct CPACR reset value for v7 cores
58
arm: Use the mmu_idx we're passed in arm_cpu_do_unaligned_access()
58
memory.h: Improve IOMMU related documentation
59
arm: Add support for M profile CPUs having different MMU index semantics
59
Make tb_invalidate_phys_addr() take a MemTxAttrs argument
60
arm: Use different ARMMMUIdx values for M profile
60
Make address_space_translate{, _cached}() take a MemTxAttrs argument
61
arm: Clean up handling of no-MPU PMSA CPUs
61
Make address_space_map() take a MemTxAttrs argument
62
arm: Don't clear ARM_FEATURE_PMSA for no-mpu configs
62
Make address_space_access_valid() take a MemTxAttrs argument
63
arm: Don't let no-MPU PMSA cores write to SCTLR.M
63
Make flatview_extend_translation() take a MemTxAttrs argument
64
arm: Remove unnecessary check on cpu->pmsav7_dregion
64
Make memory_region_access_valid() take a MemTxAttrs argument
65
arm: All M profile cores are PMSA
65
Make MemoryRegion valid.accepts callback take a MemTxAttrs argument
66
arm: Implement HFNMIENA support for M profile MPU
66
Make flatview_access_valid() take a MemTxAttrs argument
67
Make flatview_translate() take a MemTxAttrs argument
68
Make address_space_get_iotlb_entry() take a MemTxAttrs argument
69
Make flatview_do_translate() take a MemTxAttrs argument
70
Make address_space_translate_iommu take a MemTxAttrs argument
71
vmstate.h: Provide VMSTATE_BOOL_SUB_ARRAY
67
72
68
Wei Huang (1):
73
Richard Henderson (1):
69
target/arm: clear PMUVER field of AA64DFR0 when vPMU=off
74
tcg: Fix helper function vs host abi for float16
70
75
71
disas/libvixl/Makefile.objs | 3 +
76
Shannon Zhao (3):
72
hw/misc/Makefile.objs | 1 +
77
arm_gicv3_kvm: increase clroffset accordingly
73
target/arm/cpu.h | 118 ++++++++++--
78
ARM: ACPI: Fix use-after-free due to memory realloc
74
target/arm/translate.h | 2 +-
79
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
75
hw/arm/aspeed.c | 36 ++++
76
hw/arm/virt-acpi-build.c | 4 +
77
hw/arm/virt.c | 21 +++
78
hw/core/loader.c | 3 +-
79
hw/i2c/aspeed_i2c.c | 65 ++++++-
80
hw/intc/arm_gicv3_cpuif.c | 50 ++++-
81
hw/intc/armv7m_nvic.c | 104 +++++++++++
82
hw/misc/tmp421.c | 401 ++++++++++++++++++++++++++++++++++++++++
83
target/arm/cpu.c | 28 ++-
84
target/arm/helper.c | 338 ++++++++++++++++++++++-----------
85
target/arm/machine.c | 7 +-
86
target/arm/op_helper.c | 3 +-
87
target/arm/translate-a64.c | 18 +-
88
target/arm/translate.c | 14 +-
89
default-configs/arm-softmmu.mak | 1 +
90
19 files changed, 1060 insertions(+), 157 deletions(-)
91
create mode 100644 hw/misc/tmp421.c
92
80
81
include/exec/exec-all.h | 5 +-
82
include/exec/helper-head.h | 2 +-
83
include/exec/memory-internal.h | 3 +-
84
include/exec/memory.h | 128 +++++++++++++++++++++++++++++++++++------
85
include/migration/vmstate.h | 3 +
86
include/sysemu/dma.h | 6 +-
87
accel/tcg/translate-all.c | 4 +-
88
exec.c | 95 ++++++++++++++++++------------
89
hw/arm/boot.c | 18 +++---
90
hw/arm/virt-acpi-build.c | 20 +++++--
91
hw/dma/xlnx-zdma.c | 10 +++-
92
hw/hppa/dino.c | 3 +-
93
hw/intc/arm_gic_kvm.c | 1 -
94
hw/intc/arm_gicv3_cpuif.c | 12 ++--
95
hw/intc/arm_gicv3_kvm.c | 2 +-
96
hw/nvram/fw_cfg.c | 12 ++--
97
hw/s390x/s390-pci-inst.c | 3 +-
98
hw/scsi/esp.c | 3 +-
99
hw/vfio/common.c | 3 +-
100
hw/virtio/vhost.c | 3 +-
101
hw/xen/xen_pt_msi.c | 3 +-
102
memory.c | 12 ++--
103
memory_ldst.inc.c | 18 +++---
104
target/arm/gdbstub.c | 3 +-
105
target/arm/helper-a64.c | 41 +++++++------
106
target/arm/helper.c | 90 ++++++++++++++++-------------
107
target/ppc/mmu-hash64.c | 3 +-
108
target/riscv/helper.c | 2 +-
109
target/s390x/diag.c | 6 +-
110
target/s390x/excp_helper.c | 3 +-
111
target/s390x/mmu_helper.c | 3 +-
112
target/s390x/sigp.c | 3 +-
113
target/xtensa/op_helper.c | 3 +-
114
MAINTAINERS | 9 ++-
115
34 files changed, 353 insertions(+), 182 deletions(-)
116
diff view generated by jsdifflib
1
Implement HFNMIENA support for the M profile MPU. This bit controls
1
The FRECPX instructions should (like most other floating point operations)
2
whether the MPU is treated as enabled when executing at execution
2
honour the FPCR.FZ bit which specifies whether input denormals should
3
priorities of less than zero (in NMI, HardFault or with the FAULTMASK
3
be flushed to zero (or FZ16 for the half-precision version).
4
bit set).
4
We forgot to implement this, which doesn't affect the results (since
5
5
the calculation doesn't actually care about the mantissa bits) but did
6
Doing this requires us to use a different MMU index for "running
6
mean we were failing to set the FPSR.IDC bit.
7
at execution priority < 0", because we will have different
8
access permissions for that case versus the normal case.
9
7
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 1493122030-32191-14-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180521172712.19930-1-peter.maydell@linaro.org
12
---
11
---
13
target/arm/cpu.h | 24 +++++++++++++++++++++++-
12
target/arm/helper-a64.c | 6 ++++++
14
target/arm/helper.c | 18 +++++++++++++++++-
13
1 file changed, 6 insertions(+)
15
target/arm/translate.c | 1 +
16
3 files changed, 41 insertions(+), 2 deletions(-)
17
14
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
17
--- a/target/arm/helper-a64.c
21
+++ b/target/arm/cpu.h
18
+++ b/target/arm/helper-a64.c
22
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
19
@@ -XXX,XX +XXX,XX @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
23
* for the accesses done as part of a stage 1 page table walk, rather than
20
return nan;
24
* having to walk the stage 2 page table over and over.)
25
*
26
+ * R profile CPUs have an MPU, but can use the same set of MMU indexes
27
+ * as A profile. They only need to distinguish NS EL0 and NS EL1 (and
28
+ * NS EL2 if we ever model a Cortex-R52).
29
+ *
30
+ * M profile CPUs are rather different as they do not have a true MMU.
31
+ * They have the following different MMU indexes:
32
+ * User
33
+ * Privileged
34
+ * Execution priority negative (this is like privileged, but the
35
+ * MPU HFNMIENA bit means that it may have different access permission
36
+ * check results to normal privileged code, so can't share a TLB).
37
+ *
38
* The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
39
* are not quite the same -- different CPU types (most notably M profile
40
* vs A/R profile) would like to use MMU indexes with different semantics,
41
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
42
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
43
ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
44
ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
45
+ ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
46
/* Indexes below here don't have TLBs and are used only for AT system
47
* instructions or for the first stage of an S12 page table walk.
48
*/
49
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
50
ARMMMUIdxBit_S2NS = 1 << 6,
51
ARMMMUIdxBit_MUser = 1 << 0,
52
ARMMMUIdxBit_MPriv = 1 << 1,
53
+ ARMMMUIdxBit_MNegPri = 1 << 2,
54
} ARMMMUIdxBit;
55
56
#define MMU_USER_IDX 0
57
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
58
case ARM_MMU_IDX_A:
59
return mmu_idx & 3;
60
case ARM_MMU_IDX_M:
61
- return mmu_idx & 1;
62
+ return mmu_idx == ARMMMUIdx_MUser ? 0 : 1;
63
default:
64
g_assert_not_reached();
65
}
21
}
66
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
22
67
if (arm_feature(env, ARM_FEATURE_M)) {
23
+ a = float16_squash_input_denormal(a, fpst);
68
ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv;
69
70
+ /* Execution priority is negative if FAULTMASK is set or
71
+ * we're in a HardFault or NMI handler.
72
+ */
73
+ if ((env->v7m.exception > 0 && env->v7m.exception <= 3)
74
+ || env->daif & PSTATE_F) {
75
+ return arm_to_core_mmu_idx(ARMMMUIdx_MNegPri);
76
+ }
77
+
24
+
78
return arm_to_core_mmu_idx(mmu_idx);
25
val16 = float16_val(a);
26
sbit = 0x8000 & val16;
27
exp = extract32(val16, 10, 5);
28
@@ -XXX,XX +XXX,XX @@ float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
29
return nan;
79
}
30
}
80
31
81
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
+ a = float32_squash_input_denormal(a, fpst);
82
index XXXXXXX..XXXXXXX 100644
33
+
83
--- a/target/arm/helper.c
34
val32 = float32_val(a);
84
+++ b/target/arm/helper.c
35
sbit = 0x80000000ULL & val32;
85
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
36
exp = extract32(val32, 23, 8);
86
case ARMMMUIdx_S1NSE0:
37
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
87
case ARMMMUIdx_S1NSE1:
38
return nan;
88
case ARMMMUIdx_MPriv:
89
+ case ARMMMUIdx_MNegPri:
90
case ARMMMUIdx_MUser:
91
return 1;
92
default:
93
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
94
case ARMMMUIdx_S1E2:
95
case ARMMMUIdx_S2NS:
96
case ARMMMUIdx_MPriv:
97
+ case ARMMMUIdx_MNegPri:
98
case ARMMMUIdx_MUser:
99
return false;
100
case ARMMMUIdx_S1E3:
101
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
102
ARMMMUIdx mmu_idx)
103
{
104
if (arm_feature(env, ARM_FEATURE_M)) {
105
- return !(env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_ENABLE_MASK);
106
+ switch (env->v7m.mpu_ctrl &
107
+ (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
108
+ case R_V7M_MPU_CTRL_ENABLE_MASK:
109
+ /* Enabled, but not for HardFault and NMI */
110
+ return mmu_idx == ARMMMUIdx_MNegPri;
111
+ case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
112
+ /* Enabled for all cases */
113
+ return false;
114
+ case 0:
115
+ default:
116
+ /* HFNMIENA set and ENABLE clear is UNPREDICTABLE, but
117
+ * we warned about that in armv7m_nvic.c when the guest set it.
118
+ */
119
+ return true;
120
+ }
121
}
39
}
122
40
123
if (mmu_idx == ARMMMUIdx_S2NS) {
41
+ a = float64_squash_input_denormal(a, fpst);
124
diff --git a/target/arm/translate.c b/target/arm/translate.c
42
+
125
index XXXXXXX..XXXXXXX 100644
43
val64 = float64_val(a);
126
--- a/target/arm/translate.c
44
sbit = 0x8000000000000000ULL & val64;
127
+++ b/target/arm/translate.c
45
exp = extract64(float64_val(a), 52, 11);
128
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
129
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
130
case ARMMMUIdx_MUser:
131
case ARMMMUIdx_MPriv:
132
+ case ARMMMUIdx_MNegPri:
133
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
134
case ARMMMUIdx_S2NS:
135
default:
136
--
46
--
137
2.7.4
47
2.17.1
138
48
139
49
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Add entries to MAINTAINERS to cover the newer MPS2 boards and
2
the new devices they use.
2
3
3
Temperatures can be changed from the monitor with :
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180518153157.14899-1-peter.maydell@linaro.org
6
---
7
MAINTAINERS | 9 +++++++--
8
1 file changed, 7 insertions(+), 2 deletions(-)
4
9
5
    (qemu) qom-set /machine/unattached/device[2] temperature0 12000
10
diff --git a/MAINTAINERS b/MAINTAINERS
6
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 1494827476-1487-7-git-send-email-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/aspeed.c | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/aspeed.c
12
--- a/MAINTAINERS
18
+++ b/hw/arm/aspeed.c
13
+++ b/MAINTAINERS
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
14
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
20
static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
15
F: include/hw/timer/cmsdk-apb-timer.h
21
{
16
F: hw/char/cmsdk-apb-uart.c
22
AspeedSoCState *soc = &bmc->soc;
17
F: include/hw/char/cmsdk-apb-uart.h
23
+ DeviceState *dev;
18
+F: hw/misc/tz-ppc.c
24
19
+F: include/hw/misc/tz-ppc.h
25
/* The palmetto platform expects a ds3231 RTC but a ds1338 is
20
26
* enough to provide basic RTC features. Alarms will be missing */
21
ARM cores
27
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
22
M: Peter Maydell <peter.maydell@linaro.org>
28
+
23
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
29
+ /* add a TMP423 temperature sensor */
24
L: qemu-arm@nongnu.org
30
+ dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2),
25
S: Maintained
31
+ "tmp423", 0x4c);
26
F: hw/arm/mps2.c
32
+ object_property_set_int(OBJECT(dev), 31000, "temperature0", &error_abort);
27
-F: hw/misc/mps2-scc.c
33
+ object_property_set_int(OBJECT(dev), 28000, "temperature1", &error_abort);
28
-F: include/hw/misc/mps2-scc.h
34
+ object_property_set_int(OBJECT(dev), 20000, "temperature2", &error_abort);
29
+F: hw/arm/mps2-tz.c
35
+ object_property_set_int(OBJECT(dev), 110000, "temperature3", &error_abort);
30
+F: hw/misc/mps2-*.c
36
}
31
+F: include/hw/misc/mps2-*.h
37
32
+F: hw/arm/iotkit.c
38
static void palmetto_bmc_init(MachineState *machine)
33
+F: include/hw/arm/iotkit.h
34
35
Musicpal
36
M: Jan Kiszka <jan.kiszka@web.de>
39
--
37
--
40
2.7.4
38
2.17.1
41
39
42
40
diff view generated by jsdifflib
1
icc_bpr_write() was not enforcing that writing a value below the
1
From: Jan Kiszka <jan.kiszka@siemens.com>
2
minimum for the BPR should behave as if the BPR was set to the
3
minimum value. This doesn't make a difference for the secure
4
BPRs (since we define the minimum for the QEMU implementation
5
as zero) but did mean we were allowing the NS BPR1 to be set to
6
0 when 1 should be the lowest value.
7
2
3
There was a nasty flip in identifying which register group an access is
4
targeting. The issue caused spuriously raised priorities of the guest
5
when handing CPUs over in the Jailhouse hypervisor.
6
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
9
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 1493226792-3237-3-git-send-email-peter.maydell@linaro.org
11
---
12
---
12
hw/intc/arm_gicv3_cpuif.c | 6 ++++++
13
hw/intc/arm_gicv3_cpuif.c | 12 ++++++------
13
1 file changed, 6 insertions(+)
14
1 file changed, 6 insertions(+), 6 deletions(-)
14
15
15
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/arm_gicv3_cpuif.c
18
--- a/hw/intc/arm_gicv3_cpuif.c
18
+++ b/hw/intc/arm_gicv3_cpuif.c
19
+++ b/hw/intc/arm_gicv3_cpuif.c
19
@@ -XXX,XX +XXX,XX @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
20
{
21
{
21
GICv3CPUState *cs = icc_cs_from_env(env);
22
GICv3CPUState *cs = icc_cs_from_env(env);
22
int grp = (ri->crm == 8) ? GICV3_G0 : GICV3_G1;
23
int regno = ri->opc2 & 3;
23
+ uint64_t minval;
24
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
25
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
26
uint64_t value = cs->ich_apr[grp][regno];
27
28
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
29
@@ -XXX,XX +XXX,XX @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
30
{
31
GICv3CPUState *cs = icc_cs_from_env(env);
32
int regno = ri->opc2 & 3;
33
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
34
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
35
36
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
37
38
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
uint64_t value;
40
41
int regno = ri->opc2 & 3;
42
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
43
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
24
44
25
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
45
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
26
icv_bpr_write(env, ri, value);
46
return icv_ap_read(env, ri);
27
@@ -XXX,XX +XXX,XX @@ static void icc_bpr_write(CPUARMState *env, const ARMCPRegInfo *ri,
47
@@ -XXX,XX +XXX,XX @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
28
return;
48
GICv3CPUState *cs = icc_cs_from_env(env);
29
}
49
30
50
int regno = ri->opc2 & 3;
31
+ minval = (grp == GICV3_G1NS) ? GIC_MIN_BPR_NS : GIC_MIN_BPR;
51
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
32
+ if (value < minval) {
52
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
33
+ value = minval;
53
34
+ }
54
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
35
+
55
icv_ap_write(env, ri, value);
36
cs->icc_bpr[grp] = value & 7;
56
@@ -XXX,XX +XXX,XX @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
37
gicv3_cpuif_update(cs);
57
{
38
}
58
GICv3CPUState *cs = icc_cs_from_env(env);
59
int regno = ri->opc2 & 3;
60
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
61
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
62
uint64_t value;
63
64
value = cs->ich_apr[grp][regno];
65
@@ -XXX,XX +XXX,XX @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
{
67
GICv3CPUState *cs = icc_cs_from_env(env);
68
int regno = ri->opc2 & 3;
69
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
70
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
71
72
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
73
39
--
74
--
40
2.7.4
75
2.17.1
41
76
42
77
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
2
2
3
The PMUv3 driver of linux kernel (in arch/arm64/kernel/perf_event.c)
3
It forgot to increase clroffset during the loop. So it only clear the
4
relies on the PMUVER field of id_aa64dfr0_el1 to decide if PMU support
4
first 4 bytes.
5
is present or not. This patch clears the PMUVER field under TCG mode
6
when vPMU=off. Without it, PMUv3 will init insider guest VMs even
7
with vPMU=off. This patch also removes a redundant line inside the
8
if-statement.
9
5
10
Signed-off-by: Wei Huang <wei@redhat.com>
6
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
11
Message-id: 1495123889-32301-1-git-send-email-wei@redhat.com
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
target/arm/cpu.c | 2 +-
14
hw/intc/arm_gicv3_kvm.c | 1 +
16
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+)
17
16
18
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.c
19
--- a/hw/intc/arm_gicv3_kvm.c
21
+++ b/target/arm/cpu.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
22
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
23
}
22
if (clroffset != 0) {
24
23
reg = 0;
25
if (!cpu->has_pmu) {
24
kvm_gicd_access(s, clroffset, &reg, true);
26
- cpu->has_pmu = false;
25
+ clroffset += 4;
27
unset_feature(env, ARM_FEATURE_PMU);
26
}
28
+ cpu->id_aa64dfr0 &= ~0xf00;
27
reg = *gic_bmp_ptr32(bmp, irq);
29
}
28
kvm_gicd_access(s, offset, &reg, true);
30
31
if (!arm_feature(env, ARM_FEATURE_EL2)) {
32
--
29
--
33
2.7.4
30
2.17.1
34
31
35
32
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Improve the "-d mmu" tracing for the PMSAv7 MPU translation
3
Depending on the host abi, float16, aka uint16_t, values are
4
process as an aid in debugging guest MPU configurations:
4
passed and returned either zero-extended in the host register
5
* fix a missing newline for a guest-error log
5
or with garbage at the top of the host register.
6
* report the region number with guest-error or unimp
6
7
logs of bad region register values
7
The tcg code generator has so far been assuming garbage, as that
8
* add a log message for the overall result of the lookup
8
matches the x86 abi, but this is incorrect for other host abis.
9
* print "0x" prefix for hex values
9
Further, target/arm has so far been assuming zero-extended results,
10
10
so that it may store the 16-bit value into a 32-bit slot with the
11
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
11
high 16-bits already clear.
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
12
13
Rectify both problems by mapping "f16" in the helper definition
14
to uint32_t instead of (a typedef for) uint16_t. This forces
15
the host compiler to assume garbage in the upper 16 bits on input
16
and to zero-extend the result on output.
17
18
Cc: qemu-stable@nongnu.org
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 1493122030-32191-9-git-send-email-peter.maydell@linaro.org
21
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
[PMM: a little tidyup, report region number in all messages
22
Message-id: 20180522175629.24932-1-richard.henderson@linaro.org
16
rather than just one]
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
25
---
19
target/arm/helper.c | 39 +++++++++++++++++++++++++++------------
26
include/exec/helper-head.h | 2 +-
20
1 file changed, 27 insertions(+), 12 deletions(-)
27
target/arm/helper-a64.c | 35 +++++++++--------
21
28
target/arm/helper.c | 80 +++++++++++++++++++-------------------
29
3 files changed, 59 insertions(+), 58 deletions(-)
30
31
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/exec/helper-head.h
34
+++ b/include/exec/helper-head.h
35
@@ -XXX,XX +XXX,XX @@
36
#define dh_ctype_int int
37
#define dh_ctype_i64 uint64_t
38
#define dh_ctype_s64 int64_t
39
-#define dh_ctype_f16 float16
40
+#define dh_ctype_f16 uint32_t
41
#define dh_ctype_f32 float32
42
#define dh_ctype_f64 float64
43
#define dh_ctype_ptr void *
44
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper-a64.c
47
+++ b/target/arm/helper-a64.c
48
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
49
return flags;
50
}
51
52
-uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
53
+uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
54
{
55
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
56
}
57
58
-uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
59
+uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
60
{
61
return float_rel_to_flags(float16_compare(x, y, fp_status));
62
}
63
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
64
#define float64_three make_float64(0x4008000000000000ULL)
65
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
66
67
-float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
68
+uint32_t HELPER(recpsf_f16)(uint32_t a, uint32_t b, void *fpstp)
69
{
70
float_status *fpst = fpstp;
71
72
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
73
return float64_muladd(a, b, float64_two, 0, fpst);
74
}
75
76
-float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
77
+uint32_t HELPER(rsqrtsf_f16)(uint32_t a, uint32_t b, void *fpstp)
78
{
79
float_status *fpst = fpstp;
80
81
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
82
}
83
84
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
85
-float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
86
+uint32_t HELPER(frecpx_f16)(uint32_t a, void *fpstp)
87
{
88
float_status *fpst = fpstp;
89
uint16_t val16, sbit;
90
@@ -XXX,XX +XXX,XX @@ void HELPER(casp_be_parallel)(CPUARMState *env, uint32_t rs, uint64_t addr,
91
#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
92
93
#define ADVSIMD_HALFOP(name) \
94
-float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
95
+uint32_t ADVSIMD_HELPER(name, h)(uint32_t a, uint32_t b, void *fpstp) \
96
{ \
97
float_status *fpst = fpstp; \
98
return float16_ ## name(a, b, fpst); \
99
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(mulx)
100
ADVSIMD_TWOHALFOP(mulx)
101
102
/* fused multiply-accumulate */
103
-float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
104
+uint32_t HELPER(advsimd_muladdh)(uint32_t a, uint32_t b, uint32_t c,
105
+ void *fpstp)
106
{
107
float_status *fpst = fpstp;
108
return float16_muladd(a, b, c, 0, fpst);
109
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
110
111
#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
112
113
-uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
114
+uint32_t HELPER(advsimd_ceq_f16)(uint32_t a, uint32_t b, void *fpstp)
115
{
116
float_status *fpst = fpstp;
117
int compare = float16_compare_quiet(a, b, fpst);
118
return ADVSIMD_CMPRES(compare == float_relation_equal);
119
}
120
121
-uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
122
+uint32_t HELPER(advsimd_cge_f16)(uint32_t a, uint32_t b, void *fpstp)
123
{
124
float_status *fpst = fpstp;
125
int compare = float16_compare(a, b, fpst);
126
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
127
compare == float_relation_equal);
128
}
129
130
-uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
131
+uint32_t HELPER(advsimd_cgt_f16)(uint32_t a, uint32_t b, void *fpstp)
132
{
133
float_status *fpst = fpstp;
134
int compare = float16_compare(a, b, fpst);
135
return ADVSIMD_CMPRES(compare == float_relation_greater);
136
}
137
138
-uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
139
+uint32_t HELPER(advsimd_acge_f16)(uint32_t a, uint32_t b, void *fpstp)
140
{
141
float_status *fpst = fpstp;
142
float16 f0 = float16_abs(a);
143
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
144
compare == float_relation_equal);
145
}
146
147
-uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
148
+uint32_t HELPER(advsimd_acgt_f16)(uint32_t a, uint32_t b, void *fpstp)
149
{
150
float_status *fpst = fpstp;
151
float16 f0 = float16_abs(a);
152
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
153
}
154
155
/* round to integral */
156
-float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
157
+uint32_t HELPER(advsimd_rinth_exact)(uint32_t x, void *fp_status)
158
{
159
return float16_round_to_int(x, fp_status);
160
}
161
162
-float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
163
+uint32_t HELPER(advsimd_rinth)(uint32_t x, void *fp_status)
164
{
165
int old_flags = get_float_exception_flags(fp_status), new_flags;
166
float16 ret;
167
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
168
* setting the mode appropriately before calling the helper.
169
*/
170
171
-uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
172
+uint32_t HELPER(advsimd_f16tosinth)(uint32_t a, void *fpstp)
173
{
174
float_status *fpst = fpstp;
175
176
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
177
return float16_to_int16(a, fpst);
178
}
179
180
-uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
181
+uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
182
{
183
float_status *fpst = fpstp;
184
185
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
186
* Square Root and Reciprocal square root
187
*/
188
189
-float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
190
+uint32_t HELPER(sqrt_f16)(uint32_t a, void *fpstp)
191
{
192
float_status *s = fpstp;
193
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
194
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
195
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
196
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
197
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
198
@@ -XXX,XX +XXX,XX @@ DO_VFP_cmp(d, float64)
27
}
199
28
200
/* Integer to float and float to integer conversions */
29
if (!rsize) {
201
30
- qemu_log_mask(LOG_GUEST_ERROR, "DRSR.Rsize field can not be 0");
202
-#define CONV_ITOF(name, fsz, sign) \
31
+ qemu_log_mask(LOG_GUEST_ERROR,
203
- float##fsz HELPER(name)(uint32_t x, void *fpstp) \
32
+ "DRSR[%d]: Rsize field cannot be 0\n", n);
204
-{ \
33
continue;
205
- float_status *fpst = fpstp; \
34
}
206
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
35
rsize++;
207
+#define CONV_ITOF(name, ftype, fsz, sign) \
36
rmask = (1ull << rsize) - 1;
208
+ftype HELPER(name)(uint32_t x, void *fpstp) \
37
209
+{ \
38
if (base & rmask) {
210
+ float_status *fpst = fpstp; \
39
- qemu_log_mask(LOG_GUEST_ERROR, "DRBAR %" PRIx32 " misaligned "
211
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
40
- "to DRSR region size, mask = %" PRIx32,
212
}
41
- base, rmask);
213
42
+ qemu_log_mask(LOG_GUEST_ERROR,
214
-#define CONV_FTOI(name, fsz, sign, round) \
43
+ "DRBAR[%d]: 0x%" PRIx32 " misaligned "
215
-uint32_t HELPER(name)(float##fsz x, void *fpstp) \
44
+ "to DRSR region size, mask = 0x%" PRIx32 "\n",
216
-{ \
45
+ n, base, rmask);
217
- float_status *fpst = fpstp; \
46
continue;
218
- if (float##fsz##_is_any_nan(x)) { \
47
}
219
- float_raise(float_flag_invalid, fpst); \
48
220
- return 0; \
49
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
221
- } \
50
}
222
- return float##fsz##_to_##sign##int32##round(x, fpst); \
51
}
223
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
52
if (rsize < TARGET_PAGE_BITS) {
224
+uint32_t HELPER(name)(ftype x, void *fpstp) \
53
- qemu_log_mask(LOG_UNIMP, "No support for MPU (sub)region"
225
+{ \
54
+ qemu_log_mask(LOG_UNIMP,
226
+ float_status *fpst = fpstp; \
55
+ "DRSR[%d]: No support for MPU (sub)region "
227
+ if (float##fsz##_is_any_nan(x)) { \
56
"alignment of %" PRIu32 " bits. Minimum is %d\n",
228
+ float_raise(float_flag_invalid, fpst); \
57
- rsize, TARGET_PAGE_BITS);
229
+ return 0; \
58
+ n, rsize, TARGET_PAGE_BITS);
230
+ } \
59
continue;
231
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
60
}
232
}
61
if (srdis) {
233
62
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
234
-#define FLOAT_CONVS(name, p, fsz, sign) \
63
break;
235
-CONV_ITOF(vfp_##name##to##p, fsz, sign) \
64
default:
236
-CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
65
qemu_log_mask(LOG_GUEST_ERROR,
237
-CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
66
- "Bad value for AP bits in DRACR %"
238
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
67
- PRIx32 "\n", ap);
239
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
68
+ "DRACR[%d]: Bad value for AP bits: 0x%"
240
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
69
+ PRIx32 "\n", n, ap);
241
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
70
}
242
71
} else { /* Priv. mode AP bits decoding */
243
-FLOAT_CONVS(si, h, 16, )
72
switch (ap) {
244
-FLOAT_CONVS(si, s, 32, )
73
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
245
-FLOAT_CONVS(si, d, 64, )
74
break;
246
-FLOAT_CONVS(ui, h, 16, u)
75
default:
247
-FLOAT_CONVS(ui, s, 32, u)
76
qemu_log_mask(LOG_GUEST_ERROR,
248
-FLOAT_CONVS(ui, d, 64, u)
77
- "Bad value for AP bits in DRACR %"
249
+FLOAT_CONVS(si, h, uint32_t, 16, )
78
- PRIx32 "\n", ap);
250
+FLOAT_CONVS(si, s, float32, 32, )
79
+ "DRACR[%d]: Bad value for AP bits: 0x%"
251
+FLOAT_CONVS(si, d, float64, 64, )
80
+ PRIx32 "\n", n, ap);
252
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
81
}
253
+FLOAT_CONVS(ui, s, float32, 32, u)
82
}
254
+FLOAT_CONVS(ui, d, float64, 64, u)
83
255
84
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
256
#undef CONV_ITOF
85
*/
257
#undef CONV_FTOI
86
if (arm_feature(env, ARM_FEATURE_PMSA) &&
258
@@ -XXX,XX +XXX,XX @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
87
arm_feature(env, ARM_FEATURE_V7)) {
259
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
88
+ bool ret;
260
}
89
*page_size = TARGET_PAGE_SIZE;
261
90
- return get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
262
-float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
91
- phys_ptr, prot, fsr);
263
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
92
+ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
264
{
93
+ phys_ptr, prot, fsr);
265
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
94
+ qemu_log_mask(CPU_LOG_MMU, "PMSAv7 MPU lookup for %s at 0x%08" PRIx32
266
}
95
+ " mmu_idx %u -> %s (prot %c%c%c)\n",
267
96
+ access_type == 1 ? "reading" :
268
-float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
97
+ (access_type == 2 ? "writing" : "execute"),
269
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
98
+ (uint32_t)address, mmu_idx,
270
{
99
+ ret ? "Miss" : "Hit",
271
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
100
+ *prot & PAGE_READ ? 'r' : '-',
272
}
101
+ *prot & PAGE_WRITE ? 'w' : '-',
273
102
+ *prot & PAGE_EXEC ? 'x' : '-');
274
-float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
103
+
275
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
104
+ return ret;
276
{
277
return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
278
}
279
280
-float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
281
+uint32_t HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
282
{
283
return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
284
}
285
@@ -XXX,XX +XXX,XX @@ static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
105
}
286
}
106
287
}
107
if (regime_translation_disabled(env, mmu_idx)) {
288
289
-uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
290
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
291
{
292
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
293
}
294
295
-uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
296
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
297
{
298
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
299
}
300
301
-uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
302
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
303
{
304
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
305
}
306
307
-uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
308
+uint32_t HELPER(vfp_toulh)(uint32_t x, uint32_t shift, void *fpst)
309
{
310
return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
311
}
312
313
-uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
314
+uint64_t HELPER(vfp_tosqh)(uint32_t x, uint32_t shift, void *fpst)
315
{
316
return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
317
}
318
319
-uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
320
+uint64_t HELPER(vfp_touqh)(uint32_t x, uint32_t shift, void *fpst)
321
{
322
return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
323
}
324
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(set_neon_rmode)(uint32_t rmode, CPUARMState *env)
325
}
326
327
/* Half precision conversions. */
328
-float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
329
+float32 HELPER(vfp_fcvt_f16_to_f32)(uint32_t a, void *fpstp, uint32_t ahp_mode)
330
{
331
/* Squash FZ16 to 0 for the duration of conversion. In this case,
332
* it would affect flushing input denormals.
333
@@ -XXX,XX +XXX,XX @@ float32 HELPER(vfp_fcvt_f16_to_f32)(float16 a, void *fpstp, uint32_t ahp_mode)
334
return r;
335
}
336
337
-float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
338
+uint32_t HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
339
{
340
/* Squash FZ16 to 0 for the duration of conversion. In this case,
341
* it would affect flushing output denormals.
342
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_fcvt_f32_to_f16)(float32 a, void *fpstp, uint32_t ahp_mode)
343
return r;
344
}
345
346
-float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
347
+float64 HELPER(vfp_fcvt_f16_to_f64)(uint32_t a, void *fpstp, uint32_t ahp_mode)
348
{
349
/* Squash FZ16 to 0 for the duration of conversion. In this case,
350
* it would affect flushing input denormals.
351
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_fcvt_f16_to_f64)(float16 a, void *fpstp, uint32_t ahp_mode)
352
return r;
353
}
354
355
-float16 HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
356
+uint32_t HELPER(vfp_fcvt_f64_to_f16)(float64 a, void *fpstp, uint32_t ahp_mode)
357
{
358
/* Squash FZ16 to 0 for the duration of conversion. In this case,
359
* it would affect flushing output denormals.
360
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
361
g_assert_not_reached();
362
}
363
364
-float16 HELPER(recpe_f16)(float16 input, void *fpstp)
365
+uint32_t HELPER(recpe_f16)(uint32_t input, void *fpstp)
366
{
367
float_status *fpst = fpstp;
368
float16 f16 = float16_squash_input_denormal(input, fpst);
369
@@ -XXX,XX +XXX,XX @@ static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
370
return extract64(estimate, 0, 8) << 44;
371
}
372
373
-float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
374
+uint32_t HELPER(rsqrte_f16)(uint32_t input, void *fpstp)
375
{
376
float_status *s = fpstp;
377
float16 f16 = float16_squash_input_denormal(input, s);
108
--
378
--
109
2.7.4
379
2.17.1
110
380
111
381
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Igor Mammedov <imammedo@redhat.com>
2
2
3
Multiple I2C commands can be fired simultaneously and the controller
3
When QEMU is started with following CLI
4
execute the commands following these priorities:
4
-machine virt,gic-version=3,accel=kvm -cpu host -bios AAVMF_CODE.fd
5
it crashes with abort at
6
accel/kvm/kvm-all.c:2164:
7
KVM_SET_DEVICE_ATTR failed: Group 6 attr 0x000000000000c665: Invalid argument
5
8
6
(1) Master Start Command
9
Which is caused by implicit dependency of kvm_arm_gicv3_reset() on
7
(2) Master Transmit Command
10
arm_gicv3_icc_reset() where the later is called by CPU reset
8
(3) Slave Transmit Command or Master Receive Command
11
reset callback.
9
(4) Master Stop Command
10
12
11
The current code is incorrect with respect to the above sequence and
13
However commit:
12
needs to be reworked to handle each individual command.
14
3b77f6c arm/boot: split load_dtb() from arm_load_kernel()
15
broke CPU reset callback registration in case
13
16
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
arm_load_kernel()
15
Message-id: 1494827476-1487-2-git-send-email-clg@kaod.org
18
...
19
if (!info->kernel_filename || info->firmware_loaded)
20
21
branch is taken, i.e. it's sufficient to provide a firmware
22
or do not provide kernel on CLI to skip cpu reset callback
23
registration, where before offending commit the callback
24
has been registered unconditionally.
25
26
Fix it by registering the callback right at the beginning of
27
arm_load_kernel() unconditionally instead of doing it at the end.
28
29
NOTE:
30
we probably should eliminate that dependency anyways as well as
31
separate arch CPU reset parts from arm_load_kernel() into CPU
32
itself, but that refactoring that I probably would have to do
33
anyways later for CPU hotplug to work.
34
35
Reported-by: Auger Eric <eric.auger@redhat.com>
36
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
37
Reviewed-by: Eric Auger <eric.auger@redhat.com>
38
Tested-by: Eric Auger <eric.auger@redhat.com>
39
Message-id: 1527070950-208350-1-git-send-email-imammedo@redhat.com
40
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
42
---
18
hw/i2c/aspeed_i2c.c | 24 ++++++++++++++++++------
43
hw/arm/boot.c | 18 +++++++++---------
19
1 file changed, 18 insertions(+), 6 deletions(-)
44
1 file changed, 9 insertions(+), 9 deletions(-)
20
45
21
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
46
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
22
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i2c/aspeed_i2c.c
48
--- a/hw/arm/boot.c
24
+++ b/hw/i2c/aspeed_i2c.c
49
+++ b/hw/arm/boot.c
25
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
50
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
26
51
static const ARMInsnFixup *primary_loader;
27
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
52
AddressSpace *as = arm_boot_address_space(cpu, info);
28
{
53
29
+ bus->cmd &= ~0xFFFF;
54
+ /* CPU objects (unlike devices) are not automatically reset on system
30
bus->cmd |= value & 0xFFFF;
55
+ * reset, so we must always register a handler to do so. If we're
31
bus->intr_status = 0;
56
+ * actually loading a kernel, the handler is also responsible for
32
57
+ * arranging that we start it correctly.
33
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
58
+ */
34
bus->intr_status |= I2CD_INTR_TX_ACK;
59
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
35
}
60
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
36
37
- } else if (bus->cmd & I2CD_M_TX_CMD) {
38
+ /* START command is also a TX command, as the slave address is
39
+ * sent on the bus */
40
+ bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
41
+
42
+ /* No slave found */
43
+ if (!i2c_bus_busy(bus->bus)) {
44
+ return;
45
+ }
46
+ }
61
+ }
47
+
62
+
48
+ if (bus->cmd & I2CD_M_TX_CMD) {
63
/* The board code is not supposed to set secure_board_setup unless
49
if (i2c_send(bus->bus, bus->buf)) {
64
* running its code in secure mode is actually possible, and KVM
50
bus->intr_status |= (I2CD_INTR_TX_NAK | I2CD_INTR_ABNORMAL);
65
* doesn't support secure.
51
i2c_end_transfer(bus->bus);
66
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
52
} else {
67
ARM_CPU(cs)->env.boot_info = info;
53
bus->intr_status |= I2CD_INTR_TX_ACK;
54
}
55
+ bus->cmd &= ~I2CD_M_TX_CMD;
56
+ }
57
58
- } else if (bus->cmd & I2CD_M_RX_CMD) {
59
+ if (bus->cmd & I2CD_M_RX_CMD) {
60
int ret = i2c_recv(bus->bus);
61
if (ret < 0) {
62
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
63
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
64
bus->intr_status |= I2CD_INTR_RX_DONE;
65
}
66
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
67
+ bus->cmd &= ~I2CD_M_RX_CMD;
68
}
68
}
69
69
70
if (bus->cmd & (I2CD_M_STOP_CMD | I2CD_M_S_RX_CMD_LAST)) {
70
- /* CPU objects (unlike devices) are not automatically reset on system
71
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
71
- * reset, so we must always register a handler to do so. If we're
72
i2c_end_transfer(bus->bus);
72
- * actually loading a kernel, the handler is also responsible for
73
bus->intr_status |= I2CD_INTR_NORMAL_STOP;
73
- * arranging that we start it correctly.
74
}
74
- */
75
+ bus->cmd &= ~I2CD_M_STOP_CMD;
75
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
76
}
76
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
77
- }
77
-
78
-
78
- /* command is handled, reset it and check for interrupts */
79
if (!info->skip_dtb_autoload && have_dtb(info)) {
79
- bus->cmd &= ~0xFFFF;
80
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
80
- aspeed_i2c_bus_raise_interrupt(bus);
81
exit(1);
81
}
82
83
static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
84
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
85
}
86
87
aspeed_i2c_bus_handle_cmd(bus, value);
88
+ aspeed_i2c_bus_raise_interrupt(bus);
89
break;
90
91
default:
92
--
82
--
93
2.7.4
83
2.17.1
94
84
95
85
diff view generated by jsdifflib
1
From: Kamil Rytarowski <n54@gmx.com>
1
From: Paolo Bonzini <pbonzini@redhat.com>
2
2
3
Ensure that C99 macros are defined regardless of the inclusion order of
3
cpregs_keys is an uint32_t* so the allocation should use uint32_t.
4
headers in vixl. This is required at least on NetBSD.
4
g_new is even better because it is type-safe.
5
5
6
The vixl/globals.h headers defines __STDC_CONSTANT_MACROS and must be
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
included before other system headers.
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
9
This file defines unconditionally the following macros, without altering
10
the original sources:
11
- __STDC_CONSTANT_MACROS
12
- __STDC_LIMIT_MACROS
13
- __STDC_FORMAT_MACROS
14
15
Signed-off-by: Kamil Rytarowski <n54@gmx.com>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20170514051820.15985-1-n54@gmx.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
disas/libvixl/Makefile.objs | 3 +++
11
target/arm/gdbstub.c | 3 +--
22
1 file changed, 3 insertions(+)
12
1 file changed, 1 insertion(+), 2 deletions(-)
23
13
24
diff --git a/disas/libvixl/Makefile.objs b/disas/libvixl/Makefile.objs
14
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/disas/libvixl/Makefile.objs
16
--- a/target/arm/gdbstub.c
27
+++ b/disas/libvixl/Makefile.objs
17
+++ b/target/arm/gdbstub.c
28
@@ -XXX,XX +XXX,XX @@ libvixl_OBJS = vixl/utils.o \
18
@@ -XXX,XX +XXX,XX @@ int arm_gen_dynamic_xml(CPUState *cs)
29
# The -Wno-sign-compare is needed only for gcc 4.6, which complains about
19
RegisterSysregXmlParam param = {cs, s};
30
# some signed-unsigned equality comparisons which later gcc versions do not.
20
31
$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS := -I$(SRC_PATH)/disas/libvixl $(QEMU_CFLAGS) -Wno-sign-compare
21
cpu->dyn_xml.num_cpregs = 0;
32
+# Ensure that C99 macros are defined regardless of the inclusion order of
22
- cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
33
+# headers in vixl. This is required at least on NetBSD.
23
- g_hash_table_size(cpu->cp_regs));
34
+$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_FORMAT_MACROS
24
+ cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
35
25
g_string_printf(s, "<?xml version=\"1.0\"?>");
36
common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS)
26
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
27
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
37
--
28
--
38
2.7.4
29
2.17.1
39
30
40
31
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
2
3
Don't allow load_uboot_image() to proceed when less bytes than
3
Coverity found that the string return by 'object_get_canonical_path' was not
4
header-size was read.
4
being freed at two locations in the model (CID 1391294 and CID 1391293) and
5
also that a memset was being called with a value greater than the max of a byte
6
on the second argument (CID 1391286). This patch corrects this by adding the
7
freeing of the strings and also changing to memset to zero instead on
8
descriptor unaligned errors.
5
9
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Message-id: 20170524091315.20284-1-drjones@redhat.com
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180528184859.3530-1-frasse.iglesias@gmail.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
hw/core/loader.c | 3 ++-
17
hw/dma/xlnx-zdma.c | 10 +++++++---
12
1 file changed, 2 insertions(+), 1 deletion(-)
18
1 file changed, 7 insertions(+), 3 deletions(-)
13
19
14
diff --git a/hw/core/loader.c b/hw/core/loader.c
20
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/core/loader.c
22
--- a/hw/dma/xlnx-zdma.c
17
+++ b/hw/core/loader.c
23
+++ b/hw/dma/xlnx-zdma.c
18
@@ -XXX,XX +XXX,XX @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
24
@@ -XXX,XX +XXX,XX @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
19
return -1;
25
qemu_log_mask(LOG_GUEST_ERROR,
20
26
"zdma: unaligned descriptor at %" PRIx64,
21
size = read(fd, hdr, sizeof(uboot_image_header_t));
27
addr);
22
- if (size < 0)
28
- memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
23
+ if (size < sizeof(uboot_image_header_t)) {
29
+ memset(buf, 0x0, sizeof(XlnxZDMADescr));
24
goto out;
30
s->error = true;
25
+ }
31
return false;
26
32
}
27
bswap_uboot_header(hdr);
33
@@ -XXX,XX +XXX,XX @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
28
34
RegisterInfo *r = &s->regs_info[addr / 4];
35
36
if (!r->data) {
37
+ gchar *path = object_get_canonical_path(OBJECT(s));
38
qemu_log("%s: Decode error: read from %" HWADDR_PRIx "\n",
39
- object_get_canonical_path(OBJECT(s)),
40
+ path,
41
addr);
42
+ g_free(path);
43
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
44
zdma_ch_imr_update_irq(s);
45
return 0;
46
@@ -XXX,XX +XXX,XX @@ static void zdma_write(void *opaque, hwaddr addr, uint64_t value,
47
RegisterInfo *r = &s->regs_info[addr / 4];
48
49
if (!r->data) {
50
+ gchar *path = object_get_canonical_path(OBJECT(s));
51
qemu_log("%s: Decode error: write to %" HWADDR_PRIx "=%" PRIx64 "\n",
52
- object_get_canonical_path(OBJECT(s)),
53
+ path,
54
addr, value);
55
+ g_free(path);
56
ARRAY_FIELD_DP32(s->regs, ZDMA_CH_ISR, INV_APB, true);
57
zdma_ch_imr_update_irq(s);
58
return;
29
--
59
--
30
2.7.4
60
2.17.1
31
61
32
62
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
In commit f0aff255700 we made cpacr_write() enforce that some CPACR
2
bits are RAZ/WI and some are RAO/WI for ARMv7 cores. Unfortunately
3
we forgot to also update the register's reset value. The effect
4
was that (a) a guest that read CPACR on reset would not see ones in
5
the RAO bits, and (b) if you did a migration before the guest did
6
a write to the CPACR then the migration would fail because the
7
destination would enforce the RAO bits and then complain that they
8
didn't match the zero value from the source.
2
9
3
The M series MPU is almost the same as the already implemented R
10
Implement reset for the CPACR using a custom reset function
4
profile MPU (v7 PMSA). So all we need to implement here is the MPU
11
that just calls cpacr_write(), to avoid having to duplicate
5
register interface in the system register space.
12
the logic for which bits are RAO.
6
13
7
This implementation has the same restriction as the R profile MPU
14
This bug would affect migration for TCG CPUs which are ARMv7
8
that it doesn't permit regions to be sized down smaller than 1K.
15
with VFP but without one of Neon or VFPv3.
9
16
10
We also do not yet implement support for MPU_CTRL.HFNMIENA; this
17
Reported-by: Cédric Le Goater <clg@kaod.org>
11
bit should if zero disable use of the MPU when running HardFault,
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
NMI or with FAULTMASK set to 1 (ie at an execution priority of
19
Tested-by: Cédric Le Goater <clg@kaod.org>
13
less than zero) -- if the MPU is enabled we don't treat these
20
Message-id: 20180522173713.26282-1-peter.maydell@linaro.org
14
cases any differently.
21
---
22
target/arm/helper.c | 10 +++++++++-
23
1 file changed, 9 insertions(+), 1 deletion(-)
15
24
16
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
17
Message-id: 1493122030-32191-13-git-send-email-peter.maydell@linaro.org
18
[PMM: Keep all the bits in mpu_ctrl field, rather than
19
using SCTLR bits for them; drop broken HFNMIENA support;
20
various cleanup]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
target/arm/cpu.h | 6 +++
24
hw/intc/armv7m_nvic.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++
25
target/arm/helper.c | 25 +++++++++++-
26
target/arm/machine.c | 5 ++-
27
4 files changed, 137 insertions(+), 3 deletions(-)
28
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
34
uint32_t dfsr; /* Debug Fault Status Register */
35
uint32_t mmfar; /* MemManage Fault Address */
36
uint32_t bfar; /* BusFault Address */
37
+ unsigned mpu_ctrl; /* MPU_CTRL (some bits kept in sctlr_el[1]) */
38
int exception;
39
} v7m;
40
41
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_DFSR, DWTTRAP, 2, 1)
42
FIELD(V7M_DFSR, VCATCH, 3, 1)
43
FIELD(V7M_DFSR, EXTERNAL, 4, 1)
44
45
+/* v7M MPU_CTRL bits */
46
+FIELD(V7M_MPU_CTRL, ENABLE, 0, 1)
47
+FIELD(V7M_MPU_CTRL, HFNMIENA, 1, 1)
48
+FIELD(V7M_MPU_CTRL, PRIVDEFENA, 2, 1)
49
+
50
/* If adding a feature bit which corresponds to a Linux ELF
51
* HWCAP bit, remember to update the feature-bit-to-hwcap
52
* mapping in linux-user/elfload.c:get_elf_hwcap().
53
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/intc/armv7m_nvic.c
56
+++ b/hw/intc/armv7m_nvic.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/arm/arm.h"
59
#include "hw/arm/armv7m_nvic.h"
60
#include "target/arm/cpu.h"
61
+#include "exec/exec-all.h"
62
#include "qemu/log.h"
63
#include "trace.h"
64
65
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset)
66
case 0xd70: /* ISAR4. */
67
return 0x01310102;
68
/* TODO: Implement debug registers. */
69
+ case 0xd90: /* MPU_TYPE */
70
+ /* Unified MPU; if the MPU is not present this value is zero */
71
+ return cpu->pmsav7_dregion << 8;
72
+ break;
73
+ case 0xd94: /* MPU_CTRL */
74
+ return cpu->env.v7m.mpu_ctrl;
75
+ case 0xd98: /* MPU_RNR */
76
+ return cpu->env.cp15.c6_rgnr;
77
+ case 0xd9c: /* MPU_RBAR */
78
+ case 0xda4: /* MPU_RBAR_A1 */
79
+ case 0xdac: /* MPU_RBAR_A2 */
80
+ case 0xdb4: /* MPU_RBAR_A3 */
81
+ {
82
+ int region = cpu->env.cp15.c6_rgnr;
83
+
84
+ if (region >= cpu->pmsav7_dregion) {
85
+ return 0;
86
+ }
87
+ return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf);
88
+ }
89
+ case 0xda0: /* MPU_RASR */
90
+ case 0xda8: /* MPU_RASR_A1 */
91
+ case 0xdb0: /* MPU_RASR_A2 */
92
+ case 0xdb8: /* MPU_RASR_A3 */
93
+ {
94
+ int region = cpu->env.cp15.c6_rgnr;
95
+
96
+ if (region >= cpu->pmsav7_dregion) {
97
+ return 0;
98
+ }
99
+ return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) |
100
+ (cpu->env.pmsav7.drsr[region] & 0xffff);
101
+ }
102
default:
103
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
104
return 0;
105
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value)
106
qemu_log_mask(LOG_UNIMP,
107
"NVIC: Aux fault status registers unimplemented\n");
108
break;
109
+ case 0xd90: /* MPU_TYPE */
110
+ return; /* RO */
111
+ case 0xd94: /* MPU_CTRL */
112
+ if ((value &
113
+ (R_V7M_MPU_CTRL_HFNMIENA_MASK | R_V7M_MPU_CTRL_ENABLE_MASK))
114
+ == R_V7M_MPU_CTRL_HFNMIENA_MASK) {
115
+ qemu_log_mask(LOG_GUEST_ERROR, "MPU_CTRL: HFNMIENA and !ENABLE is "
116
+ "UNPREDICTABLE\n");
117
+ }
118
+ cpu->env.v7m.mpu_ctrl = value & (R_V7M_MPU_CTRL_ENABLE_MASK |
119
+ R_V7M_MPU_CTRL_HFNMIENA_MASK |
120
+ R_V7M_MPU_CTRL_PRIVDEFENA_MASK);
121
+ tlb_flush(CPU(cpu));
122
+ break;
123
+ case 0xd98: /* MPU_RNR */
124
+ if (value >= cpu->pmsav7_dregion) {
125
+ qemu_log_mask(LOG_GUEST_ERROR, "MPU region out of range %"
126
+ PRIu32 "/%" PRIu32 "\n",
127
+ value, cpu->pmsav7_dregion);
128
+ } else {
129
+ cpu->env.cp15.c6_rgnr = value;
130
+ }
131
+ break;
132
+ case 0xd9c: /* MPU_RBAR */
133
+ case 0xda4: /* MPU_RBAR_A1 */
134
+ case 0xdac: /* MPU_RBAR_A2 */
135
+ case 0xdb4: /* MPU_RBAR_A3 */
136
+ {
137
+ int region;
138
+
139
+ if (value & (1 << 4)) {
140
+ /* VALID bit means use the region number specified in this
141
+ * value and also update MPU_RNR.REGION with that value.
142
+ */
143
+ region = extract32(value, 0, 4);
144
+ if (region >= cpu->pmsav7_dregion) {
145
+ qemu_log_mask(LOG_GUEST_ERROR,
146
+ "MPU region out of range %u/%" PRIu32 "\n",
147
+ region, cpu->pmsav7_dregion);
148
+ return;
149
+ }
150
+ cpu->env.cp15.c6_rgnr = region;
151
+ } else {
152
+ region = cpu->env.cp15.c6_rgnr;
153
+ }
154
+
155
+ if (region >= cpu->pmsav7_dregion) {
156
+ return;
157
+ }
158
+
159
+ cpu->env.pmsav7.drbar[region] = value & ~0x1f;
160
+ tlb_flush(CPU(cpu));
161
+ break;
162
+ }
163
+ case 0xda0: /* MPU_RASR */
164
+ case 0xda8: /* MPU_RASR_A1 */
165
+ case 0xdb0: /* MPU_RASR_A2 */
166
+ case 0xdb8: /* MPU_RASR_A3 */
167
+ {
168
+ int region = cpu->env.cp15.c6_rgnr;
169
+
170
+ if (region >= cpu->pmsav7_dregion) {
171
+ return;
172
+ }
173
+
174
+ cpu->env.pmsav7.drsr[region] = value & 0xff3f;
175
+ cpu->env.pmsav7.dracr[region] = (value >> 16) & 0x173f;
176
+ tlb_flush(CPU(cpu));
177
+ break;
178
+ }
179
case 0xf00: /* Software Triggered Interrupt Register */
180
{
181
/* user mode can only write to STIR if CCR.USERSETMPEND permits it */
182
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
183
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/helper.c
27
--- a/target/arm/helper.c
185
+++ b/target/arm/helper.c
28
+++ b/target/arm/helper.c
186
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_sctlr(CPUARMState *env, ARMMMUIdx mmu_idx)
29
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
187
static inline bool regime_translation_disabled(CPUARMState *env,
30
env->cp15.cpacr_el1 = value;
188
ARMMMUIdx mmu_idx)
189
{
190
+ if (arm_feature(env, ARM_FEATURE_M)) {
191
+ return !(env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_ENABLE_MASK);
192
+ }
193
+
194
if (mmu_idx == ARMMMUIdx_S2NS) {
195
return (env->cp15.hcr_el2 & HCR_VM) == 0;
196
}
197
@@ -XXX,XX +XXX,XX @@ static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
198
}
199
}
31
}
200
32
201
+static bool pmsav7_use_background_region(ARMCPU *cpu,
33
+static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
202
+ ARMMMUIdx mmu_idx, bool is_user)
203
+{
34
+{
204
+ /* Return true if we should use the default memory map as a
35
+ /* Call cpacr_write() so that we reset with the correct RAO bits set
205
+ * "background" region if there are no hits against any MPU regions.
36
+ * for our CPU features.
206
+ */
37
+ */
207
+ CPUARMState *env = &cpu->env;
38
+ cpacr_write(env, ri, 0);
208
+
209
+ if (is_user) {
210
+ return false;
211
+ }
212
+
213
+ if (arm_feature(env, ARM_FEATURE_M)) {
214
+ return env->v7m.mpu_ctrl & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
215
+ } else {
216
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
217
+ }
218
+}
39
+}
219
+
40
+
220
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
41
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
221
int access_type, ARMMMUIdx mmu_idx,
42
bool isread)
222
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
43
{
223
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
224
}
45
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
225
46
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
226
if (n == -1) { /* no hits */
47
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
227
- if (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
48
- .resetvalue = 0, .writefn = cpacr_write },
228
+ if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
49
+ .resetfn = cpacr_reset, .writefn = cpacr_write },
229
/* background fault */
50
REGINFO_SENTINEL
230
*fsr = 0;
51
};
231
return true;
52
232
diff --git a/target/arm/machine.c b/target/arm/machine.c
233
index XXXXXXX..XXXXXXX 100644
234
--- a/target/arm/machine.c
235
+++ b/target/arm/machine.c
236
@@ -XXX,XX +XXX,XX @@ static bool m_needed(void *opaque)
237
238
static const VMStateDescription vmstate_m = {
239
.name = "cpu/m",
240
- .version_id = 3,
241
- .minimum_version_id = 3,
242
+ .version_id = 4,
243
+ .minimum_version_id = 4,
244
.needed = m_needed,
245
.fields = (VMStateField[]) {
246
VMSTATE_UINT32(env.v7m.vecbase, ARMCPU),
247
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
248
VMSTATE_UINT32(env.v7m.dfsr, ARMCPU),
249
VMSTATE_UINT32(env.v7m.mmfar, ARMCPU),
250
VMSTATE_UINT32(env.v7m.bfar, ARMCPU),
251
+ VMSTATE_UINT32(env.v7m.mpu_ctrl, ARMCPU),
252
VMSTATE_INT32(env.v7m.exception, ARMCPU),
253
VMSTATE_END_OF_LIST()
254
}
255
--
53
--
256
2.7.4
54
2.17.1
257
55
258
56
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Add more detail to the documentation for memory_region_init_iommu()
2
and other IOMMU-related functions and data structures.
2
3
3
Let's add an RTC to the palmetto BMC and a LM75 temperature sensor to
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the AST2500 EVB to start with.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20180521140402.23318-2-peter.maydell@linaro.org
9
---
10
include/exec/memory.h | 105 ++++++++++++++++++++++++++++++++++++++----
11
1 file changed, 95 insertions(+), 10 deletions(-)
5
12
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
diff --git a/include/exec/memory.h b/include/exec/memory.h
7
Message-id: 1494827476-1487-5-git-send-email-clg@kaod.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/aspeed.c | 27 +++++++++++++++++++++++++++
12
1 file changed, 27 insertions(+)
13
14
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/aspeed.c
15
--- a/include/exec/memory.h
17
+++ b/hw/arm/aspeed.c
16
+++ b/include/exec/memory.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedBoardConfig {
17
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
19
const char *fmc_model;
18
IOMMU_ATTR_SPAPR_TCE_FD
20
const char *spi_model;
21
uint32_t num_cs;
22
+ void (*i2c_init)(AspeedBoardState *bmc);
23
} AspeedBoardConfig;
24
25
enum {
26
@@ -XXX,XX +XXX,XX @@ enum {
27
SCU_AST2500_HW_STRAP_ACPI_ENABLE | \
28
SCU_HW_STRAP_SPI_MODE(SCU_HW_STRAP_SPI_MASTER))
29
30
+static void palmetto_bmc_i2c_init(AspeedBoardState *bmc);
31
+static void ast2500_evb_i2c_init(AspeedBoardState *bmc);
32
+
33
static const AspeedBoardConfig aspeed_boards[] = {
34
[PALMETTO_BMC] = {
35
.soc_name = "ast2400-a1",
36
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
37
.fmc_model = "n25q256a",
38
.spi_model = "mx25l25635e",
39
.num_cs = 1,
40
+ .i2c_init = palmetto_bmc_i2c_init,
41
},
42
[AST2500_EVB] = {
43
.soc_name = "ast2500-a1",
44
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
45
.fmc_model = "n25q256a",
46
.spi_model = "mx25l25635e",
47
.num_cs = 1,
48
+ .i2c_init = ast2500_evb_i2c_init,
49
},
50
[ROMULUS_BMC] = {
51
.soc_name = "ast2500-a1",
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
53
aspeed_board_binfo.ram_size = ram_size;
54
aspeed_board_binfo.loader_start = sc->info->sdram_base;
55
56
+ if (cfg->i2c_init) {
57
+ cfg->i2c_init(bmc);
58
+ }
59
+
60
arm_load_kernel(ARM_CPU(first_cpu), &aspeed_board_binfo);
61
}
62
63
+static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
64
+{
65
+ AspeedSoCState *soc = &bmc->soc;
66
+
67
+ /* The palmetto platform expects a ds3231 RTC but a ds1338 is
68
+ * enough to provide basic RTC features. Alarms will be missing */
69
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
70
+}
71
+
72
static void palmetto_bmc_init(MachineState *machine)
73
{
74
aspeed_board_init(machine, &aspeed_boards[PALMETTO_BMC]);
75
@@ -XXX,XX +XXX,XX @@ static const TypeInfo palmetto_bmc_type = {
76
.class_init = palmetto_bmc_class_init,
77
};
19
};
78
20
79
+static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
21
+/**
80
+{
22
+ * IOMMUMemoryRegionClass:
81
+ AspeedSoCState *soc = &bmc->soc;
23
+ *
82
+
24
+ * All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
83
+ /* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
25
+ * and provide an implementation of at least the @translate method here
84
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
26
+ * to handle requests to the memory region. Other methods are optional.
85
+}
27
+ *
86
+
28
+ * The IOMMU implementation must use the IOMMU notifier infrastructure
87
static void ast2500_evb_init(MachineState *machine)
29
+ * to report whenever mappings are changed, by calling
88
{
30
+ * memory_region_notify_iommu() (or, if necessary, by calling
89
aspeed_board_init(machine, &aspeed_boards[AST2500_EVB]);
31
+ * memory_region_notify_one() for each registered notifier).
32
+ */
33
typedef struct IOMMUMemoryRegionClass {
34
/* private */
35
struct DeviceClass parent_class;
36
37
/*
38
- * Return a TLB entry that contains a given address. Flag should
39
- * be the access permission of this translation operation. We can
40
- * set flag to IOMMU_NONE to mean that we don't need any
41
- * read/write permission checks, like, when for region replay.
42
+ * Return a TLB entry that contains a given address.
43
+ *
44
+ * The IOMMUAccessFlags indicated via @flag are optional and may
45
+ * be specified as IOMMU_NONE to indicate that the caller needs
46
+ * the full translation information for both reads and writes. If
47
+ * the access flags are specified then the IOMMU implementation
48
+ * may use this as an optimization, to stop doing a page table
49
+ * walk as soon as it knows that the requested permissions are not
50
+ * allowed. If IOMMU_NONE is passed then the IOMMU must do the
51
+ * full page table walk and report the permissions in the returned
52
+ * IOMMUTLBEntry. (Note that this implies that an IOMMU may not
53
+ * return different mappings for reads and writes.)
54
+ *
55
+ * The returned information remains valid while the caller is
56
+ * holding the big QEMU lock or is inside an RCU critical section;
57
+ * if the caller wishes to cache the mapping beyond that it must
58
+ * register an IOMMU notifier so it can invalidate its cached
59
+ * information when the IOMMU mapping changes.
60
+ *
61
+ * @iommu: the IOMMUMemoryRegion
62
+ * @hwaddr: address to be translated within the memory region
63
+ * @flag: requested access permissions
64
*/
65
IOMMUTLBEntry (*translate)(IOMMUMemoryRegion *iommu, hwaddr addr,
66
IOMMUAccessFlags flag);
67
- /* Returns minimum supported page size */
68
+ /* Returns minimum supported page size in bytes.
69
+ * If this method is not provided then the minimum is assumed to
70
+ * be TARGET_PAGE_SIZE.
71
+ *
72
+ * @iommu: the IOMMUMemoryRegion
73
+ */
74
uint64_t (*get_min_page_size)(IOMMUMemoryRegion *iommu);
75
- /* Called when IOMMU Notifier flag changed */
76
+ /* Called when IOMMU Notifier flag changes (ie when the set of
77
+ * events which IOMMU users are requesting notification for changes).
78
+ * Optional method -- need not be provided if the IOMMU does not
79
+ * need to know exactly which events must be notified.
80
+ *
81
+ * @iommu: the IOMMUMemoryRegion
82
+ * @old_flags: events which previously needed to be notified
83
+ * @new_flags: events which now need to be notified
84
+ */
85
void (*notify_flag_changed)(IOMMUMemoryRegion *iommu,
86
IOMMUNotifierFlag old_flags,
87
IOMMUNotifierFlag new_flags);
88
- /* Set this up to provide customized IOMMU replay function */
89
+ /* Called to handle memory_region_iommu_replay().
90
+ *
91
+ * The default implementation of memory_region_iommu_replay() is to
92
+ * call the IOMMU translate method for every page in the address space
93
+ * with flag == IOMMU_NONE and then call the notifier if translate
94
+ * returns a valid mapping. If this method is implemented then it
95
+ * overrides the default behaviour, and must provide the full semantics
96
+ * of memory_region_iommu_replay(), by calling @notifier for every
97
+ * translation present in the IOMMU.
98
+ *
99
+ * Optional method -- an IOMMU only needs to provide this method
100
+ * if the default is inefficient or produces undesirable side effects.
101
+ *
102
+ * Note: this is not related to record-and-replay functionality.
103
+ */
104
void (*replay)(IOMMUMemoryRegion *iommu, IOMMUNotifier *notifier);
105
106
- /* Get IOMMU misc attributes */
107
- int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr,
108
+ /* Get IOMMU misc attributes. This is an optional method that
109
+ * can be used to allow users of the IOMMU to get implementation-specific
110
+ * information. The IOMMU implements this method to handle calls
111
+ * by IOMMU users to memory_region_iommu_get_attr() by filling in
112
+ * the arbitrary data pointer for any IOMMUMemoryRegionAttr values that
113
+ * the IOMMU supports. If the method is unimplemented then
114
+ * memory_region_iommu_get_attr() will always return -EINVAL.
115
+ *
116
+ * @iommu: the IOMMUMemoryRegion
117
+ * @attr: attribute being queried
118
+ * @data: memory to fill in with the attribute data
119
+ *
120
+ * Returns 0 on success, or a negative errno; in particular
121
+ * returns -EINVAL for unrecognized or unimplemented attribute types.
122
+ */
123
+ int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
124
void *data);
125
} IOMMUMemoryRegionClass;
126
127
@@ -XXX,XX +XXX,XX @@ static inline void memory_region_init_reservation(MemoryRegion *mr,
128
* An IOMMU region translates addresses and forwards accesses to a target
129
* memory region.
130
*
131
+ * The IOMMU implementation must define a subclass of TYPE_IOMMU_MEMORY_REGION.
132
+ * @_iommu_mr should be a pointer to enough memory for an instance of
133
+ * that subclass, @instance_size is the size of that subclass, and
134
+ * @mrtypename is its name. This function will initialize @_iommu_mr as an
135
+ * instance of the subclass, and its methods will then be called to handle
136
+ * accesses to the memory region. See the documentation of
137
+ * #IOMMUMemoryRegionClass for further details.
138
+ *
139
* @_iommu_mr: the #IOMMUMemoryRegion to be initialized
140
* @instance_size: the IOMMUMemoryRegion subclass instance size
141
* @mrtypename: the type name of the #IOMMUMemoryRegion
142
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
143
* a notifier with the minimum page granularity returned by
144
* mr->iommu_ops->get_page_size().
145
*
146
+ * Note: this is not related to record-and-replay functionality.
147
+ *
148
* @iommu_mr: the memory region to observe
149
* @n: the notifier to which to replay iommu mappings
150
*/
151
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
152
* memory_region_iommu_replay_all: replay existing IOMMU translations
153
* to all the notifiers registered.
154
*
155
+ * Note: this is not related to record-and-replay functionality.
156
+ *
157
* @iommu_mr: the memory region to observe
158
*/
159
void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
160
@@ -XXX,XX +XXX,XX @@ void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
161
* memory_region_iommu_get_attr: return an IOMMU attr if get_attr() is
162
* defined on the IOMMU.
163
*
164
- * Returns 0 if succeded, error code otherwise.
165
+ * Returns 0 on success, or a negative errno otherwise. In particular,
166
+ * -EINVAL indicates that the IOMMU does not support the requested
167
+ * attribute.
168
*
169
* @iommu_mr: the memory region
170
* @attr: the requested attribute
90
--
171
--
91
2.7.4
172
2.17.1
92
173
93
174
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to tb_invalidate_phys_addr().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
2
5
3
The Aspeed I2C controller maintains a state machine in the command
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
register, which is mostly used for debug.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180521140402.23318-3-peter.maydell@linaro.org
10
---
11
include/exec/exec-all.h | 5 +++--
12
accel/tcg/translate-all.c | 2 +-
13
exec.c | 2 +-
14
target/xtensa/op_helper.c | 3 ++-
15
4 files changed, 7 insertions(+), 5 deletions(-)
5
16
6
Let's start adding a few states to handle abnormal STOP
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
7
commands. Today, the model uses the busy status of the bus as a
8
condition to do so but it is not precise enough.
9
10
Also remove the ABNORMAL bit for failing TX commands. This is
11
incorrect with respect to the specs.
12
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 1494827476-1487-4-git-send-email-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/i2c/aspeed_i2c.c | 36 +++++++++++++++++++++++++++++++++---
18
1 file changed, 33 insertions(+), 3 deletions(-)
19
20
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/i2c/aspeed_i2c.c
19
--- a/include/exec/exec-all.h
23
+++ b/hw/i2c/aspeed_i2c.c
20
+++ b/include/exec/exec-all.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
22
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
23
hwaddr paddr, int prot,
24
int mmu_idx, target_ulong size);
25
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr);
26
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs);
27
void probe_write(CPUArchState *env, target_ulong addr, int size, int mmu_idx,
28
uintptr_t retaddr);
29
#else
30
@@ -XXX,XX +XXX,XX @@ static inline void tlb_flush_by_mmuidx_all_cpus_synced(CPUState *cpu,
31
uint16_t idxmap)
32
{
33
}
34
-static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
35
+static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
36
+ MemTxAttrs attrs)
37
{
38
}
39
#endif
40
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/accel/tcg/translate-all.c
43
+++ b/accel/tcg/translate-all.c
44
@@ -XXX,XX +XXX,XX @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
45
}
46
47
#if !defined(CONFIG_USER_ONLY)
48
-void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
49
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
50
{
51
ram_addr_t ram_addr;
52
MemoryRegion *mr;
53
diff --git a/exec.c b/exec.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/exec.c
56
+++ b/exec.c
57
@@ -XXX,XX +XXX,XX @@ static void breakpoint_invalidate(CPUState *cpu, target_ulong pc)
58
if (phys != -1) {
59
/* Locks grabbed by tb_invalidate_phys_addr */
60
tb_invalidate_phys_addr(cpu->cpu_ases[asidx].as,
61
- phys | (pc & ~TARGET_PAGE_MASK));
62
+ phys | (pc & ~TARGET_PAGE_MASK), attrs);
25
}
63
}
26
}
64
}
27
65
#endif
28
+static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
66
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
29
+{
67
index XXXXXXX..XXXXXXX 100644
30
+ bus->cmd &= ~(I2CD_TX_STATE_MASK << I2CD_TX_STATE_SHIFT);
68
--- a/target/xtensa/op_helper.c
31
+ bus->cmd |= (state & I2CD_TX_STATE_MASK) << I2CD_TX_STATE_SHIFT;
69
+++ b/target/xtensa/op_helper.c
32
+}
70
@@ -XXX,XX +XXX,XX @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
33
+
71
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
34
+static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
72
&paddr, &page_size, &access);
35
+{
73
if (ret == 0) {
36
+ return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
74
- tb_invalidate_phys_addr(&address_space_memory, paddr);
37
+}
75
+ tb_invalidate_phys_addr(&address_space_memory, paddr,
38
+
76
+ MEMTXATTRS_UNSPECIFIED);
39
+/*
40
+ * The state machine needs some refinement. It is only used to track
41
+ * invalid STOP commands for the moment.
42
+ */
43
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
44
{
45
bus->cmd &= ~0xFFFF;
46
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
47
bus->intr_status = 0;
48
49
if (bus->cmd & I2CD_M_START_CMD) {
50
+ uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
51
+ I2CD_MSTARTR : I2CD_MSTART;
52
+
53
+ aspeed_i2c_set_state(bus, state);
54
+
55
if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
56
extract32(bus->buf, 0, 1))) {
57
bus->intr_status |= I2CD_INTR_TX_NAK;
58
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
59
if (!i2c_bus_busy(bus->bus)) {
60
return;
61
}
62
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
63
}
64
65
if (bus->cmd & I2CD_M_TX_CMD) {
66
+ aspeed_i2c_set_state(bus, I2CD_MTXD);
67
if (i2c_send(bus->bus, bus->buf)) {
68
- bus->intr_status |= (I2CD_INTR_TX_NAK | I2CD_INTR_ABNORMAL);
69
+ bus->intr_status |= (I2CD_INTR_TX_NAK);
70
i2c_end_transfer(bus->bus);
71
} else {
72
bus->intr_status |= I2CD_INTR_TX_ACK;
73
}
74
bus->cmd &= ~I2CD_M_TX_CMD;
75
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
76
}
77
78
if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) {
79
- int ret = i2c_recv(bus->bus);
80
+ int ret;
81
+
82
+ aspeed_i2c_set_state(bus, I2CD_MRXD);
83
+ ret = i2c_recv(bus->bus);
84
if (ret < 0) {
85
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
86
ret = 0xff;
87
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
88
i2c_nack(bus->bus);
89
}
90
bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
91
+ aspeed_i2c_set_state(bus, I2CD_MACTIVE);
92
}
93
94
if (bus->cmd & I2CD_M_STOP_CMD) {
95
- if (!i2c_bus_busy(bus->bus)) {
96
+ if (!(aspeed_i2c_get_state(bus) & I2CD_MACTIVE)) {
97
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: abnormal stop\n", __func__);
98
bus->intr_status |= I2CD_INTR_ABNORMAL;
99
} else {
100
+ aspeed_i2c_set_state(bus, I2CD_MSTOP);
101
i2c_end_transfer(bus->bus);
102
bus->intr_status |= I2CD_INTR_NORMAL_STOP;
103
}
104
bus->cmd &= ~I2CD_M_STOP_CMD;
105
+ aspeed_i2c_set_state(bus, I2CD_IDLE);
106
}
77
}
107
}
78
}
108
79
109
--
80
--
110
2.7.4
81
2.17.1
111
82
112
83
diff view generated by jsdifflib
1
All M profile CPUs are PMSA, so set the feature bit.
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
(We haven't actually implemented the M profile MPU register
2
add MemTxAttrs as an argument to address_space_translate()
3
interface yet, but setting this feature bit gives us closer
3
and address_space_translate_cached(). Callers either have an
4
to correct behaviour for the MPU-disabled case.)
4
attrs value to hand, or don't care and can use MEMTXATTRS_UNSPECIFIED.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 1493122030-32191-11-git-send-email-peter.maydell@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-4-peter.maydell@linaro.org
9
---
10
---
10
target/arm/cpu.c | 8 ++++++++
11
include/exec/memory.h | 4 +++-
11
1 file changed, 8 insertions(+)
12
accel/tcg/translate-all.c | 2 +-
12
13
exec.c | 14 +++++++++-----
13
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
hw/vfio/common.c | 3 ++-
14
index XXXXXXX..XXXXXXX 100644
15
memory_ldst.inc.c | 18 +++++++++---------
15
--- a/target/arm/cpu.c
16
target/riscv/helper.c | 2 +-
16
+++ b/target/arm/cpu.c
17
6 files changed, 25 insertions(+), 18 deletions(-)
17
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_post_init(Object *obj)
18
19
diff --git a/include/exec/memory.h b/include/exec/memory.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/memory.h
22
+++ b/include/exec/memory.h
23
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
24
* #MemoryRegion.
25
* @len: pointer to length
26
* @is_write: indicates the transfer direction
27
+ * @attrs: memory attributes
28
*/
29
MemoryRegion *flatview_translate(FlatView *fv,
30
hwaddr addr, hwaddr *xlat,
31
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv,
32
33
static inline MemoryRegion *address_space_translate(AddressSpace *as,
34
hwaddr addr, hwaddr *xlat,
35
- hwaddr *len, bool is_write)
36
+ hwaddr *len, bool is_write,
37
+ MemTxAttrs attrs)
18
{
38
{
19
ARMCPU *cpu = ARM_CPU(obj);
39
return flatview_translate(address_space_to_flatview(as),
20
40
addr, xlat, len, is_write);
21
+ /* M profile implies PMSA. We have to do this here rather than
41
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
22
+ * in realize with the other feature-implication checks because
42
index XXXXXXX..XXXXXXX 100644
23
+ * we look at the PMSA bit to see if we should add some properties.
43
--- a/accel/tcg/translate-all.c
24
+ */
44
+++ b/accel/tcg/translate-all.c
25
+ if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
45
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
26
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
46
hwaddr l = 1;
27
+ }
47
28
+
48
rcu_read_lock();
29
if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
49
- mr = address_space_translate(as, addr, &addr, &l, false);
30
arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
50
+ mr = address_space_translate(as, addr, &addr, &l, false, attrs);
31
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
51
if (!(memory_region_is_ram(mr)
52
|| memory_region_is_romd(mr))) {
53
rcu_read_unlock();
54
diff --git a/exec.c b/exec.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/exec.c
57
+++ b/exec.c
58
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
59
rcu_read_lock();
60
while (len > 0) {
61
l = len;
62
- mr = address_space_translate(as, addr, &addr1, &l, true);
63
+ mr = address_space_translate(as, addr, &addr1, &l, true,
64
+ MEMTXATTRS_UNSPECIFIED);
65
66
if (!(memory_region_is_ram(mr) ||
67
memory_region_is_romd(mr))) {
68
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache)
69
*/
70
static inline MemoryRegion *address_space_translate_cached(
71
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
72
- hwaddr *plen, bool is_write)
73
+ hwaddr *plen, bool is_write, MemTxAttrs attrs)
74
{
75
MemoryRegionSection section;
76
MemoryRegion *mr;
77
@@ -XXX,XX +XXX,XX @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
78
MemoryRegion *mr;
79
80
l = len;
81
- mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
82
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
83
+ MEMTXATTRS_UNSPECIFIED);
84
flatview_read_continue(cache->fv,
85
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
86
addr1, l, mr);
87
@@ -XXX,XX +XXX,XX @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
92
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, true,
93
+ MEMTXATTRS_UNSPECIFIED);
94
flatview_write_continue(cache->fv,
95
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
96
addr1, l, mr);
97
@@ -XXX,XX +XXX,XX @@ bool cpu_physical_memory_is_io(hwaddr phys_addr)
98
99
rcu_read_lock();
100
mr = address_space_translate(&address_space_memory,
101
- phys_addr, &phys_addr, &l, false);
102
+ phys_addr, &phys_addr, &l, false,
103
+ MEMTXATTRS_UNSPECIFIED);
104
105
res = !(memory_region_is_ram(mr) || memory_region_is_romd(mr));
106
rcu_read_unlock();
107
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/vfio/common.c
110
+++ b/hw/vfio/common.c
111
@@ -XXX,XX +XXX,XX @@ static bool vfio_get_vaddr(IOMMUTLBEntry *iotlb, void **vaddr,
112
*/
113
mr = address_space_translate(&address_space_memory,
114
iotlb->translated_addr,
115
- &xlat, &len, writable);
116
+ &xlat, &len, writable,
117
+ MEMTXATTRS_UNSPECIFIED);
118
if (!memory_region_is_ram(mr)) {
119
error_report("iommu map to non memory area %"HWADDR_PRIx"",
120
xlat);
121
diff --git a/memory_ldst.inc.c b/memory_ldst.inc.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/memory_ldst.inc.c
124
+++ b/memory_ldst.inc.c
125
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
126
bool release_lock = false;
127
128
RCU_READ_LOCK();
129
- mr = TRANSLATE(addr, &addr1, &l, false);
130
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
131
if (l < 4 || !IS_DIRECT(mr, false)) {
132
release_lock |= prepare_mmio_access(mr);
133
134
@@ -XXX,XX +XXX,XX @@ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
135
bool release_lock = false;
136
137
RCU_READ_LOCK();
138
- mr = TRANSLATE(addr, &addr1, &l, false);
139
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
140
if (l < 8 || !IS_DIRECT(mr, false)) {
141
release_lock |= prepare_mmio_access(mr);
142
143
@@ -XXX,XX +XXX,XX @@ uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
144
bool release_lock = false;
145
146
RCU_READ_LOCK();
147
- mr = TRANSLATE(addr, &addr1, &l, false);
148
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
149
if (!IS_DIRECT(mr, false)) {
150
release_lock |= prepare_mmio_access(mr);
151
152
@@ -XXX,XX +XXX,XX @@ static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
153
bool release_lock = false;
154
155
RCU_READ_LOCK();
156
- mr = TRANSLATE(addr, &addr1, &l, false);
157
+ mr = TRANSLATE(addr, &addr1, &l, false, attrs);
158
if (l < 2 || !IS_DIRECT(mr, false)) {
159
release_lock |= prepare_mmio_access(mr);
160
161
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
162
bool release_lock = false;
163
164
RCU_READ_LOCK();
165
- mr = TRANSLATE(addr, &addr1, &l, true);
166
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
167
if (l < 4 || !IS_DIRECT(mr, true)) {
168
release_lock |= prepare_mmio_access(mr);
169
170
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
171
bool release_lock = false;
172
173
RCU_READ_LOCK();
174
- mr = TRANSLATE(addr, &addr1, &l, true);
175
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
176
if (l < 4 || !IS_DIRECT(mr, true)) {
177
release_lock |= prepare_mmio_access(mr);
178
179
@@ -XXX,XX +XXX,XX @@ void glue(address_space_stb, SUFFIX)(ARG1_DECL,
180
bool release_lock = false;
181
182
RCU_READ_LOCK();
183
- mr = TRANSLATE(addr, &addr1, &l, true);
184
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
185
if (!IS_DIRECT(mr, true)) {
186
release_lock |= prepare_mmio_access(mr);
187
r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
188
@@ -XXX,XX +XXX,XX @@ static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
189
bool release_lock = false;
190
191
RCU_READ_LOCK();
192
- mr = TRANSLATE(addr, &addr1, &l, true);
193
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
194
if (l < 2 || !IS_DIRECT(mr, true)) {
195
release_lock |= prepare_mmio_access(mr);
196
197
@@ -XXX,XX +XXX,XX @@ static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
198
bool release_lock = false;
199
200
RCU_READ_LOCK();
201
- mr = TRANSLATE(addr, &addr1, &l, true);
202
+ mr = TRANSLATE(addr, &addr1, &l, true, attrs);
203
if (l < 8 || !IS_DIRECT(mr, true)) {
204
release_lock |= prepare_mmio_access(mr);
205
206
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/riscv/helper.c
209
+++ b/target/riscv/helper.c
210
@@ -XXX,XX +XXX,XX @@ restart:
211
MemoryRegion *mr;
212
hwaddr l = sizeof(target_ulong), addr1;
213
mr = address_space_translate(cs->as, pte_addr,
214
- &addr1, &l, false);
215
+ &addr1, &l, false, MEMTXATTRS_UNSPECIFIED);
216
if (memory_access_is_direct(mr, true)) {
217
target_ulong *pte_pa =
218
qemu_map_ram_ptr(mr->ram_block, addr1);
32
--
219
--
33
2.7.4
220
2.17.1
34
221
35
222
diff view generated by jsdifflib
1
If the CPU is a PMSA config with no MPU implemented, then the
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
SCTLR.M bit should be RAZ/WI, so that the guest can never
2
add MemTxAttrs as an argument to address_space_map().
3
turn on the non-existent MPU.
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1493122030-32191-7-git-send-email-peter.maydell@linaro.org
9
Message-id: 20180521140402.23318-5-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper.c | 5 +++++
11
include/exec/memory.h | 3 ++-
11
1 file changed, 5 insertions(+)
12
include/sysemu/dma.h | 3 ++-
13
exec.c | 6 ++++--
14
target/ppc/mmu-hash64.c | 3 ++-
15
4 files changed, 10 insertions(+), 5 deletions(-)
12
16
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
19
--- a/include/exec/memory.h
16
+++ b/target/arm/helper.c
20
+++ b/include/exec/memory.h
17
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
18
return;
22
* @addr: address within that address space
23
* @plen: pointer to length of buffer; updated on return
24
* @is_write: indicates the transfer direction
25
+ * @attrs: memory attributes
26
*/
27
void *address_space_map(AddressSpace *as, hwaddr addr,
28
- hwaddr *plen, bool is_write);
29
+ hwaddr *plen, bool is_write, MemTxAttrs attrs);
30
31
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
32
*
33
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/sysemu/dma.h
36
+++ b/include/sysemu/dma.h
37
@@ -XXX,XX +XXX,XX @@ static inline void *dma_memory_map(AddressSpace *as,
38
hwaddr xlen = *len;
39
void *p;
40
41
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
42
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
43
+ MEMTXATTRS_UNSPECIFIED);
44
*len = xlen;
45
return p;
46
}
47
diff --git a/exec.c b/exec.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/exec.c
50
+++ b/exec.c
51
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
52
void *address_space_map(AddressSpace *as,
53
hwaddr addr,
54
hwaddr *plen,
55
- bool is_write)
56
+ bool is_write,
57
+ MemTxAttrs attrs)
58
{
59
hwaddr len = *plen;
60
hwaddr l, xlat;
61
@@ -XXX,XX +XXX,XX @@ void *cpu_physical_memory_map(hwaddr addr,
62
hwaddr *plen,
63
int is_write)
64
{
65
- return address_space_map(&address_space_memory, addr, plen, is_write);
66
+ return address_space_map(&address_space_memory, addr, plen, is_write,
67
+ MEMTXATTRS_UNSPECIFIED);
68
}
69
70
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
71
diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/ppc/mmu-hash64.c
74
+++ b/target/ppc/mmu-hash64.c
75
@@ -XXX,XX +XXX,XX @@ const ppc_hash_pte64_t *ppc_hash64_map_hptes(PowerPCCPU *cpu,
76
return NULL;
19
}
77
}
20
78
21
+ if (arm_feature(env, ARM_FEATURE_PMSA) && !cpu->has_mpu) {
79
- hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
22
+ /* M bit is RAZ/WI for PMSA with no MPU implemented */
80
+ hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
23
+ value &= ~SCTLR_M;
81
+ MEMTXATTRS_UNSPECIFIED);
24
+ }
82
if (plen < (n * HASH_PTE_SIZE_64)) {
25
+
83
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
26
raw_write(env, ri, value);
84
}
27
/* ??? Lots of these bits are not implemented. */
28
/* This may enable/disable the MMU, so do a TLB flush. */
29
--
85
--
30
2.7.4
86
2.17.1
31
87
32
88
diff view generated by jsdifflib
1
Make M profile use completely separate ARMMMUIdx values from
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
those that A profile CPUs use. This is a prelude to adding
2
add MemTxAttrs as an argument to address_space_access_valid().
3
support for the MPU and for v8M, which together will require
3
Its callers either have an attrs value to hand, or don't care
4
6 MMU indexes which don't map cleanly onto the A profile
4
and can use MEMTXATTRS_UNSPECIFIED.
5
uses:
6
non secure User
7
non secure Privileged
8
non secure Privileged, execution priority < 0
9
secure User
10
secure Privileged
11
secure Privileged, execution priority < 0
12
5
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1493122030-32191-4-git-send-email-peter.maydell@linaro.org
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-6-peter.maydell@linaro.org
15
---
10
---
16
target/arm/cpu.h | 21 +++++++++++++++++++--
11
include/exec/memory.h | 4 +++-
17
target/arm/helper.c | 5 +++++
12
include/sysemu/dma.h | 3 ++-
18
target/arm/translate.c | 3 +++
13
exec.c | 3 ++-
19
3 files changed, 27 insertions(+), 2 deletions(-)
14
target/s390x/diag.c | 6 ++++--
15
target/s390x/excp_helper.c | 3 ++-
16
target/s390x/mmu_helper.c | 3 ++-
17
target/s390x/sigp.c | 3 ++-
18
7 files changed, 17 insertions(+), 8 deletions(-)
20
19
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.h
22
--- a/include/exec/memory.h
24
+++ b/target/arm/cpu.h
23
+++ b/include/exec/memory.h
25
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
24
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
26
* of the AT/ATS operations.
25
* @addr: address within that address space
27
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
26
* @len: length of the area to be checked
27
* @is_write: indicates the transfer direction
28
+ * @attrs: memory attributes
28
*/
29
*/
29
-#define ARM_MMU_IDX_A 0x10 /* A profile (and M profile, for the moment) */
30
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
30
+#define ARM_MMU_IDX_A 0x10 /* A profile */
31
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
31
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
32
+ bool is_write, MemTxAttrs attrs);
32
+#define ARM_MMU_IDX_M 0x40 /* M profile */
33
33
34
/* address_space_map: map a physical memory region into a host virtual address
34
#define ARM_MMU_IDX_TYPE_MASK (~0x7)
35
*
35
#define ARM_MMU_IDX_COREIDX_MASK 0x7
36
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
36
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
37
index XXXXXXX..XXXXXXX 100644
37
ARMMMUIdx_S1SE0 = 4 | ARM_MMU_IDX_A,
38
--- a/include/sysemu/dma.h
38
ARMMMUIdx_S1SE1 = 5 | ARM_MMU_IDX_A,
39
+++ b/include/sysemu/dma.h
39
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
40
@@ -XXX,XX +XXX,XX @@ static inline bool dma_memory_valid(AddressSpace *as,
40
+ ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
41
DMADirection dir)
41
+ ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
42
/* Indexes below here don't have TLBs and are used only for AT system
43
* instructions or for the first stage of an S12 page table walk.
44
*/
45
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
46
ARMMMUIdxBit_S1SE0 = 1 << 4,
47
ARMMMUIdxBit_S1SE1 = 1 << 5,
48
ARMMMUIdxBit_S2NS = 1 << 6,
49
+ ARMMMUIdxBit_MUser = 1 << 0,
50
+ ARMMMUIdxBit_MPriv = 1 << 1,
51
} ARMMMUIdxBit;
52
53
#define MMU_USER_IDX 0
54
@@ -XXX,XX +XXX,XX @@ static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
55
56
static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
57
{
42
{
58
- return mmu_idx | ARM_MMU_IDX_A;
43
return address_space_access_valid(as, addr, len,
59
+ if (arm_feature(env, ARM_FEATURE_M)) {
44
- dir == DMA_DIRECTION_FROM_DEVICE);
60
+ return mmu_idx | ARM_MMU_IDX_M;
45
+ dir == DMA_DIRECTION_FROM_DEVICE,
61
+ } else {
46
+ MEMTXATTRS_UNSPECIFIED);
62
+ return mmu_idx | ARM_MMU_IDX_A;
63
+ }
64
}
47
}
65
48
66
/* Return the exception level we're running at if this is our mmu_idx */
49
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
67
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
50
diff --git a/exec.c b/exec.c
68
switch (mmu_idx & ARM_MMU_IDX_TYPE_MASK) {
51
index XXXXXXX..XXXXXXX 100644
69
case ARM_MMU_IDX_A:
52
--- a/exec.c
70
return mmu_idx & 3;
53
+++ b/exec.c
71
+ case ARM_MMU_IDX_M:
54
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
72
+ return mmu_idx & 1;
55
}
73
default:
56
74
g_assert_not_reached();
57
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
58
- int len, bool is_write)
59
+ int len, bool is_write,
60
+ MemTxAttrs attrs)
61
{
62
FlatView *fv;
63
bool result;
64
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/s390x/diag.c
67
+++ b/target/s390x/diag.c
68
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
69
return;
70
}
71
if (!address_space_access_valid(&address_space_memory, addr,
72
- sizeof(IplParameterBlock), false)) {
73
+ sizeof(IplParameterBlock), false,
74
+ MEMTXATTRS_UNSPECIFIED)) {
75
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
76
return;
77
}
78
@@ -XXX,XX +XXX,XX @@ out:
79
return;
80
}
81
if (!address_space_access_valid(&address_space_memory, addr,
82
- sizeof(IplParameterBlock), true)) {
83
+ sizeof(IplParameterBlock), true,
84
+ MEMTXATTRS_UNSPECIFIED)) {
85
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
86
return;
87
}
88
diff --git a/target/s390x/excp_helper.c b/target/s390x/excp_helper.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/s390x/excp_helper.c
91
+++ b/target/s390x/excp_helper.c
92
@@ -XXX,XX +XXX,XX @@ int s390_cpu_handle_mmu_fault(CPUState *cs, vaddr orig_vaddr, int size,
93
94
/* check out of RAM access */
95
if (!address_space_access_valid(&address_space_memory, raddr,
96
- TARGET_PAGE_SIZE, rw)) {
97
+ TARGET_PAGE_SIZE, rw,
98
+ MEMTXATTRS_UNSPECIFIED)) {
99
DPRINTF("%s: raddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
100
(uint64_t)raddr, (uint64_t)ram_size);
101
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_AUTO);
102
diff --git a/target/s390x/mmu_helper.c b/target/s390x/mmu_helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/s390x/mmu_helper.c
105
+++ b/target/s390x/mmu_helper.c
106
@@ -XXX,XX +XXX,XX @@ static int translate_pages(S390CPU *cpu, vaddr addr, int nr_pages,
107
return ret;
108
}
109
if (!address_space_access_valid(&address_space_memory, pages[i],
110
- TARGET_PAGE_SIZE, is_write)) {
111
+ TARGET_PAGE_SIZE, is_write,
112
+ MEMTXATTRS_UNSPECIFIED)) {
113
trigger_access_exception(env, PGM_ADDRESSING, ILEN_AUTO, 0);
114
return -EFAULT;
115
}
116
diff --git a/target/s390x/sigp.c b/target/s390x/sigp.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/s390x/sigp.c
119
+++ b/target/s390x/sigp.c
120
@@ -XXX,XX +XXX,XX @@ static void sigp_set_prefix(CPUState *cs, run_on_cpu_data arg)
121
cpu_synchronize_state(cs);
122
123
if (!address_space_access_valid(&address_space_memory, addr,
124
- sizeof(struct LowCore), false)) {
125
+ sizeof(struct LowCore), false,
126
+ MEMTXATTRS_UNSPECIFIED)) {
127
set_sigp_status(si, SIGP_STAT_INVALID_PARAMETER);
128
return;
75
}
129
}
76
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
77
{
78
int el = arm_current_el(env);
79
80
+ if (arm_feature(env, ARM_FEATURE_M)) {
81
+ ARMMMUIdx mmu_idx = el == 0 ? ARMMMUIdx_MUser : ARMMMUIdx_MPriv;
82
+
83
+ return arm_to_core_mmu_idx(mmu_idx);
84
+ }
85
+
86
if (el < 2 && arm_is_secure_below_el3(env)) {
87
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
88
}
89
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/target/arm/helper.c
92
+++ b/target/arm/helper.c
93
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
94
case ARMMMUIdx_S1SE1:
95
case ARMMMUIdx_S1NSE0:
96
case ARMMMUIdx_S1NSE1:
97
+ case ARMMMUIdx_MPriv:
98
+ case ARMMMUIdx_MUser:
99
return 1;
100
default:
101
g_assert_not_reached();
102
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
103
case ARMMMUIdx_S1NSE1:
104
case ARMMMUIdx_S1E2:
105
case ARMMMUIdx_S2NS:
106
+ case ARMMMUIdx_MPriv:
107
+ case ARMMMUIdx_MUser:
108
return false;
109
case ARMMMUIdx_S1E3:
110
case ARMMMUIdx_S1SE0:
111
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
112
switch (mmu_idx) {
113
case ARMMMUIdx_S1SE0:
114
case ARMMMUIdx_S1NSE0:
115
+ case ARMMMUIdx_MUser:
116
return true;
117
default:
118
return false;
119
diff --git a/target/arm/translate.c b/target/arm/translate.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/target/arm/translate.c
122
+++ b/target/arm/translate.c
123
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
124
case ARMMMUIdx_S1SE0:
125
case ARMMMUIdx_S1SE1:
126
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
127
+ case ARMMMUIdx_MUser:
128
+ case ARMMMUIdx_MPriv:
129
+ return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
130
case ARMMMUIdx_S2NS:
131
default:
132
g_assert_not_reached();
133
--
130
--
134
2.7.4
131
2.17.1
135
132
136
133
diff view generated by jsdifflib
1
Now that we enforce both:
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
* pmsav7_dregion == 0 implies has_mpu == false
2
add MemTxAttrs as an argument to flatview_extend_translation().
3
* PMSA with has_mpu == false means SCTLR.M cannot be set
3
Its callers either have an attrs value to hand, or don't care
4
we can remove a check on pmsav7_dregion from get_phys_addr_pmsav7(),
4
and can use MEMTXATTRS_UNSPECIFIED.
5
because we can only reach this code path if the MPU is enabled
6
(and so region_translation_disabled() returned false).
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 1493122030-32191-8-git-send-email-peter.maydell@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-7-peter.maydell@linaro.org
11
---
10
---
12
target/arm/helper.c | 3 +--
11
exec.c | 15 ++++++++++-----
13
1 file changed, 1 insertion(+), 2 deletions(-)
12
1 file changed, 10 insertions(+), 5 deletions(-)
14
13
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/exec.c b/exec.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
16
--- a/exec.c
18
+++ b/target/arm/helper.c
17
+++ b/exec.c
19
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
18
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
20
}
19
21
20
static hwaddr
22
if (n == -1) { /* no hits */
21
flatview_extend_translation(FlatView *fv, hwaddr addr,
23
- if (cpu->pmsav7_dregion &&
22
- hwaddr target_len,
24
- (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR))) {
23
- MemoryRegion *mr, hwaddr base, hwaddr len,
25
+ if (is_user || !(regime_sctlr(env, mmu_idx) & SCTLR_BR)) {
24
- bool is_write)
26
/* background fault */
25
+ hwaddr target_len,
27
*fsr = 0;
26
+ MemoryRegion *mr, hwaddr base, hwaddr len,
28
return true;
27
+ bool is_write, MemTxAttrs attrs)
28
{
29
hwaddr done = 0;
30
hwaddr xlat;
31
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
32
33
memory_region_ref(mr);
34
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
35
- l, is_write);
36
+ l, is_write, attrs);
37
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
38
rcu_read_unlock();
39
40
@@ -XXX,XX +XXX,XX @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
41
mr = cache->mrs.mr;
42
memory_region_ref(mr);
43
if (memory_access_is_direct(mr, is_write)) {
44
+ /* We don't care about the memory attributes here as we're only
45
+ * doing this if we found actual RAM, which behaves the same
46
+ * regardless of attributes; so UNSPECIFIED is fine.
47
+ */
48
l = flatview_extend_translation(cache->fv, addr, len, mr,
49
- cache->xlat, l, is_write);
50
+ cache->xlat, l, is_write,
51
+ MEMTXATTRS_UNSPECIFIED);
52
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
53
} else {
54
cache->ptr = NULL;
29
--
55
--
30
2.7.4
56
2.17.1
31
57
32
58
diff view generated by jsdifflib
1
ARM CPUs come in two flavours:
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
* proper MMU ("VMSA")
2
add MemTxAttrs as an argument to memory_region_access_valid().
3
* only an MPU ("PMSA")
3
Its callers either have an attrs value to hand, or don't care
4
For PMSA, the MPU may be implemented, or not (in which case there
4
and can use MEMTXATTRS_UNSPECIFIED.
5
is default "always acts the same" behaviour, but it isn't guest
6
programmable).
7
5
8
QEMU is a bit confused about how we indicate this: we have an
6
The callsite in flatview_access_valid() is part of a recursive
9
ARM_FEATURE_MPU, but it's not clear whether this indicates
7
loop flatview_access_valid() -> memory_region_access_valid() ->
10
"PMSA, not VMSA" or "PMSA and MPU present" , and sometimes we
8
subpage_accepts() -> flatview_access_valid(); we make it pass
11
use it for one purpose and sometimes the other.
9
MEMTXATTRS_UNSPECIFIED for now, until the next several commits
12
10
have plumbed an attrs parameter through the rest of the loop
13
Currently trying to implement a PMSA-without-MPU core won't
11
and we can add an attrs parameter to flatview_access_valid().
14
work correctly because we turn off the ARM_FEATURE_MPU bit
15
and then a lot of things which should still exist get
16
turned off too.
17
18
As the first step in cleaning this up, rename the feature
19
bit to ARM_FEATURE_PMSA, which indicates a PMSA CPU (with
20
or without MPU).
21
12
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
24
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 1493122030-32191-5-git-send-email-peter.maydell@linaro.org
16
Message-id: 20180521140402.23318-8-peter.maydell@linaro.org
26
---
17
---
27
target/arm/cpu.h | 2 +-
18
include/exec/memory-internal.h | 3 ++-
28
target/arm/cpu.c | 12 ++++++------
19
exec.c | 4 +++-
29
target/arm/helper.c | 12 ++++++------
20
hw/s390x/s390-pci-inst.c | 3 ++-
30
target/arm/machine.c | 2 +-
21
memory.c | 7 ++++---
31
4 files changed, 14 insertions(+), 14 deletions(-)
22
4 files changed, 11 insertions(+), 6 deletions(-)
32
23
33
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
34
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/cpu.h
26
--- a/include/exec/memory-internal.h
36
+++ b/target/arm/cpu.h
27
+++ b/include/exec/memory-internal.h
37
@@ -XXX,XX +XXX,XX @@ enum arm_features {
28
@@ -XXX,XX +XXX,XX @@ void flatview_unref(FlatView *view);
38
ARM_FEATURE_V6K,
29
extern const MemoryRegionOps unassigned_mem_ops;
39
ARM_FEATURE_V7,
30
40
ARM_FEATURE_THUMB2,
31
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
41
- ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */
32
- unsigned size, bool is_write);
42
+ ARM_FEATURE_PMSA, /* no MMU; may have Memory Protection Unit */
33
+ unsigned size, bool is_write,
43
ARM_FEATURE_VFP3,
34
+ MemTxAttrs attrs);
44
ARM_FEATURE_VFP_FP16,
35
45
ARM_FEATURE_NEON,
36
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
37
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
38
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu.c
40
--- a/exec.c
49
+++ b/target/arm/cpu.c
41
+++ b/exec.c
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_post_init(Object *obj)
42
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
51
&error_abort);
43
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
52
}
44
if (!memory_access_is_direct(mr, is_write)) {
53
45
l = memory_access_size(mr, l, addr);
54
- if (arm_feature(&cpu->env, ARM_FEATURE_MPU)) {
46
- if (!memory_region_access_valid(mr, xlat, l, is_write)) {
55
+ if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
47
+ /* When our callers all have attrs we'll pass them through here */
56
qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property,
48
+ if (!memory_region_access_valid(mr, xlat, l, is_write,
57
&error_abort);
49
+ MEMTXATTRS_UNSPECIFIED)) {
58
if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
50
return false;
59
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
51
}
60
52
}
61
if (arm_feature(env, ARM_FEATURE_V7) &&
53
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
62
!arm_feature(env, ARM_FEATURE_M) &&
63
- !arm_feature(env, ARM_FEATURE_MPU)) {
64
+ !arm_feature(env, ARM_FEATURE_PMSA)) {
65
/* v7VMSA drops support for the old ARMv5 tiny pages, so we
66
* can use 4K pages.
67
*/
68
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
69
}
70
71
if (!cpu->has_mpu) {
72
- unset_feature(env, ARM_FEATURE_MPU);
73
+ unset_feature(env, ARM_FEATURE_PMSA);
74
}
75
76
- if (arm_feature(env, ARM_FEATURE_MPU) &&
77
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
78
arm_feature(env, ARM_FEATURE_V7)) {
79
uint32_t nr = cpu->pmsav7_dregion;
80
81
@@ -XXX,XX +XXX,XX @@ static void arm946_initfn(Object *obj)
82
83
cpu->dtb_compatible = "arm,arm946";
84
set_feature(&cpu->env, ARM_FEATURE_V5);
85
- set_feature(&cpu->env, ARM_FEATURE_MPU);
86
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
87
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
88
cpu->midr = 0x41059461;
89
cpu->ctr = 0x0f004006;
90
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
91
set_feature(&cpu->env, ARM_FEATURE_THUMB_DIV);
92
set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
93
set_feature(&cpu->env, ARM_FEATURE_V7MP);
94
- set_feature(&cpu->env, ARM_FEATURE_MPU);
95
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
96
cpu->midr = 0x411fc153; /* r1p3 */
97
cpu->id_pfr0 = 0x0131;
98
cpu->id_pfr1 = 0x001;
99
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
101
--- a/target/arm/helper.c
55
--- a/hw/s390x/s390-pci-inst.c
102
+++ b/target/arm/helper.c
56
+++ b/hw/s390x/s390-pci-inst.c
103
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
57
@@ -XXX,XX +XXX,XX @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
104
{
58
mr = s390_get_subregion(mr, offset, len);
105
ARMCPU *cpu = arm_env_get_cpu(env);
59
offset -= mr->addr;
106
60
107
- if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_MPU)
61
- if (!memory_region_access_valid(mr, offset, len, true)) {
108
+ if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
62
+ if (!memory_region_access_valid(mr, offset, len, true,
109
&& !extended_addresses_enabled(env)) {
63
+ MEMTXATTRS_UNSPECIFIED)) {
110
/* For VMSA (when not using the LPAE long descriptor page table
64
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
111
* format) this register includes the ASID, so do a TLB flush.
112
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
113
define_arm_cp_regs(cpu, v6k_cp_reginfo);
114
}
115
if (arm_feature(env, ARM_FEATURE_V7MP) &&
116
- !arm_feature(env, ARM_FEATURE_MPU)) {
117
+ !arm_feature(env, ARM_FEATURE_PMSA)) {
118
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
119
}
120
if (arm_feature(env, ARM_FEATURE_V7)) {
121
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
122
}
123
}
124
125
- if (arm_feature(env, ARM_FEATURE_MPU)) {
126
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
127
if (arm_feature(env, ARM_FEATURE_V6)) {
128
/* PMSAv6 not implemented */
129
assert(arm_feature(env, ARM_FEATURE_V7));
130
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
131
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
132
}
133
define_arm_cp_regs(cpu, id_cp_reginfo);
134
- if (!arm_feature(env, ARM_FEATURE_MPU)) {
135
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
136
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
137
} else if (arm_feature(env, ARM_FEATURE_V7)) {
138
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
139
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
140
/* pmsav7 has special handling for when MPU is disabled so call it before
141
* the common MMU/MPU disabled check below.
142
*/
143
- if (arm_feature(env, ARM_FEATURE_MPU) &&
144
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
145
arm_feature(env, ARM_FEATURE_V7)) {
146
*page_size = TARGET_PAGE_SIZE;
147
return get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
148
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
149
return 0;
65
return 0;
150
}
66
}
151
67
diff --git a/memory.c b/memory.c
152
- if (arm_feature(env, ARM_FEATURE_MPU)) {
153
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
154
/* Pre-v7 MPU */
155
*page_size = TARGET_PAGE_SIZE;
156
return get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
157
diff --git a/target/arm/machine.c b/target/arm/machine.c
158
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/machine.c
69
--- a/memory.c
160
+++ b/target/arm/machine.c
70
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_needed(void *opaque)
71
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ram_device_mem_ops = {
162
ARMCPU *cpu = opaque;
72
bool memory_region_access_valid(MemoryRegion *mr,
163
CPUARMState *env = &cpu->env;
73
hwaddr addr,
164
74
unsigned size,
165
- return arm_feature(env, ARM_FEATURE_MPU) &&
75
- bool is_write)
166
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
76
+ bool is_write,
167
arm_feature(env, ARM_FEATURE_V7);
77
+ MemTxAttrs attrs)
168
}
78
{
169
79
int access_size_min, access_size_max;
80
int access_size, i;
81
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
82
{
83
MemTxResult r;
84
85
- if (!memory_region_access_valid(mr, addr, size, false)) {
86
+ if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
87
*pval = unassigned_mem_read(mr, addr, size);
88
return MEMTX_DECODE_ERROR;
89
}
90
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
91
unsigned size,
92
MemTxAttrs attrs)
93
{
94
- if (!memory_region_access_valid(mr, addr, size, true)) {
95
+ if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
96
unassigned_mem_write(mr, addr, data, size);
97
return MEMTX_DECODE_ERROR;
98
}
170
--
99
--
171
2.7.4
100
2.17.1
172
101
173
102
diff view generated by jsdifflib
1
The M profile CPU's MPU has an awkward corner case which we
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
would like to implement with a different MMU index.
2
add MemTxAttrs as an argument to the MemoryRegion valid.accepts
3
callback. We'll need this for subpage_accepts().
3
4
4
We can avoid having to bump the number of MMU modes ARM
5
We could take the approach we used with the read and write
5
uses, because some of our existing MMU indexes are only
6
callbacks and add new a new _with_attrs version, but since there
6
used by non-M-profile CPUs, so we can borrow one.
7
are so few implementations of the accepts hook we just change
7
To avoid that getting too confusing, clean up the code
8
them all.
8
to try to keep the two meanings of the index separate.
9
10
Instead of ARMMMUIdx enum values being identical to core QEMU
11
MMU index values, they are now the core index values with some
12
high bits set. Any particular CPU always uses the same high
13
bits (so eventually A profile cores and M profile cores will
14
use different bits). New functions arm_to_core_mmu_idx()
15
and core_to_arm_mmu_idx() convert between the two.
16
17
In general core index values are stored in 'int' types, and
18
ARM values are stored in ARMMMUIdx types.
19
9
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Message-id: 1493122030-32191-3-git-send-email-peter.maydell@linaro.org
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180521140402.23318-9-peter.maydell@linaro.org
22
---
14
---
23
target/arm/cpu.h | 71 ++++++++++++++++-----
15
include/exec/memory.h | 3 ++-
24
target/arm/translate.h | 2 +-
16
exec.c | 9 ++++++---
25
target/arm/helper.c | 151 ++++++++++++++++++++++++---------------------
17
hw/hppa/dino.c | 3 ++-
26
target/arm/op_helper.c | 3 +-
18
hw/nvram/fw_cfg.c | 12 ++++++++----
27
target/arm/translate-a64.c | 18 ++++--
19
hw/scsi/esp.c | 3 ++-
28
target/arm/translate.c | 10 +--
20
hw/xen/xen_pt_msi.c | 3 ++-
29
6 files changed, 156 insertions(+), 99 deletions(-)
21
memory.c | 5 +++--
22
7 files changed, 25 insertions(+), 13 deletions(-)
30
23
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/include/exec/memory.h b/include/exec/memory.h
32
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
26
--- a/include/exec/memory.h
34
+++ b/target/arm/cpu.h
27
+++ b/include/exec/memory.h
35
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
28
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
36
* for the accesses done as part of a stage 1 page table walk, rather than
29
* as a machine check exception).
37
* having to walk the stage 2 page table over and over.)
30
*/
38
*
31
bool (*accepts)(void *opaque, hwaddr addr,
39
+ * The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
32
- unsigned size, bool is_write);
40
+ * are not quite the same -- different CPU types (most notably M profile
33
+ unsigned size, bool is_write,
41
+ * vs A/R profile) would like to use MMU indexes with different semantics,
34
+ MemTxAttrs attrs);
42
+ * but since we don't ever need to use all of those in a single CPU we
35
} valid;
43
+ * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
36
/* Internal implementation constraints: */
44
+ * ARMMMUIdx are the core TLB mmu index, and the higher bits are always
37
struct {
45
+ * the same for any particular CPU.
38
diff --git a/exec.c b/exec.c
46
+ * Variables of type ARMMUIdx are always full values, and the core
39
index XXXXXXX..XXXXXXX 100644
47
+ * index values are in variables of type 'int'.
40
--- a/exec.c
48
+ *
41
+++ b/exec.c
49
* Our enumeration includes at the end some entries which are not "true"
42
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
50
* mmu_idx values in that they don't have corresponding TLBs and are only
43
}
51
* valid for doing slow path page table walks.
44
52
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
45
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
53
* of the AT/ATS operations.
46
- unsigned size, bool is_write)
54
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
47
+ unsigned size, bool is_write,
55
*/
48
+ MemTxAttrs attrs)
56
+#define ARM_MMU_IDX_A 0x10 /* A profile (and M profile, for the moment) */
57
+#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
58
+
59
+#define ARM_MMU_IDX_TYPE_MASK (~0x7)
60
+#define ARM_MMU_IDX_COREIDX_MASK 0x7
61
+
62
typedef enum ARMMMUIdx {
63
- ARMMMUIdx_S12NSE0 = 0,
64
- ARMMMUIdx_S12NSE1 = 1,
65
- ARMMMUIdx_S1E2 = 2,
66
- ARMMMUIdx_S1E3 = 3,
67
- ARMMMUIdx_S1SE0 = 4,
68
- ARMMMUIdx_S1SE1 = 5,
69
- ARMMMUIdx_S2NS = 6,
70
+ ARMMMUIdx_S12NSE0 = 0 | ARM_MMU_IDX_A,
71
+ ARMMMUIdx_S12NSE1 = 1 | ARM_MMU_IDX_A,
72
+ ARMMMUIdx_S1E2 = 2 | ARM_MMU_IDX_A,
73
+ ARMMMUIdx_S1E3 = 3 | ARM_MMU_IDX_A,
74
+ ARMMMUIdx_S1SE0 = 4 | ARM_MMU_IDX_A,
75
+ ARMMMUIdx_S1SE1 = 5 | ARM_MMU_IDX_A,
76
+ ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
77
/* Indexes below here don't have TLBs and are used only for AT system
78
* instructions or for the first stage of an S12 page table walk.
79
*/
80
- ARMMMUIdx_S1NSE0 = 7,
81
- ARMMMUIdx_S1NSE1 = 8,
82
+ ARMMMUIdx_S1NSE0 = 0 | ARM_MMU_IDX_NOTLB,
83
+ ARMMMUIdx_S1NSE1 = 1 | ARM_MMU_IDX_NOTLB,
84
} ARMMMUIdx;
85
86
+/* Bit macros for the core-mmu-index values for each index,
87
+ * for use when calling tlb_flush_by_mmuidx() and friends.
88
+ */
89
+typedef enum ARMMMUIdxBit {
90
+ ARMMMUIdxBit_S12NSE0 = 1 << 0,
91
+ ARMMMUIdxBit_S12NSE1 = 1 << 1,
92
+ ARMMMUIdxBit_S1E2 = 1 << 2,
93
+ ARMMMUIdxBit_S1E3 = 1 << 3,
94
+ ARMMMUIdxBit_S1SE0 = 1 << 4,
95
+ ARMMMUIdxBit_S1SE1 = 1 << 5,
96
+ ARMMMUIdxBit_S2NS = 1 << 6,
97
+} ARMMMUIdxBit;
98
+
99
#define MMU_USER_IDX 0
100
101
+static inline int arm_to_core_mmu_idx(ARMMMUIdx mmu_idx)
102
+{
103
+ return mmu_idx & ARM_MMU_IDX_COREIDX_MASK;
104
+}
105
+
106
+static inline ARMMMUIdx core_to_arm_mmu_idx(CPUARMState *env, int mmu_idx)
107
+{
108
+ return mmu_idx | ARM_MMU_IDX_A;
109
+}
110
+
111
/* Return the exception level we're running at if this is our mmu_idx */
112
static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
113
{
49
{
114
- assert(mmu_idx < ARMMMUIdx_S2NS);
50
return is_write;
115
- return mmu_idx & 3;
116
+ switch (mmu_idx & ARM_MMU_IDX_TYPE_MASK) {
117
+ case ARM_MMU_IDX_A:
118
+ return mmu_idx & 3;
119
+ default:
120
+ g_assert_not_reached();
121
+ }
122
}
51
}
123
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
124
/* Determine the current mmu_idx to use for normal loads/stores */
125
@@ -XXX,XX +XXX,XX @@ static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
126
int el = arm_current_el(env);
127
128
if (el < 2 && arm_is_secure_below_el3(env)) {
129
- return ARMMMUIdx_S1SE0 + el;
130
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
131
}
132
return el;
133
}
53
}
134
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
54
135
static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
static bool subpage_accepts(void *opaque, hwaddr addr,
136
target_ulong *cs_base, uint32_t *flags)
56
- unsigned len, bool is_write)
57
+ unsigned len, bool is_write,
58
+ MemTxAttrs attrs)
137
{
59
{
138
- ARMMMUIdx mmu_idx = cpu_mmu_index(env, false);
60
subpage_t *subpage = opaque;
139
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
61
#if defined(DEBUG_SUBPAGE)
140
if (is_a64(env)) {
62
@@ -XXX,XX +XXX,XX @@ static void readonly_mem_write(void *opaque, hwaddr addr,
141
*pc = env->pc;
63
}
142
*flags = ARM_TBFLAG_AARCH64_STATE_MASK;
64
143
@@ -XXX,XX +XXX,XX @@ static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
65
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
144
<< ARM_TBFLAG_XSCALE_CPAR_SHIFT);
66
- unsigned size, bool is_write)
145
}
67
+ unsigned size, bool is_write,
146
68
+ MemTxAttrs attrs)
147
- *flags |= (mmu_idx << ARM_TBFLAG_MMUIDX_SHIFT);
69
{
148
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
70
return is_write;
149
71
}
150
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
72
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
151
* states defined in the ARM ARM for software singlestep:
152
diff --git a/target/arm/translate.h b/target/arm/translate.h
153
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.h
74
--- a/hw/hppa/dino.c
155
+++ b/target/arm/translate.h
75
+++ b/hw/hppa/dino.c
156
@@ -XXX,XX +XXX,XX @@ static inline int arm_dc_feature(DisasContext *dc, int feature)
76
@@ -XXX,XX +XXX,XX @@ static void gsc_to_pci_forwarding(DinoState *s)
157
77
}
158
static inline int get_mem_index(DisasContext *s)
78
79
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
80
- unsigned size, bool is_write)
81
+ unsigned size, bool is_write,
82
+ MemTxAttrs attrs)
159
{
83
{
160
- return s->mmu_idx;
84
switch (addr) {
161
+ return arm_to_core_mmu_idx(s->mmu_idx);
85
case DINO_IAR0:
86
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/nvram/fw_cfg.c
89
+++ b/hw/nvram/fw_cfg.c
90
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_dma_mem_write(void *opaque, hwaddr addr,
162
}
91
}
163
92
164
/* Function used to determine the target exception EL when otherwise not known
93
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
165
diff --git a/target/arm/helper.c b/target/arm/helper.c
94
- unsigned size, bool is_write)
95
+ unsigned size, bool is_write,
96
+ MemTxAttrs attrs)
97
{
98
return !is_write || ((size == 4 && (addr == 0 || addr == 4)) ||
99
(size == 8 && addr == 0));
100
}
101
102
static bool fw_cfg_data_mem_valid(void *opaque, hwaddr addr,
103
- unsigned size, bool is_write)
104
+ unsigned size, bool is_write,
105
+ MemTxAttrs attrs)
106
{
107
return addr == 0;
108
}
109
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_ctl_mem_write(void *opaque, hwaddr addr,
110
}
111
112
static bool fw_cfg_ctl_mem_valid(void *opaque, hwaddr addr,
113
- unsigned size, bool is_write)
114
+ unsigned size, bool is_write,
115
+ MemTxAttrs attrs)
116
{
117
return is_write && size == 2;
118
}
119
@@ -XXX,XX +XXX,XX @@ static void fw_cfg_comb_write(void *opaque, hwaddr addr,
120
}
121
122
static bool fw_cfg_comb_valid(void *opaque, hwaddr addr,
123
- unsigned size, bool is_write)
124
+ unsigned size, bool is_write,
125
+ MemTxAttrs attrs)
126
{
127
return (size == 1) || (is_write && size == 2);
128
}
129
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
166
index XXXXXXX..XXXXXXX 100644
130
index XXXXXXX..XXXXXXX 100644
167
--- a/target/arm/helper.c
131
--- a/hw/scsi/esp.c
168
+++ b/target/arm/helper.c
132
+++ b/hw/scsi/esp.c
169
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
133
@@ -XXX,XX +XXX,XX @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
170
CPUState *cs = ENV_GET_CPU(env);
171
172
tlb_flush_by_mmuidx(cs,
173
- (1 << ARMMMUIdx_S12NSE1) |
174
- (1 << ARMMMUIdx_S12NSE0) |
175
- (1 << ARMMMUIdx_S2NS));
176
+ ARMMMUIdxBit_S12NSE1 |
177
+ ARMMMUIdxBit_S12NSE0 |
178
+ ARMMMUIdxBit_S2NS);
179
}
134
}
180
135
181
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
136
static bool esp_mem_accepts(void *opaque, hwaddr addr,
182
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
137
- unsigned size, bool is_write)
183
CPUState *cs = ENV_GET_CPU(env);
138
+ unsigned size, bool is_write,
184
139
+ MemTxAttrs attrs)
185
tlb_flush_by_mmuidx_all_cpus_synced(cs,
140
{
186
- (1 << ARMMMUIdx_S12NSE1) |
141
return (size == 1) || (is_write && size == 4);
187
- (1 << ARMMMUIdx_S12NSE0) |
188
- (1 << ARMMMUIdx_S2NS));
189
+ ARMMMUIdxBit_S12NSE1 |
190
+ ARMMMUIdxBit_S12NSE0 |
191
+ ARMMMUIdxBit_S2NS);
192
}
142
}
193
143
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
194
static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
index XXXXXXX..XXXXXXX 100644
195
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
145
--- a/hw/xen/xen_pt_msi.c
196
146
+++ b/hw/xen/xen_pt_msi.c
197
pageaddr = sextract64(value << 12, 0, 40);
147
@@ -XXX,XX +XXX,XX @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
198
199
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S2NS));
200
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
201
}
148
}
202
149
203
static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
150
static bool pci_msix_accepts(void *opaque, hwaddr addr,
204
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
151
- unsigned size, bool is_write)
205
pageaddr = sextract64(value << 12, 0, 40);
152
+ unsigned size, bool is_write,
206
153
+ MemTxAttrs attrs)
207
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
154
{
208
- (1 << ARMMMUIdx_S2NS));
155
return !(addr & (size - 1));
209
+ ARMMMUIdxBit_S2NS);
210
}
156
}
211
157
diff --git a/memory.c b/memory.c
212
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
158
index XXXXXXX..XXXXXXX 100644
213
@@ -XXX,XX +XXX,XX @@ static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
159
--- a/memory.c
160
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
162
}
163
164
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
165
- unsigned size, bool is_write)
166
+ unsigned size, bool is_write,
167
+ MemTxAttrs attrs)
214
{
168
{
215
CPUState *cs = ENV_GET_CPU(env);
169
return false;
216
217
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E2));
218
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
219
}
170
}
220
171
@@ -XXX,XX +XXX,XX @@ bool memory_region_access_valid(MemoryRegion *mr,
221
static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
172
access_size = MAX(MIN(size, access_size_max), access_size_min);
222
@@ -XXX,XX +XXX,XX @@ static void tlbiall_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
173
for (i = 0; i < size; i += access_size) {
223
{
174
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
224
CPUState *cs = ENV_GET_CPU(env);
175
- is_write)) {
225
176
+ is_write, attrs)) {
226
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E2));
177
return false;
227
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
228
}
229
230
static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
@@ -XXX,XX +XXX,XX @@ static void tlbimva_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
232
CPUState *cs = ENV_GET_CPU(env);
233
uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
234
235
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E2));
236
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
237
}
238
239
static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
240
@@ -XXX,XX +XXX,XX @@ static void tlbimva_hyp_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
241
uint64_t pageaddr = value & ~MAKE_64BIT_MASK(0, 12);
242
243
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
244
- (1 << ARMMMUIdx_S1E2));
245
+ ARMMMUIdxBit_S1E2);
246
}
247
248
static const ARMCPRegInfo cp_reginfo[] = {
249
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
250
/* Accesses to VTTBR may change the VMID so we must flush the TLB. */
251
if (raw_read(env, ri) != value) {
252
tlb_flush_by_mmuidx(cs,
253
- (1 << ARMMMUIdx_S12NSE1) |
254
- (1 << ARMMMUIdx_S12NSE0) |
255
- (1 << ARMMMUIdx_S2NS));
256
+ ARMMMUIdxBit_S12NSE1 |
257
+ ARMMMUIdxBit_S12NSE0 |
258
+ ARMMMUIdxBit_S2NS);
259
raw_write(env, ri, value);
260
}
261
}
262
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
263
264
if (arm_is_secure_below_el3(env)) {
265
tlb_flush_by_mmuidx(cs,
266
- (1 << ARMMMUIdx_S1SE1) |
267
- (1 << ARMMMUIdx_S1SE0));
268
+ ARMMMUIdxBit_S1SE1 |
269
+ ARMMMUIdxBit_S1SE0);
270
} else {
271
tlb_flush_by_mmuidx(cs,
272
- (1 << ARMMMUIdx_S12NSE1) |
273
- (1 << ARMMMUIdx_S12NSE0));
274
+ ARMMMUIdxBit_S12NSE1 |
275
+ ARMMMUIdxBit_S12NSE0);
276
}
277
}
278
279
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vmalle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
280
281
if (sec) {
282
tlb_flush_by_mmuidx_all_cpus_synced(cs,
283
- (1 << ARMMMUIdx_S1SE1) |
284
- (1 << ARMMMUIdx_S1SE0));
285
+ ARMMMUIdxBit_S1SE1 |
286
+ ARMMMUIdxBit_S1SE0);
287
} else {
288
tlb_flush_by_mmuidx_all_cpus_synced(cs,
289
- (1 << ARMMMUIdx_S12NSE1) |
290
- (1 << ARMMMUIdx_S12NSE0));
291
+ ARMMMUIdxBit_S12NSE1 |
292
+ ARMMMUIdxBit_S12NSE0);
293
}
294
}
295
296
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle1_write(CPUARMState *env, const ARMCPRegInfo *ri,
297
298
if (arm_is_secure_below_el3(env)) {
299
tlb_flush_by_mmuidx(cs,
300
- (1 << ARMMMUIdx_S1SE1) |
301
- (1 << ARMMMUIdx_S1SE0));
302
+ ARMMMUIdxBit_S1SE1 |
303
+ ARMMMUIdxBit_S1SE0);
304
} else {
305
if (arm_feature(env, ARM_FEATURE_EL2)) {
306
tlb_flush_by_mmuidx(cs,
307
- (1 << ARMMMUIdx_S12NSE1) |
308
- (1 << ARMMMUIdx_S12NSE0) |
309
- (1 << ARMMMUIdx_S2NS));
310
+ ARMMMUIdxBit_S12NSE1 |
311
+ ARMMMUIdxBit_S12NSE0 |
312
+ ARMMMUIdxBit_S2NS);
313
} else {
314
tlb_flush_by_mmuidx(cs,
315
- (1 << ARMMMUIdx_S12NSE1) |
316
- (1 << ARMMMUIdx_S12NSE0));
317
+ ARMMMUIdxBit_S12NSE1 |
318
+ ARMMMUIdxBit_S12NSE0);
319
}
178
}
320
}
179
}
321
}
322
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle2_write(CPUARMState *env, const ARMCPRegInfo *ri,
323
ARMCPU *cpu = arm_env_get_cpu(env);
324
CPUState *cs = CPU(cpu);
325
326
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E2));
327
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E2);
328
}
329
330
static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
331
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3_write(CPUARMState *env, const ARMCPRegInfo *ri,
332
ARMCPU *cpu = arm_env_get_cpu(env);
333
CPUState *cs = CPU(cpu);
334
335
- tlb_flush_by_mmuidx(cs, (1 << ARMMMUIdx_S1E3));
336
+ tlb_flush_by_mmuidx(cs, ARMMMUIdxBit_S1E3);
337
}
338
339
static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
340
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
341
342
if (sec) {
343
tlb_flush_by_mmuidx_all_cpus_synced(cs,
344
- (1 << ARMMMUIdx_S1SE1) |
345
- (1 << ARMMMUIdx_S1SE0));
346
+ ARMMMUIdxBit_S1SE1 |
347
+ ARMMMUIdxBit_S1SE0);
348
} else if (has_el2) {
349
tlb_flush_by_mmuidx_all_cpus_synced(cs,
350
- (1 << ARMMMUIdx_S12NSE1) |
351
- (1 << ARMMMUIdx_S12NSE0) |
352
- (1 << ARMMMUIdx_S2NS));
353
+ ARMMMUIdxBit_S12NSE1 |
354
+ ARMMMUIdxBit_S12NSE0 |
355
+ ARMMMUIdxBit_S2NS);
356
} else {
357
tlb_flush_by_mmuidx_all_cpus_synced(cs,
358
- (1 << ARMMMUIdx_S12NSE1) |
359
- (1 << ARMMMUIdx_S12NSE0));
360
+ ARMMMUIdxBit_S12NSE1 |
361
+ ARMMMUIdxBit_S12NSE0);
362
}
363
}
364
365
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
366
{
367
CPUState *cs = ENV_GET_CPU(env);
368
369
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E2));
370
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E2);
371
}
372
373
static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
374
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
375
{
376
CPUState *cs = ENV_GET_CPU(env);
377
378
- tlb_flush_by_mmuidx_all_cpus_synced(cs, (1 << ARMMMUIdx_S1E3));
379
+ tlb_flush_by_mmuidx_all_cpus_synced(cs, ARMMMUIdxBit_S1E3);
380
}
381
382
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
383
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
384
385
if (arm_is_secure_below_el3(env)) {
386
tlb_flush_page_by_mmuidx(cs, pageaddr,
387
- (1 << ARMMMUIdx_S1SE1) |
388
- (1 << ARMMMUIdx_S1SE0));
389
+ ARMMMUIdxBit_S1SE1 |
390
+ ARMMMUIdxBit_S1SE0);
391
} else {
392
tlb_flush_page_by_mmuidx(cs, pageaddr,
393
- (1 << ARMMMUIdx_S12NSE1) |
394
- (1 << ARMMMUIdx_S12NSE0));
395
+ ARMMMUIdxBit_S12NSE1 |
396
+ ARMMMUIdxBit_S12NSE0);
397
}
398
}
399
400
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
401
CPUState *cs = CPU(cpu);
402
uint64_t pageaddr = sextract64(value << 12, 0, 56);
403
404
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E2));
405
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E2);
406
}
407
408
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
409
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
410
CPUState *cs = CPU(cpu);
411
uint64_t pageaddr = sextract64(value << 12, 0, 56);
412
413
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S1E3));
414
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S1E3);
415
}
416
417
static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
418
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
419
420
if (sec) {
421
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
422
- (1 << ARMMMUIdx_S1SE1) |
423
- (1 << ARMMMUIdx_S1SE0));
424
+ ARMMMUIdxBit_S1SE1 |
425
+ ARMMMUIdxBit_S1SE0);
426
} else {
427
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
428
- (1 << ARMMMUIdx_S12NSE1) |
429
- (1 << ARMMMUIdx_S12NSE0));
430
+ ARMMMUIdxBit_S12NSE1 |
431
+ ARMMMUIdxBit_S12NSE0);
432
}
433
}
434
435
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
436
uint64_t pageaddr = sextract64(value << 12, 0, 56);
437
438
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
439
- (1 << ARMMMUIdx_S1E2));
440
+ ARMMMUIdxBit_S1E2);
441
}
442
443
static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
444
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
445
uint64_t pageaddr = sextract64(value << 12, 0, 56);
446
447
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
448
- (1 << ARMMMUIdx_S1E3));
449
+ ARMMMUIdxBit_S1E3);
450
}
451
452
static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
453
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
454
455
pageaddr = sextract64(value << 12, 0, 48);
456
457
- tlb_flush_page_by_mmuidx(cs, pageaddr, (1 << ARMMMUIdx_S2NS));
458
+ tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_S2NS);
459
}
460
461
static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
462
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
463
pageaddr = sextract64(value << 12, 0, 48);
464
465
tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
466
- (1 << ARMMMUIdx_S2NS));
467
+ ARMMMUIdxBit_S2NS);
468
}
469
470
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
471
@@ -XXX,XX +XXX,XX @@ static inline TCR *regime_tcr(CPUARMState *env, ARMMMUIdx mmu_idx)
472
return &env->cp15.tcr_el[regime_el(env, mmu_idx)];
473
}
474
475
+/* Convert a possible stage1+2 MMU index into the appropriate
476
+ * stage 1 MMU index
477
+ */
478
+static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
479
+{
480
+ if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
481
+ mmu_idx += (ARMMMUIdx_S1NSE0 - ARMMMUIdx_S12NSE0);
482
+ }
483
+ return mmu_idx;
484
+}
485
+
486
/* Returns TBI0 value for current regime el */
487
uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
488
{
489
@@ -XXX,XX +XXX,XX @@ uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
490
uint32_t el;
491
492
/* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
493
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
494
- */
495
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
496
- mmu_idx += ARMMMUIdx_S1NSE0;
497
- }
498
+ * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
499
+ */
500
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
501
502
tcr = regime_tcr(env, mmu_idx);
503
el = regime_el(env, mmu_idx);
504
@@ -XXX,XX +XXX,XX @@ uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
505
uint32_t el;
506
507
/* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
508
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
509
- */
510
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
511
- mmu_idx += ARMMMUIdx_S1NSE0;
512
- }
513
+ * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
514
+ */
515
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
516
517
tcr = regime_tcr(env, mmu_idx);
518
el = regime_el(env, mmu_idx);
519
@@ -XXX,XX +XXX,XX @@ static inline bool regime_using_lpae_format(CPUARMState *env,
520
* on whether the long or short descriptor format is in use. */
521
bool arm_s1_regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
522
{
523
- if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
524
- mmu_idx += ARMMMUIdx_S1NSE0;
525
- }
526
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
527
528
return regime_using_lpae_format(env, mmu_idx);
529
}
530
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
531
int ret;
532
533
ret = get_phys_addr(env, address, access_type,
534
- mmu_idx + ARMMMUIdx_S1NSE0, &ipa, attrs,
535
+ stage_1_mmu_idx(mmu_idx), &ipa, attrs,
536
prot, page_size, fsr, fi);
537
538
/* If S1 fails or S2 is disabled, return early. */
539
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
540
/*
541
* For non-EL2 CPUs a stage1+stage2 translation is just stage 1.
542
*/
543
- mmu_idx += ARMMMUIdx_S1NSE0;
544
+ mmu_idx = stage_1_mmu_idx(mmu_idx);
545
}
546
}
547
548
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
549
int ret;
550
MemTxAttrs attrs = {};
551
552
- ret = get_phys_addr(env, address, access_type, mmu_idx, &phys_addr,
553
+ ret = get_phys_addr(env, address, access_type,
554
+ core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
555
&attrs, &prot, &page_size, fsr, fi);
556
if (!ret) {
557
/* Map a single [sub]page. */
558
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
559
bool ret;
560
uint32_t fsr;
561
ARMMMUFaultInfo fi = {};
562
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
563
564
*attrs = (MemTxAttrs) {};
565
566
- ret = get_phys_addr(env, addr, 0, cpu_mmu_index(env, false), &phys_addr,
567
+ ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
568
attrs, &prot, &page_size, &fsr, &fi);
569
570
if (ret) {
571
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
572
index XXXXXXX..XXXXXXX 100644
573
--- a/target/arm/op_helper.c
574
+++ b/target/arm/op_helper.c
575
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
576
int target_el;
577
bool same_el;
578
uint32_t syn;
579
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
580
581
if (retaddr) {
582
/* now we have a real cpu fault */
583
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
584
/* the DFSR for an alignment fault depends on whether we're using
585
* the LPAE long descriptor format, or the short descriptor format
586
*/
587
- if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
588
+ if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
589
env->exception.fsr = (1 << 9) | 0x21;
590
} else {
591
env->exception.fsr = 0x1;
592
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
593
index XXXXXXX..XXXXXXX 100644
594
--- a/target/arm/translate-a64.c
595
+++ b/target/arm/translate-a64.c
596
@@ -XXX,XX +XXX,XX @@ void a64_translate_init(void)
597
offsetof(CPUARMState, exclusive_high), "exclusive_high");
598
}
599
600
-static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s)
601
+static inline int get_a64_user_mem_index(DisasContext *s)
602
{
603
- /* Return the mmu_idx to use for A64 "unprivileged load/store" insns:
604
+ /* Return the core mmu_idx to use for A64 "unprivileged load/store" insns:
605
* if EL1, access as if EL0; otherwise access at current EL
606
*/
607
+ ARMMMUIdx useridx;
608
+
609
switch (s->mmu_idx) {
610
case ARMMMUIdx_S12NSE1:
611
- return ARMMMUIdx_S12NSE0;
612
+ useridx = ARMMMUIdx_S12NSE0;
613
+ break;
614
case ARMMMUIdx_S1SE1:
615
- return ARMMMUIdx_S1SE0;
616
+ useridx = ARMMMUIdx_S1SE0;
617
+ break;
618
case ARMMMUIdx_S2NS:
619
g_assert_not_reached();
620
default:
621
- return s->mmu_idx;
622
+ useridx = s->mmu_idx;
623
+ break;
624
}
625
+ return arm_to_core_mmu_idx(useridx);
626
}
627
628
void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
629
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb)
630
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
631
dc->condexec_mask = 0;
632
dc->condexec_cond = 0;
633
- dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
634
+ dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
635
dc->tbi0 = ARM_TBFLAG_TBI0(tb->flags);
636
dc->tbi1 = ARM_TBFLAG_TBI1(tb->flags);
637
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
638
diff --git a/target/arm/translate.c b/target/arm/translate.c
639
index XXXXXXX..XXXXXXX 100644
640
--- a/target/arm/translate.c
641
+++ b/target/arm/translate.c
642
@@ -XXX,XX +XXX,XX @@ static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
643
disas_set_insn_syndrome(s, syn);
644
}
645
646
-static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
647
+static inline int get_a32_user_mem_index(DisasContext *s)
648
{
649
- /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
650
+ /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
651
* insns:
652
* if PL2, UNPREDICTABLE (we choose to implement as if PL0)
653
* otherwise, access as if at PL0.
654
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
655
case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
656
case ARMMMUIdx_S12NSE0:
657
case ARMMMUIdx_S12NSE1:
658
- return ARMMMUIdx_S12NSE0;
659
+ return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
660
case ARMMMUIdx_S1E3:
661
case ARMMMUIdx_S1SE0:
662
case ARMMMUIdx_S1SE1:
663
- return ARMMMUIdx_S1SE0;
664
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
665
case ARMMMUIdx_S2NS:
666
default:
667
g_assert_not_reached();
668
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
669
dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
670
dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
671
dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
672
- dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
673
+ dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
674
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
675
#if !defined(CONFIG_USER_ONLY)
676
dc->user = (dc->current_el == 0);
677
--
180
--
678
2.7.4
181
2.17.1
679
182
680
183
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to flatview_access_valid().
3
Its callers now all have an attrs value to hand, so we can
4
correct our earlier temporary use of MEMTXATTRS_UNSPECIFIED.
2
5
3
This is based on patch Shannon Zhao originally posted.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180521140402.23318-10-peter.maydell@linaro.org
10
---
11
exec.c | 12 +++++-------
12
1 file changed, 5 insertions(+), 7 deletions(-)
4
13
5
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
14
diff --git a/exec.c b/exec.c
6
Signed-off-by: Andrew Jones <drjones@redhat.com>
7
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
8
Message-id: 20170529173751.3443-3-drjones@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/arm/virt.c | 21 +++++++++++++++++++++
12
1 file changed, 21 insertions(+)
13
14
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/virt.c
16
--- a/exec.c
17
+++ b/hw/arm/virt.c
17
+++ b/exec.c
18
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
19
"clk24mhz");
19
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
20
qemu_fdt_setprop_cell(fdt, "/apb-pclk", "phandle", vms->clock_phandle);
20
const uint8_t *buf, int len);
21
21
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
22
+ if (have_numa_distance) {
22
- bool is_write);
23
+ int size = nb_numa_nodes * nb_numa_nodes * 3 * sizeof(uint32_t);
23
+ bool is_write, MemTxAttrs attrs);
24
+ uint32_t *matrix = g_malloc0(size);
24
25
+ int idx, i, j;
25
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
26
+
26
unsigned len, MemTxAttrs attrs)
27
+ for (i = 0; i < nb_numa_nodes; i++) {
27
@@ -XXX,XX +XXX,XX @@ static bool subpage_accepts(void *opaque, hwaddr addr,
28
+ for (j = 0; j < nb_numa_nodes; j++) {
28
#endif
29
+ idx = (i * nb_numa_nodes + j) * 3;
29
30
+ matrix[idx + 0] = cpu_to_be32(i);
30
return flatview_access_valid(subpage->fv, addr + subpage->base,
31
+ matrix[idx + 1] = cpu_to_be32(j);
31
- len, is_write);
32
+ matrix[idx + 2] = cpu_to_be32(numa_info[i].distance[j]);
32
+ len, is_write, attrs);
33
+ }
34
+ }
35
+
36
+ qemu_fdt_add_subnode(fdt, "/distance-map");
37
+ qemu_fdt_setprop_string(fdt, "/distance-map", "compatible",
38
+ "numa-distance-map-v1");
39
+ qemu_fdt_setprop(fdt, "/distance-map", "distance-matrix",
40
+ matrix, size);
41
+ g_free(matrix);
42
+ }
43
}
33
}
44
34
45
static void fdt_add_psci_node(const VirtMachineState *vms)
35
static const MemoryRegionOps subpage_ops = {
36
@@ -XXX,XX +XXX,XX @@ static void cpu_notify_map_clients(void)
37
}
38
39
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
40
- bool is_write)
41
+ bool is_write, MemTxAttrs attrs)
42
{
43
MemoryRegion *mr;
44
hwaddr l, xlat;
45
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
46
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
47
if (!memory_access_is_direct(mr, is_write)) {
48
l = memory_access_size(mr, l, addr);
49
- /* When our callers all have attrs we'll pass them through here */
50
- if (!memory_region_access_valid(mr, xlat, l, is_write,
51
- MEMTXATTRS_UNSPECIFIED)) {
52
+ if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
53
return false;
54
}
55
}
56
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
57
58
rcu_read_lock();
59
fv = address_space_to_flatview(as);
60
- result = flatview_access_valid(fv, addr, len, is_write);
61
+ result = flatview_access_valid(fv, addr, len, is_write, attrs);
62
rcu_read_unlock();
63
return result;
64
}
46
--
65
--
47
2.7.4
66
2.17.1
48
67
49
68
diff view generated by jsdifflib
1
Fix the handling of QOM properties for PMSA CPUs with no MPU:
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
2
add MemTxAttrs as an argument to flatview_translate(); all its
3
Allow no-MPU to be specified by either:
3
callers now have attrs available.
4
* has-mpu = false
5
* pmsav7_dregion = 0
6
and make setting one imply the other. Don't clear the PMSA
7
feature bit in this situation.
8
4
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 1493122030-32191-6-git-send-email-peter.maydell@linaro.org
8
Message-id: 20180521140402.23318-11-peter.maydell@linaro.org
13
---
9
---
14
target/arm/cpu.c | 8 +++++++-
10
include/exec/memory.h | 7 ++++---
15
1 file changed, 7 insertions(+), 1 deletion(-)
11
exec.c | 17 +++++++++--------
12
2 files changed, 13 insertions(+), 11 deletions(-)
16
13
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
16
--- a/include/exec/memory.h
20
+++ b/target/arm/cpu.c
17
+++ b/include/exec/memory.h
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
22
cpu->id_pfr1 &= ~0xf000;
19
*/
20
MemoryRegion *flatview_translate(FlatView *fv,
21
hwaddr addr, hwaddr *xlat,
22
- hwaddr *len, bool is_write);
23
+ hwaddr *len, bool is_write,
24
+ MemTxAttrs attrs);
25
26
static inline MemoryRegion *address_space_translate(AddressSpace *as,
27
hwaddr addr, hwaddr *xlat,
28
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
29
MemTxAttrs attrs)
30
{
31
return flatview_translate(address_space_to_flatview(as),
32
- addr, xlat, len, is_write);
33
+ addr, xlat, len, is_write, attrs);
34
}
35
36
/* address_space_access_valid: check for validity of accessing an address
37
@@ -XXX,XX +XXX,XX @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
38
rcu_read_lock();
39
fv = address_space_to_flatview(as);
40
l = len;
41
- mr = flatview_translate(fv, addr, &addr1, &l, false);
42
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
43
if (len == l && memory_access_is_direct(mr, false)) {
44
ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
45
memcpy(buf, ptr, len);
46
diff --git a/exec.c b/exec.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/exec.c
49
+++ b/exec.c
50
@@ -XXX,XX +XXX,XX @@ iotlb_fail:
51
52
/* Called from RCU critical section */
53
MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
54
- hwaddr *plen, bool is_write)
55
+ hwaddr *plen, bool is_write,
56
+ MemTxAttrs attrs)
57
{
58
MemoryRegion *mr;
59
MemoryRegionSection section;
60
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr,
61
}
62
63
l = len;
64
- mr = flatview_translate(fv, addr, &addr1, &l, true);
65
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
23
}
66
}
24
67
25
+ /* MPU can be configured out of a PMSA CPU either by setting has-mpu
68
return result;
26
+ * to false or by setting pmsav7-dregion to 0.
69
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
27
+ */
70
MemTxResult result = MEMTX_OK;
28
if (!cpu->has_mpu) {
71
29
- unset_feature(env, ARM_FEATURE_PMSA);
72
l = len;
30
+ cpu->pmsav7_dregion = 0;
73
- mr = flatview_translate(fv, addr, &addr1, &l, true);
31
+ }
74
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
32
+ if (cpu->pmsav7_dregion == 0) {
75
result = flatview_write_continue(fv, addr, attrs, buf, len,
33
+ cpu->has_mpu = false;
76
addr1, l, mr);
77
78
@@ -XXX,XX +XXX,XX @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr,
79
}
80
81
l = len;
82
- mr = flatview_translate(fv, addr, &addr1, &l, false);
83
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
34
}
84
}
35
85
36
if (arm_feature(env, ARM_FEATURE_PMSA) &&
86
return result;
87
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
88
MemoryRegion *mr;
89
90
l = len;
91
- mr = flatview_translate(fv, addr, &addr1, &l, false);
92
+ mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
93
return flatview_read_continue(fv, addr, attrs, buf, len,
94
addr1, l, mr);
95
}
96
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
97
98
while (len > 0) {
99
l = len;
100
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
101
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
102
if (!memory_access_is_direct(mr, is_write)) {
103
l = memory_access_size(mr, l, addr);
104
if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
105
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
106
107
len = target_len;
108
this_mr = flatview_translate(fv, addr, &xlat,
109
- &len, is_write);
110
+ &len, is_write, attrs);
111
if (this_mr != mr || xlat != base + done) {
112
return done;
113
}
114
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
115
l = len;
116
rcu_read_lock();
117
fv = address_space_to_flatview(as);
118
- mr = flatview_translate(fv, addr, &xlat, &l, is_write);
119
+ mr = flatview_translate(fv, addr, &xlat, &l, is_write, attrs);
120
121
if (!memory_access_is_direct(mr, is_write)) {
122
if (atomic_xchg(&bounce.in_use, true)) {
37
--
123
--
38
2.7.4
124
2.17.1
39
125
40
126
diff view generated by jsdifflib
1
When identifying the DFSR format for an alignment fault, use
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
the mmu index that we are passed, rather than calling cpu_mmu_index()
2
add MemTxAttrs as an argument to address_space_get_iotlb_entry().
3
to get the mmu index for the current CPU state. This doesn't actually
4
make any difference since the only cases where the current MMU index
5
differs from the index used for the load are the "unprivileged
6
load/store" instructions, and in that case the mmu index may
7
differ but the translation regime is the same (apart from the
8
"use from Hyp mode" case which is UNPREDICTABLE).
9
However it's the more logical thing to do.
10
3
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 1493122030-32191-2-git-send-email-peter.maydell@linaro.org
7
Message-id: 20180521140402.23318-12-peter.maydell@linaro.org
15
---
8
---
16
target/arm/op_helper.c | 2 +-
9
include/exec/memory.h | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
10
exec.c | 2 +-
11
hw/virtio/vhost.c | 3 ++-
12
3 files changed, 4 insertions(+), 3 deletions(-)
18
13
19
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/op_helper.c
16
--- a/include/exec/memory.h
22
+++ b/target/arm/op_helper.c
17
+++ b/include/exec/memory.h
23
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
18
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache);
24
/* the DFSR for an alignment fault depends on whether we're using
19
* entry. Should be called from an RCU critical section.
25
* the LPAE long descriptor format, or the short descriptor format
20
*/
26
*/
21
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
27
- if (arm_s1_regime_using_lpae_format(env, cpu_mmu_index(env, false))) {
22
- bool is_write);
28
+ if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
23
+ bool is_write, MemTxAttrs attrs);
29
env->exception.fsr = (1 << 9) | 0x21;
24
30
} else {
25
/* address_space_translate: translate an address range into an address space
31
env->exception.fsr = 0x1;
26
* into a MemoryRegion and an address range into that section. Should be
27
diff --git a/exec.c b/exec.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/exec.c
30
+++ b/exec.c
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
32
33
/* Called from RCU critical section */
34
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
35
- bool is_write)
36
+ bool is_write, MemTxAttrs attrs)
37
{
38
MemoryRegionSection section;
39
hwaddr xlat, page_mask;
40
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/virtio/vhost.c
43
+++ b/hw/virtio/vhost.c
44
@@ -XXX,XX +XXX,XX @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
45
trace_vhost_iotlb_miss(dev, 1);
46
47
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
48
- iova, write);
49
+ iova, write,
50
+ MEMTXATTRS_UNSPECIFIED);
51
if (iotlb.target_as != NULL) {
52
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
53
&uaddr, &len);
32
--
54
--
33
2.7.4
55
2.17.1
34
56
35
57
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
add MemTxAttrs as an argument to flatview_do_translate().
2
3
3
Today, the LAST command is handled with the STOP command but this is
4
incorrect. Also nack the I2C bus when a LAST is issued.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Message-id: 1494827476-1487-3-git-send-email-clg@kaod.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-13-peter.maydell@linaro.org
9
---
8
---
10
hw/i2c/aspeed_i2c.c | 9 ++++++---
9
exec.c | 9 ++++++---
11
1 file changed, 6 insertions(+), 3 deletions(-)
10
1 file changed, 6 insertions(+), 3 deletions(-)
12
11
13
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
12
diff --git a/exec.c b/exec.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/aspeed_i2c.c
14
--- a/exec.c
16
+++ b/hw/i2c/aspeed_i2c.c
15
+++ b/exec.c
17
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
16
@@ -XXX,XX +XXX,XX @@ unassigned:
18
bus->cmd &= ~I2CD_M_TX_CMD;
17
* @is_write: whether the translation operation is for write
19
}
18
* @is_mmio: whether this can be MMIO, set true if it can
20
19
* @target_as: the address space targeted by the IOMMU
21
- if (bus->cmd & I2CD_M_RX_CMD) {
20
+ * @attrs: memory transaction attributes
22
+ if (bus->cmd & (I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST)) {
21
*
23
int ret = i2c_recv(bus->bus);
22
* This function is called from RCU critical section
24
if (ret < 0) {
23
*/
25
qemu_log_mask(LOG_GUEST_ERROR, "%s: read failed\n", __func__);
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
26
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
25
hwaddr *page_mask_out,
27
bus->intr_status |= I2CD_INTR_RX_DONE;
26
bool is_write,
28
}
27
bool is_mmio,
29
bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
28
- AddressSpace **target_as)
30
- bus->cmd &= ~I2CD_M_RX_CMD;
29
+ AddressSpace **target_as,
31
+ if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
30
+ MemTxAttrs attrs)
32
+ i2c_nack(bus->bus);
31
{
33
+ }
32
MemoryRegionSection *section;
34
+ bus->cmd &= ~(I2CD_M_RX_CMD | I2CD_M_S_RX_CMD_LAST);
33
IOMMUMemoryRegion *iommu_mr;
35
}
34
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
36
35
* but page mask.
37
- if (bus->cmd & (I2CD_M_STOP_CMD | I2CD_M_S_RX_CMD_LAST)) {
36
*/
38
+ if (bus->cmd & I2CD_M_STOP_CMD) {
37
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
39
if (!i2c_bus_busy(bus->bus)) {
38
- NULL, &page_mask, is_write, false, &as);
40
bus->intr_status |= I2CD_INTR_ABNORMAL;
39
+ NULL, &page_mask, is_write, false, &as,
41
} else {
40
+ attrs);
41
42
/* Illegal translation */
43
if (section.mr == &io_mem_unassigned) {
44
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
45
46
/* This can be MMIO, so setup MMIO bit. */
47
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
48
- is_write, true, &as);
49
+ is_write, true, &as, attrs);
50
mr = section.mr;
51
52
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
42
--
53
--
43
2.7.4
54
2.17.1
44
55
45
56
diff view generated by jsdifflib
1
When we calculate the mask to use to get the group priority from
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
2
an interrupt priority, the way that NS BPR1 is handled differs
2
add MemTxAttrs as an argument to address_space_translate_iommu().
3
from how BPR0 and S BPR1 work -- a BPR1 value of 1 means
4
the group priority is in bits [7:1], whereas for BPR0 and S BPR1
5
this is indicated by a 0 BPR value.
6
7
Subtract 1 from the BPR value before creating the mask if
8
we're using the NS BPR value, for both hardware and virtual
9
interrupts, as the GICv3 pseudocode does, and fix the comments
10
accordingly.
11
3
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 1493226792-3237-4-git-send-email-peter.maydell@linaro.org
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180521140402.23318-14-peter.maydell@linaro.org
15
---
8
---
16
hw/intc/arm_gicv3_cpuif.c | 42 ++++++++++++++++++++++++++++++++++++++----
9
exec.c | 8 +++++---
17
1 file changed, 38 insertions(+), 4 deletions(-)
10
1 file changed, 5 insertions(+), 3 deletions(-)
18
11
19
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
12
diff --git a/exec.c b/exec.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/arm_gicv3_cpuif.c
14
--- a/exec.c
22
+++ b/hw/intc/arm_gicv3_cpuif.c
15
+++ b/exec.c
23
@@ -XXX,XX +XXX,XX @@ static uint32_t icv_gprio_mask(GICv3CPUState *cs, int group)
16
@@ -XXX,XX +XXX,XX @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
17
* @is_write: whether the translation operation is for write
18
* @is_mmio: whether this can be MMIO, set true if it can
19
* @target_as: the address space targeted by the IOMMU
20
+ * @attrs: transaction attributes
21
*
22
* This function is called from RCU critical section. It is the common
23
* part of flatview_do_translate and address_space_translate_cached.
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
25
hwaddr *page_mask_out,
26
bool is_write,
27
bool is_mmio,
28
- AddressSpace **target_as)
29
+ AddressSpace **target_as,
30
+ MemTxAttrs attrs)
24
{
31
{
25
/* Return a mask word which clears the subpriority bits from
32
MemoryRegionSection *section;
26
* a priority value for a virtual interrupt in the specified group.
33
hwaddr page_mask = (hwaddr)-1;
27
- * This depends on the VBPR value:
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
28
+ * This depends on the VBPR value.
35
return address_space_translate_iommu(iommu_mr, xlat,
29
+ * If using VBPR0 then:
36
plen_out, page_mask_out,
30
* a BPR of 0 means the group priority bits are [7:1];
37
is_write, is_mmio,
31
* a BPR of 1 means they are [7:2], and so on down to
38
- target_as);
32
* a BPR of 7 meaning no group priority bits at all.
39
+ target_as, attrs);
33
+ * If using VBPR1 then:
34
+ * a BPR of 0 is impossible (the minimum value is 1)
35
+ * a BPR of 1 means the group priority bits are [7:1];
36
+ * a BPR of 2 means they are [7:2], and so on down to
37
+ * a BPR of 7 meaning the group priority is [7].
38
+ *
39
* Which BPR to use depends on the group of the interrupt and
40
* the current ICH_VMCR_EL2.VCBPR settings.
41
+ *
42
+ * This corresponds to the VGroupBits() pseudocode.
43
*/
44
+ int bpr;
45
+
46
if (group == GICV3_G1NS && cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) {
47
group = GICV3_G0;
48
}
40
}
49
41
if (page_mask_out) {
50
- return ~0U << (read_vbpr(cs, group) + 1);
42
/* Not behind an IOMMU, use default page size. */
51
+ bpr = read_vbpr(cs, group);
43
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate_cached(
52
+ if (group == GICV3_G1NS) {
44
53
+ assert(bpr > 0);
45
section = address_space_translate_iommu(iommu_mr, xlat, plen,
54
+ bpr--;
46
NULL, is_write, true,
55
+ }
47
- &target_as);
56
+
48
+ &target_as, attrs);
57
+ return ~0U << (bpr + 1);
49
return section.mr;
58
}
50
}
59
51
60
static bool icv_hppi_can_preempt(GICv3CPUState *cs, uint64_t lr)
61
@@ -XXX,XX +XXX,XX @@ static uint32_t icc_gprio_mask(GICv3CPUState *cs, int group)
62
{
63
/* Return a mask word which clears the subpriority bits from
64
* a priority value for an interrupt in the specified group.
65
- * This depends on the BPR value:
66
+ * This depends on the BPR value. For CBPR0 (S or NS):
67
* a BPR of 0 means the group priority bits are [7:1];
68
* a BPR of 1 means they are [7:2], and so on down to
69
* a BPR of 7 meaning no group priority bits at all.
70
+ * For CBPR1 NS:
71
+ * a BPR of 0 is impossible (the minimum value is 1)
72
+ * a BPR of 1 means the group priority bits are [7:1];
73
+ * a BPR of 2 means they are [7:2], and so on down to
74
+ * a BPR of 7 meaning the group priority is [7].
75
+ *
76
* Which BPR to use depends on the group of the interrupt and
77
* the current ICC_CTLR.CBPR settings.
78
+ *
79
+ * This corresponds to the GroupBits() pseudocode.
80
*/
81
+ int bpr;
82
+
83
if ((group == GICV3_G1 && cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR) ||
84
(group == GICV3_G1NS &&
85
cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) {
86
group = GICV3_G0;
87
}
88
89
- return ~0U << ((cs->icc_bpr[group] & 7) + 1);
90
+ bpr = cs->icc_bpr[group] & 7;
91
+
92
+ if (group == GICV3_G1NS) {
93
+ assert(bpr > 0);
94
+ bpr--;
95
+ }
96
+
97
+ return ~0U << (bpr + 1);
98
}
99
100
static bool icc_no_enabled_hppi(GICv3CPUState *cs)
101
--
52
--
102
2.7.4
53
2.17.1
103
54
104
55
diff view generated by jsdifflib
1
We were setting the VBPR1 field of VMCR_EL2 to icv_min_vbpr()
1
Provide a VMSTATE_BOOL_SUB_ARRAY to go with VMSTATE_UINT8_SUB_ARRAY
2
on reset, but this is not correct. The field should reset to
2
and friends.
3
the minimum value of ICV_BPR0_EL1 plus one.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 1493226792-3237-2-git-send-email-peter.maydell@linaro.org
6
Message-id: 20180521140402.23318-23-peter.maydell@linaro.org
8
---
7
---
9
hw/intc/arm_gicv3_cpuif.c | 2 +-
8
include/migration/vmstate.h | 3 +++
10
1 file changed, 1 insertion(+), 1 deletion(-)
9
1 file changed, 3 insertions(+)
11
10
12
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
11
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/arm_gicv3_cpuif.c
13
--- a/include/migration/vmstate.h
15
+++ b/hw/intc/arm_gicv3_cpuif.c
14
+++ b/include/migration/vmstate.h
16
@@ -XXX,XX +XXX,XX @@ static void icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
15
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
17
cs->ich_hcr_el2 = 0;
16
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
18
memset(cs->ich_lr_el2, 0, sizeof(cs->ich_lr_el2));
17
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
19
cs->ich_vmcr_el2 = ICH_VMCR_EL2_VFIQEN |
18
20
- (icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR1_SHIFT) |
19
+#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
21
+ ((icv_min_vbpr(cs) + 1) << ICH_VMCR_EL2_VBPR1_SHIFT) |
20
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
22
(icv_min_vbpr(cs) << ICH_VMCR_EL2_VBPR0_SHIFT);
21
+
23
}
22
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
23
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
24
24
25
--
25
--
26
2.7.4
26
2.17.1
27
27
28
28
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
2
2
3
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
is no enough contiguous memory, the address will be changed. So previous
5
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
5
pointer could not be used any more. It must update the pointer and use
6
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
6
the new one.
7
Message-id: 20170529173751.3443-2-drjones@redhat.com
7
8
Also, previous codes wrongly use le32 conversion of iort->node_offset
9
for subsequent computations that will result incorrect value if host is
10
not litlle endian. So use the non-converted one instead.
11
12
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
14
Message-id: 1527663951-14552-1-git-send-email-zhaoshenglong@huawei.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
16
---
10
hw/arm/virt-acpi-build.c | 4 ++++
17
hw/arm/virt-acpi-build.c | 20 +++++++++++++++-----
11
1 file changed, 4 insertions(+)
18
1 file changed, 15 insertions(+), 5 deletions(-)
12
19
13
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
20
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/virt-acpi-build.c
22
--- a/hw/arm/virt-acpi-build.c
16
+++ b/hw/arm/virt-acpi-build.c
23
+++ b/hw/arm/virt-acpi-build.c
17
@@ -XXX,XX +XXX,XX @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
24
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
18
if (nb_numa_nodes > 0) {
25
AcpiIortItsGroup *its;
19
acpi_add_table(table_offsets, tables_blob);
26
AcpiIortTable *iort;
20
build_srat(tables_blob, tables->linker, vms);
27
AcpiIortSmmu3 *smmu;
21
+ if (have_numa_distance) {
28
- size_t node_size, iort_length, smmu_offset = 0;
22
+ acpi_add_table(table_offsets, tables_blob);
29
+ size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
23
+ build_slit(tables_blob, tables->linker);
30
AcpiIortRC *rc;
24
+ }
31
32
iort = acpi_data_push(table_data, sizeof(*iort));
33
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
34
35
iort_length = sizeof(*iort);
36
iort->node_count = cpu_to_le32(nb_nodes);
37
- iort->node_offset = cpu_to_le32(sizeof(*iort));
38
+ /*
39
+ * Use a copy in case table_data->data moves during acpi_data_push
40
+ * operations.
41
+ */
42
+ iort_node_offset = sizeof(*iort);
43
+ iort->node_offset = cpu_to_le32(iort_node_offset);
44
45
/* ITS group node */
46
node_size = sizeof(*its) + sizeof(uint32_t);
47
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
48
int irq = vms->irqmap[VIRT_SMMU];
49
50
/* SMMUv3 node */
51
- smmu_offset = iort->node_offset + node_size;
52
+ smmu_offset = iort_node_offset + node_size;
53
node_size = sizeof(*smmu) + sizeof(*idmap);
54
iort_length += node_size;
55
smmu = acpi_data_push(table_data, node_size);
56
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
57
idmap->id_count = cpu_to_le32(0xFFFF);
58
idmap->output_base = 0;
59
/* output IORT node is the ITS group node (the first node) */
60
- idmap->output_reference = cpu_to_le32(iort->node_offset);
61
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
25
}
62
}
26
63
27
if (its_class_name() && !vmc->no_its) {
64
/* Root Complex Node */
65
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
idmap->output_reference = cpu_to_le32(smmu_offset);
67
} else {
68
/* output IORT node is the ITS group node (the first node) */
69
- idmap->output_reference = cpu_to_le32(iort->node_offset);
70
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
71
}
72
73
+ /*
74
+ * Update the pointer address in case table_data->data moves during above
75
+ * acpi_data_push operations.
76
+ */
77
+ iort = (AcpiIortTable *)(table_data->data + iort_start);
78
iort->length = cpu_to_le32(iort_length);
79
80
build_header(linker, table_data, (void *)(table_data->data + iort_start),
28
--
81
--
29
2.7.4
82
2.17.1
30
83
31
84
diff view generated by jsdifflib
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
2
2
3
Add support for the M profile default memory map which is used
3
kvm_irqchip_create called by kvm_init will call kvm_init_irq_routing to
4
if the MPU is not present or disabled.
4
initialize global capability variables. If we call kvm_init_irq_routing in
5
GIC realize function, previous allocated memory will leak.
5
6
6
The main differences in behaviour from implementing this
7
Fix this by deleting the unnecessary call.
7
correctly are that we set the PAGE_EXEC attribute on
8
the right regions of memory, such that device regions
9
are not executable.
10
8
11
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
9
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
12
Message-id: 1493122030-32191-10-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
13
[PMM: rephrased comment and commit message; don't mark
11
Message-id: 1527750994-14360-1-git-send-email-zhaoshenglong@huawei.com
14
the flash memory region as not-writable; list all
15
the cases in the default map explicitly rather than
16
using a 'default' case for the non-executable regions]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
13
---
19
target/arm/helper.c | 41 ++++++++++++++++++++++++++++++++---------
14
hw/intc/arm_gic_kvm.c | 1 -
20
1 file changed, 32 insertions(+), 9 deletions(-)
15
hw/intc/arm_gicv3_kvm.c | 1 -
16
2 files changed, 2 deletions(-)
21
17
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
23
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
20
--- a/hw/intc/arm_gic_kvm.c
25
+++ b/target/arm/helper.c
21
+++ b/hw/intc/arm_gic_kvm.c
26
@@ -XXX,XX +XXX,XX @@ static inline void get_phys_addr_pmsav7_default(CPUARMState *env,
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
27
ARMMMUIdx mmu_idx,
23
28
int32_t address, int *prot)
24
if (kvm_has_gsi_routing()) {
29
{
25
/* set up irq routing */
30
- *prot = PAGE_READ | PAGE_WRITE;
26
- kvm_init_irq_routing(kvm_state);
31
- switch (address) {
27
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
32
- case 0xF0000000 ... 0xFFFFFFFF:
28
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
33
- if (regime_sctlr(env, mmu_idx) & SCTLR_V) { /* hivecs execing is ok */
34
+ if (!arm_feature(env, ARM_FEATURE_M)) {
35
+ *prot = PAGE_READ | PAGE_WRITE;
36
+ switch (address) {
37
+ case 0xF0000000 ... 0xFFFFFFFF:
38
+ if (regime_sctlr(env, mmu_idx) & SCTLR_V) {
39
+ /* hivecs execing is ok */
40
+ *prot |= PAGE_EXEC;
41
+ }
42
+ break;
43
+ case 0x00000000 ... 0x7FFFFFFF:
44
*prot |= PAGE_EXEC;
45
+ break;
46
+ }
47
+ } else {
48
+ /* Default system address map for M profile cores.
49
+ * The architecture specifies which regions are execute-never;
50
+ * at the MPU level no other checks are defined.
51
+ */
52
+ switch (address) {
53
+ case 0x00000000 ... 0x1fffffff: /* ROM */
54
+ case 0x20000000 ... 0x3fffffff: /* SRAM */
55
+ case 0x60000000 ... 0x7fffffff: /* RAM */
56
+ case 0x80000000 ... 0x9fffffff: /* RAM */
57
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
58
+ break;
59
+ case 0x40000000 ... 0x5fffffff: /* Peripheral */
60
+ case 0xa0000000 ... 0xbfffffff: /* Device */
61
+ case 0xc0000000 ... 0xdfffffff: /* Device */
62
+ case 0xe0000000 ... 0xffffffff: /* System */
63
+ *prot = PAGE_READ | PAGE_WRITE;
64
+ break;
65
+ default:
66
+ g_assert_not_reached();
67
}
29
}
68
- break;
30
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
69
- case 0x00000000 ... 0x7FFFFFFF:
31
index XXXXXXX..XXXXXXX 100644
70
- *prot |= PAGE_EXEC;
32
--- a/hw/intc/arm_gicv3_kvm.c
71
- break;
33
+++ b/hw/intc/arm_gicv3_kvm.c
72
}
34
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
73
-
35
74
}
36
if (kvm_has_gsi_routing()) {
75
37
/* set up irq routing */
76
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
38
- kvm_init_irq_routing(kvm_state);
39
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
40
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
41
}
77
--
42
--
78
2.7.4
43
2.17.1
79
44
80
45
diff view generated by jsdifflib
Deleted patch
1
From: Michael Davidsaver <mdavidsaver@gmail.com>
2
1
3
General logic is that operations stopped by the MPU are MemManage,
4
and those which go through the MPU and are caught by the unassigned
5
handle are BusFault. Distinguish these by looking at the
6
exception.fsr values, and set the CFSR bits and (if appropriate)
7
fill in the BFAR or MMFAR with the exception address.
8
9
Signed-off-by: Michael Davidsaver <mdavidsaver@gmail.com>
10
Message-id: 1493122030-32191-12-git-send-email-peter.maydell@linaro.org
11
[PMM: i-side faults do not set BFAR/MMFAR, only d-side;
12
added some CPU_LOG_INT logging]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
---
16
target/arm/helper.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
17
1 file changed, 42 insertions(+), 3 deletions(-)
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
24
break;
25
case EXCP_PREFETCH_ABORT:
26
case EXCP_DATA_ABORT:
27
- /* TODO: if we implemented the MPU registers, this is where we
28
- * should set the MMFAR, etc from exception.fsr and exception.vaddress.
29
+ /* Note that for M profile we don't have a guest facing FSR, but
30
+ * the env->exception.fsr will be populated by the code that
31
+ * raises the fault, in the A profile short-descriptor format.
32
*/
33
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
34
+ switch (env->exception.fsr & 0xf) {
35
+ case 0x8: /* External Abort */
36
+ switch (cs->exception_index) {
37
+ case EXCP_PREFETCH_ABORT:
38
+ env->v7m.cfsr |= R_V7M_CFSR_PRECISERR_MASK;
39
+ qemu_log_mask(CPU_LOG_INT, "...with CFSR.PRECISERR\n");
40
+ break;
41
+ case EXCP_DATA_ABORT:
42
+ env->v7m.cfsr |=
43
+ (R_V7M_CFSR_IBUSERR_MASK | R_V7M_CFSR_BFARVALID_MASK);
44
+ env->v7m.bfar = env->exception.vaddress;
45
+ qemu_log_mask(CPU_LOG_INT,
46
+ "...with CFSR.IBUSERR and BFAR 0x%x\n",
47
+ env->v7m.bfar);
48
+ break;
49
+ }
50
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS);
51
+ break;
52
+ default:
53
+ /* All other FSR values are either MPU faults or "can't happen
54
+ * for M profile" cases.
55
+ */
56
+ switch (cs->exception_index) {
57
+ case EXCP_PREFETCH_ABORT:
58
+ env->v7m.cfsr |= R_V7M_CFSR_IACCVIOL_MASK;
59
+ qemu_log_mask(CPU_LOG_INT, "...with CFSR.IACCVIOL\n");
60
+ break;
61
+ case EXCP_DATA_ABORT:
62
+ env->v7m.cfsr |=
63
+ (R_V7M_CFSR_DACCVIOL_MASK | R_V7M_CFSR_MMARVALID_MASK);
64
+ env->v7m.mmfar = env->exception.vaddress;
65
+ qemu_log_mask(CPU_LOG_INT,
66
+ "...with CFSR.DACCVIOL and MMFAR 0x%x\n",
67
+ env->v7m.mmfar);
68
+ break;
69
+ }
70
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
71
+ break;
72
+ }
73
break;
74
case EXCP_BKPT:
75
if (semihosting_enabled()) {
76
--
77
2.7.4
78
79
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
Largely inspired by the TMP105 temperature sensor, here is a model for
4
the TMP42{1,2,3} temperature sensors.
5
6
Specs can be found here :
7
8
    http://www.ti.com/lit/gpn/tmp421
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 1494827476-1487-6-git-send-email-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/misc/Makefile.objs | 1 +
16
hw/misc/tmp421.c | 401 ++++++++++++++++++++++++++++++++++++++++
17
default-configs/arm-softmmu.mak | 1 +
18
3 files changed, 403 insertions(+)
19
create mode 100644 hw/misc/tmp421.c
20
21
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/misc/Makefile.objs
24
+++ b/hw/misc/Makefile.objs
25
@@ -XXX,XX +XXX,XX @@
26
common-obj-$(CONFIG_APPLESMC) += applesmc.o
27
common-obj-$(CONFIG_MAX111X) += max111x.o
28
common-obj-$(CONFIG_TMP105) += tmp105.o
29
+common-obj-$(CONFIG_TMP421) += tmp421.o
30
common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
31
common-obj-$(CONFIG_SGA) += sga.o
32
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
33
diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c
34
new file mode 100644
35
index XXXXXXX..XXXXXXX
36
--- /dev/null
37
+++ b/hw/misc/tmp421.c
38
@@ -XXX,XX +XXX,XX @@
39
+/*
40
+ * Texas Instruments TMP421 temperature sensor.
41
+ *
42
+ * Copyright (c) 2016 IBM Corporation.
43
+ *
44
+ * Largely inspired by :
45
+ *
46
+ * Texas Instruments TMP105 temperature sensor.
47
+ *
48
+ * Copyright (C) 2008 Nokia Corporation
49
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or
52
+ * modify it under the terms of the GNU General Public License as
53
+ * published by the Free Software Foundation; either version 2 or
54
+ * (at your option) version 3 of the License.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59
+ * GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+
65
+#include "qemu/osdep.h"
66
+#include "hw/hw.h"
67
+#include "hw/i2c/i2c.h"
68
+#include "qapi/error.h"
69
+#include "qapi/visitor.h"
70
+
71
+/* Manufacturer / Device ID's */
72
+#define TMP421_MANUFACTURER_ID 0x55
73
+#define TMP421_DEVICE_ID 0x21
74
+#define TMP422_DEVICE_ID 0x22
75
+#define TMP423_DEVICE_ID 0x23
76
+
77
+typedef struct DeviceInfo {
78
+ int model;
79
+ const char *name;
80
+} DeviceInfo;
81
+
82
+static const DeviceInfo devices[] = {
83
+ { TMP421_DEVICE_ID, "tmp421" },
84
+ { TMP422_DEVICE_ID, "tmp422" },
85
+ { TMP423_DEVICE_ID, "tmp423" },
86
+};
87
+
88
+typedef struct TMP421State {
89
+ /*< private >*/
90
+ I2CSlave i2c;
91
+ /*< public >*/
92
+
93
+ int16_t temperature[4];
94
+
95
+ uint8_t status;
96
+ uint8_t config[2];
97
+ uint8_t rate;
98
+
99
+ uint8_t len;
100
+ uint8_t buf[2];
101
+ uint8_t pointer;
102
+
103
+} TMP421State;
104
+
105
+typedef struct TMP421Class {
106
+ I2CSlaveClass parent_class;
107
+ DeviceInfo *dev;
108
+} TMP421Class;
109
+
110
+#define TYPE_TMP421 "tmp421-generic"
111
+#define TMP421(obj) OBJECT_CHECK(TMP421State, (obj), TYPE_TMP421)
112
+
113
+#define TMP421_CLASS(klass) \
114
+ OBJECT_CLASS_CHECK(TMP421Class, (klass), TYPE_TMP421)
115
+#define TMP421_GET_CLASS(obj) \
116
+ OBJECT_GET_CLASS(TMP421Class, (obj), TYPE_TMP421)
117
+
118
+/* the TMP421 registers */
119
+#define TMP421_STATUS_REG 0x08
120
+#define TMP421_STATUS_BUSY (1 << 7)
121
+#define TMP421_CONFIG_REG_1 0x09
122
+#define TMP421_CONFIG_RANGE (1 << 2)
123
+#define TMP421_CONFIG_SHUTDOWN (1 << 6)
124
+#define TMP421_CONFIG_REG_2 0x0A
125
+#define TMP421_CONFIG_RC (1 << 2)
126
+#define TMP421_CONFIG_LEN (1 << 3)
127
+#define TMP421_CONFIG_REN (1 << 4)
128
+#define TMP421_CONFIG_REN2 (1 << 5)
129
+#define TMP421_CONFIG_REN3 (1 << 6)
130
+
131
+#define TMP421_CONVERSION_RATE_REG 0x0B
132
+#define TMP421_ONE_SHOT 0x0F
133
+
134
+#define TMP421_RESET 0xFC
135
+#define TMP421_MANUFACTURER_ID_REG 0xFE
136
+#define TMP421_DEVICE_ID_REG 0xFF
137
+
138
+#define TMP421_TEMP_MSB0 0x00
139
+#define TMP421_TEMP_MSB1 0x01
140
+#define TMP421_TEMP_MSB2 0x02
141
+#define TMP421_TEMP_MSB3 0x03
142
+#define TMP421_TEMP_LSB0 0x10
143
+#define TMP421_TEMP_LSB1 0x11
144
+#define TMP421_TEMP_LSB2 0x12
145
+#define TMP421_TEMP_LSB3 0x13
146
+
147
+static const int32_t mins[2] = { -40000, -55000 };
148
+static const int32_t maxs[2] = { 127000, 150000 };
149
+
150
+static void tmp421_get_temperature(Object *obj, Visitor *v, const char *name,
151
+ void *opaque, Error **errp)
152
+{
153
+ TMP421State *s = TMP421(obj);
154
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
155
+ int offset = ext_range * 64 * 256;
156
+ int64_t value;
157
+ int tempid;
158
+
159
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
160
+ error_setg(errp, "error reading %s: %m", name);
161
+ return;
162
+ }
163
+
164
+ if (tempid >= 4 || tempid < 0) {
165
+ error_setg(errp, "error reading %s", name);
166
+ return;
167
+ }
168
+
169
+ value = ((s->temperature[tempid] - offset) * 1000 + 128) / 256;
170
+
171
+ visit_type_int(v, name, &value, errp);
172
+}
173
+
174
+/* Units are 0.001 centigrades relative to 0 C. s->temperature is 8.8
175
+ * fixed point, so units are 1/256 centigrades. A simple ratio will do.
176
+ */
177
+static void tmp421_set_temperature(Object *obj, Visitor *v, const char *name,
178
+ void *opaque, Error **errp)
179
+{
180
+ TMP421State *s = TMP421(obj);
181
+ Error *local_err = NULL;
182
+ int64_t temp;
183
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
184
+ int offset = ext_range * 64 * 256;
185
+ int tempid;
186
+
187
+ visit_type_int(v, name, &temp, &local_err);
188
+ if (local_err) {
189
+ error_propagate(errp, local_err);
190
+ return;
191
+ }
192
+
193
+ if (temp >= maxs[ext_range] || temp < mins[ext_range]) {
194
+ error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
195
+ temp / 1000, temp % 1000);
196
+ return;
197
+ }
198
+
199
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
200
+ error_setg(errp, "error reading %s: %m", name);
201
+ return;
202
+ }
203
+
204
+ if (tempid >= 4 || tempid < 0) {
205
+ error_setg(errp, "error reading %s", name);
206
+ return;
207
+ }
208
+
209
+ s->temperature[tempid] = (int16_t) ((temp * 256 - 128) / 1000) + offset;
210
+}
211
+
212
+static void tmp421_read(TMP421State *s)
213
+{
214
+ TMP421Class *sc = TMP421_GET_CLASS(s);
215
+
216
+ s->len = 0;
217
+
218
+ switch (s->pointer) {
219
+ case TMP421_MANUFACTURER_ID_REG:
220
+ s->buf[s->len++] = TMP421_MANUFACTURER_ID;
221
+ break;
222
+ case TMP421_DEVICE_ID_REG:
223
+ s->buf[s->len++] = sc->dev->model;
224
+ break;
225
+ case TMP421_CONFIG_REG_1:
226
+ s->buf[s->len++] = s->config[0];
227
+ break;
228
+ case TMP421_CONFIG_REG_2:
229
+ s->buf[s->len++] = s->config[1];
230
+ break;
231
+ case TMP421_CONVERSION_RATE_REG:
232
+ s->buf[s->len++] = s->rate;
233
+ break;
234
+ case TMP421_STATUS_REG:
235
+ s->buf[s->len++] = s->status;
236
+ break;
237
+
238
+ /* FIXME: check for channel enablement in config registers */
239
+ case TMP421_TEMP_MSB0:
240
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 8);
241
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
242
+ break;
243
+ case TMP421_TEMP_MSB1:
244
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 8);
245
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
246
+ break;
247
+ case TMP421_TEMP_MSB2:
248
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 8);
249
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
250
+ break;
251
+ case TMP421_TEMP_MSB3:
252
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 8);
253
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
254
+ break;
255
+ case TMP421_TEMP_LSB0:
256
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
257
+ break;
258
+ case TMP421_TEMP_LSB1:
259
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
260
+ break;
261
+ case TMP421_TEMP_LSB2:
262
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
263
+ break;
264
+ case TMP421_TEMP_LSB3:
265
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
266
+ break;
267
+ }
268
+}
269
+
270
+static void tmp421_reset(I2CSlave *i2c);
271
+
272
+static void tmp421_write(TMP421State *s)
273
+{
274
+ switch (s->pointer) {
275
+ case TMP421_CONVERSION_RATE_REG:
276
+ s->rate = s->buf[0];
277
+ break;
278
+ case TMP421_CONFIG_REG_1:
279
+ s->config[0] = s->buf[0];
280
+ break;
281
+ case TMP421_CONFIG_REG_2:
282
+ s->config[1] = s->buf[0];
283
+ break;
284
+ case TMP421_RESET:
285
+ tmp421_reset(I2C_SLAVE(s));
286
+ break;
287
+ }
288
+}
289
+
290
+static int tmp421_rx(I2CSlave *i2c)
291
+{
292
+ TMP421State *s = TMP421(i2c);
293
+
294
+ if (s->len < 2) {
295
+ return s->buf[s->len++];
296
+ } else {
297
+ return 0xff;
298
+ }
299
+}
300
+
301
+static int tmp421_tx(I2CSlave *i2c, uint8_t data)
302
+{
303
+ TMP421State *s = TMP421(i2c);
304
+
305
+ if (s->len == 0) {
306
+ /* first byte is the register pointer for a read or write
307
+ * operation */
308
+ s->pointer = data;
309
+ s->len++;
310
+ } else if (s->len == 1) {
311
+ /* second byte is the data to write. The device only supports
312
+ * one byte writes */
313
+ s->buf[0] = data;
314
+ tmp421_write(s);
315
+ }
316
+
317
+ return 0;
318
+}
319
+
320
+static int tmp421_event(I2CSlave *i2c, enum i2c_event event)
321
+{
322
+ TMP421State *s = TMP421(i2c);
323
+
324
+ if (event == I2C_START_RECV) {
325
+ tmp421_read(s);
326
+ }
327
+
328
+ s->len = 0;
329
+ return 0;
330
+}
331
+
332
+static const VMStateDescription vmstate_tmp421 = {
333
+ .name = "TMP421",
334
+ .version_id = 0,
335
+ .minimum_version_id = 0,
336
+ .fields = (VMStateField[]) {
337
+ VMSTATE_UINT8(len, TMP421State),
338
+ VMSTATE_UINT8_ARRAY(buf, TMP421State, 2),
339
+ VMSTATE_UINT8(pointer, TMP421State),
340
+ VMSTATE_UINT8_ARRAY(config, TMP421State, 2),
341
+ VMSTATE_UINT8(status, TMP421State),
342
+ VMSTATE_UINT8(rate, TMP421State),
343
+ VMSTATE_INT16_ARRAY(temperature, TMP421State, 4),
344
+ VMSTATE_I2C_SLAVE(i2c, TMP421State),
345
+ VMSTATE_END_OF_LIST()
346
+ }
347
+};
348
+
349
+static void tmp421_reset(I2CSlave *i2c)
350
+{
351
+ TMP421State *s = TMP421(i2c);
352
+ TMP421Class *sc = TMP421_GET_CLASS(s);
353
+
354
+ memset(s->temperature, 0, sizeof(s->temperature));
355
+ s->pointer = 0;
356
+
357
+ s->config[0] = 0; /* TMP421_CONFIG_RANGE */
358
+
359
+ /* resistance correction and channel enablement */
360
+ switch (sc->dev->model) {
361
+ case TMP421_DEVICE_ID:
362
+ s->config[1] = 0x1c;
363
+ break;
364
+ case TMP422_DEVICE_ID:
365
+ s->config[1] = 0x3c;
366
+ break;
367
+ case TMP423_DEVICE_ID:
368
+ s->config[1] = 0x7c;
369
+ break;
370
+ }
371
+
372
+ s->rate = 0x7; /* 8Hz */
373
+ s->status = 0;
374
+}
375
+
376
+static int tmp421_init(I2CSlave *i2c)
377
+{
378
+ TMP421State *s = TMP421(i2c);
379
+
380
+ tmp421_reset(&s->i2c);
381
+
382
+ return 0;
383
+}
384
+
385
+static void tmp421_initfn(Object *obj)
386
+{
387
+ object_property_add(obj, "temperature0", "int",
388
+ tmp421_get_temperature,
389
+ tmp421_set_temperature, NULL, NULL, NULL);
390
+ object_property_add(obj, "temperature1", "int",
391
+ tmp421_get_temperature,
392
+ tmp421_set_temperature, NULL, NULL, NULL);
393
+ object_property_add(obj, "temperature2", "int",
394
+ tmp421_get_temperature,
395
+ tmp421_set_temperature, NULL, NULL, NULL);
396
+ object_property_add(obj, "temperature3", "int",
397
+ tmp421_get_temperature,
398
+ tmp421_set_temperature, NULL, NULL, NULL);
399
+}
400
+
401
+static void tmp421_class_init(ObjectClass *klass, void *data)
402
+{
403
+ DeviceClass *dc = DEVICE_CLASS(klass);
404
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
405
+ TMP421Class *sc = TMP421_CLASS(klass);
406
+
407
+ k->init = tmp421_init;
408
+ k->event = tmp421_event;
409
+ k->recv = tmp421_rx;
410
+ k->send = tmp421_tx;
411
+ dc->vmsd = &vmstate_tmp421;
412
+ sc->dev = (DeviceInfo *) data;
413
+}
414
+
415
+static const TypeInfo tmp421_info = {
416
+ .name = TYPE_TMP421,
417
+ .parent = TYPE_I2C_SLAVE,
418
+ .instance_size = sizeof(TMP421State),
419
+ .instance_init = tmp421_initfn,
420
+ .class_init = tmp421_class_init,
421
+};
422
+
423
+static void tmp421_register_types(void)
424
+{
425
+ int i;
426
+
427
+ type_register_static(&tmp421_info);
428
+ for (i = 0; i < ARRAY_SIZE(devices); ++i) {
429
+ TypeInfo ti = {
430
+ .name = devices[i].name,
431
+ .parent = TYPE_TMP421,
432
+ .class_init = tmp421_class_init,
433
+ .class_data = (void *) &devices[i],
434
+ };
435
+ type_register(&ti);
436
+ }
437
+}
438
+
439
+type_init(tmp421_register_types)
440
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
441
index XXXXXXX..XXXXXXX 100644
442
--- a/default-configs/arm-softmmu.mak
443
+++ b/default-configs/arm-softmmu.mak
444
@@ -XXX,XX +XXX,XX @@ CONFIG_TWL92230=y
445
CONFIG_TSC2005=y
446
CONFIG_LM832X=y
447
CONFIG_TMP105=y
448
+CONFIG_TMP421=y
449
CONFIG_STELLARIS=y
450
CONFIG_STELLARIS_INPUT=y
451
CONFIG_STELLARIS_ENET=y
452
--
453
2.7.4
454
455
diff view generated by jsdifflib