1
target-arm queue. This has the "plumb txattrs through various
1
First arm pullreq of 5.0!
2
bits of exec.c" patches, and a collection of bug fixes from
3
various people.
4
2
5
thanks
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
6
-- PMM
7
4
8
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
9
10
The following changes since commit a3ac12fba028df90f7b3dbec924995c126c41022:
11
12
Merge remote-tracking branch 'remotes/ehabkost/tags/numa-next-pull-request' into staging (2018-05-31 11:12:36 +0100)
13
6
14
are available in the Git repository at:
7
are available in the Git repository at:
15
8
16
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180531
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
17
10
18
for you to fetch changes up to 49d1dca0520ea71bc21867fab6647f474fcf857b:
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
19
12
20
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice (2018-05-31 14:52:53 +0100)
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
21
14
22
----------------------------------------------------------------
15
----------------------------------------------------------------
23
target-arm queue:
16
target-arm queue:
24
* target/arm: Honour FPCR.FZ in FRECPX
17
* Add support for Cortex-M7 CPU
25
* MAINTAINERS: Add entries for newer MPS2 boards and devices
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
26
* hw/intc/arm_gicv3: Fix APxR<n> register dispatching
19
* aspeed: Various minor bug fixes and improvements
27
* arm_gicv3_kvm: fix bug in writing zero bits back to the in-kernel
20
* aspeed: Add support for the tacoma-bmc board
28
GIC state
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
29
* tcg: Fix helper function vs host abi for float16
22
* Handle trapping to EL2 of AArch32 VMRS instructions
30
* arm: fix qemu crash on startup with -bios option
23
* Handle AArch32 CP15 trapping via HSTR_EL2
31
* arm: fix malloc type mismatch
24
* Add support for missing Jazelle system registers
32
* xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
33
* Correct CPACR reset value for v7 cores
26
* Add support for DC CVAP & DC CVADP instructions
34
* memory.h: Improve IOMMU related documentation
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
35
* exec: Plumb transaction attributes through various functions in
28
* enable SHPC native hot plug in arm ACPI
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
40
29
41
----------------------------------------------------------------
30
----------------------------------------------------------------
42
Francisco Iglesias (1):
31
Alex Bennée (1):
43
xlnx-zdma: Correct mem leaks and memset to zero on desc unaligned errors
32
target/arm: ensure we use current exception state after SCR update
44
33
45
Igor Mammedov (1):
34
Beata Michalska (4):
46
arm: fix qemu crash on startup with -bios option
35
tcg: cputlb: Add probe_read
36
Memory: Enable writeback for given memory region
37
migration: ram: Switch to ram block writeback
38
target/arm: Add support for DC CVAP & DC CVADP ins
47
39
48
Jan Kiszka (1):
40
Christophe Lyon (1):
49
hw/intc/arm_gicv3: Fix APxR<n> register dispatching
41
target/arm: Add support for cortex-m7 CPU
50
42
51
Paolo Bonzini (1):
43
Cédric Le Goater (12):
52
arm: fix malloc type mismatch
44
aspeed/i2c: Add support for pool buffer transfers
45
aspeed/i2c: Check SRAM enablement on AST2500
46
aspeed: Add a DRAM memory region at the SoC level
47
aspeed/i2c: Add support for DMA transfers
48
aspeed/i2c: Add trace events
49
aspeed/smc: Restore default AHB window mapping at reset
50
aspeed/smc: Do not map disabled segment on the AST2600
51
aspeed/smc: Add AST2600 timings registers
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
53
aspeed: Add support for the tacoma-bmc board
54
aspeed: Change the "scu" property definition
55
aspeed: Change the "nic" property definition
53
56
54
Peter Maydell (17):
57
David Gibson (1):
55
target/arm: Honour FPCR.FZ in FRECPX
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
56
MAINTAINERS: Add entries for newer MPS2 boards and devices
57
Correct CPACR reset value for v7 cores
58
memory.h: Improve IOMMU related documentation
59
Make tb_invalidate_phys_addr() take a MemTxAttrs argument
60
Make address_space_translate{, _cached}() take a MemTxAttrs argument
61
Make address_space_map() take a MemTxAttrs argument
62
Make address_space_access_valid() take a MemTxAttrs argument
63
Make flatview_extend_translation() take a MemTxAttrs argument
64
Make memory_region_access_valid() take a MemTxAttrs argument
65
Make MemoryRegion valid.accepts callback take a MemTxAttrs argument
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
72
59
73
Richard Henderson (1):
60
Heyi Guo (2):
74
tcg: Fix helper function vs host abi for float16
61
hw/arm/acpi: simplify AML bit and/or statement
62
hw/arm/acpi: enable SHPC native hot plug
75
63
76
Shannon Zhao (3):
64
Joel Stanley (4):
77
arm_gicv3_kvm: increase clroffset accordingly
65
aspeed/sdmc: Make ast2600 default 1G
78
ARM: ACPI: Fix use-after-free due to memory realloc
66
aspeed/scu: Fix W1C behavior
79
KVM: GIC: Fix memory leak due to calling kvm_init_irq_routing twice
67
watchdog/aspeed: Improve watchdog timeout message
68
watchdog/aspeed: Fix AST2600 frequency behaviour
80
69
81
include/exec/exec-all.h | 5 +-
70
Marc Zyngier (5):
82
include/exec/helper-head.h | 2 +-
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
83
include/exec/memory-internal.h | 3 +-
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
84
include/exec/memory.h | 128 +++++++++++++++++++++++++++++++++++------
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
85
include/migration/vmstate.h | 3 +
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
86
include/sysemu/dma.h | 6 +-
75
target/arm: Add support for missing Jazelle system registers
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
76
77
Niek Linnenbank (1):
78
arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on()
79
80
PanNengyuan (1):
81
gpio: fix memory leak in aspeed_gpio_init()
82
83
Philippe Mathieu-Daudé (2):
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
85
hw/arm/virt: Simplify by moving the gic in the machine state
86
87
include/exec/exec-all.h | 6 +
88
include/exec/memory.h | 6 +
89
include/exec/ram_addr.h | 8 +
90
include/hw/arm/aspeed.h | 24 +--
91
include/hw/arm/aspeed_soc.h | 1 +
92
include/hw/arm/virt.h | 1 +
93
include/hw/i2c/aspeed_i2c.h | 16 ++
94
include/hw/ssi/aspeed_smc.h | 1 +
95
include/hw/watchdog/wdt_aspeed.h | 1 +
96
include/qemu/cutils.h | 1 +
97
target/arm/cpu.h | 20 +-
98
target/arm/helper.h | 3 +
99
target/arm/translate.h | 2 +
100
exec.c | 36 ++++
101
hw/arm/aspeed.c | 271 +++++++++++++----------
102
hw/arm/aspeed_ast2600.c | 25 ++-
103
hw/arm/aspeed_soc.c | 22 +-
104
hw/arm/sbsa-ref.c | 86 ++++----
105
hw/arm/virt-acpi-build.c | 21 +-
106
hw/arm/virt.c | 109 +++++-----
107
hw/gpio/aspeed_gpio.c | 1 +
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
109
hw/intc/exynos4210_gic.c | 9 +-
110
hw/misc/aspeed_scu.c | 19 +-
111
hw/misc/aspeed_sdmc.c | 6 +-
112
hw/net/ftgmac100.c | 19 +-
113
hw/ssi/aspeed_smc.c | 63 ++++--
114
hw/timer/aspeed_timer.c | 17 +-
115
hw/watchdog/wdt_aspeed.c | 41 ++--
116
linux-user/elfload.c | 2 +
117
memory.c | 12 ++
118
migration/ram.c | 5 +-
119
target/arm/arm-powerctl.c | 3 +
120
target/arm/cpu.c | 33 +++
121
target/arm/cpu64.c | 1 +
122
target/arm/helper.c | 170 ++++++++++++++-
123
target/arm/op_helper.c | 22 ++
124
target/arm/translate-vfp.inc.c | 20 +-
125
target/arm/translate.c | 9 +-
126
target/arm/vfp_helper.c | 29 +++
127
util/cutils.c | 38 ++++
128
hw/i2c/trace-events | 9 +
129
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
130
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
131
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
132
45 files changed, 1273 insertions(+), 354 deletions(-)
133
diff view generated by jsdifflib
New patch
1
From: Christophe Lyon <christophe.lyon@linaro.org>
1
2
3
This is derived from cortex-m4 description, adding DP support and FPv5
4
instructions with the corresponding flags in isar and mvfr2.
5
6
Checked that it could successfully execute
7
vrinta.f32 s15, s15
8
while cortex-m4 emulation rejects it with "illegal instruction".
9
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20191025090841.10299-1-christophe.lyon@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
17
1 file changed, 33 insertions(+)
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
24
cpu->isar.id_isar6 = 0x00000000;
25
}
26
27
+static void cortex_m7_initfn(Object *obj)
28
+{
29
+ ARMCPU *cpu = ARM_CPU(obj);
30
+
31
+ set_feature(&cpu->env, ARM_FEATURE_V7);
32
+ set_feature(&cpu->env, ARM_FEATURE_M);
33
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
34
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
35
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
36
+ cpu->midr = 0x411fc272; /* r1p2 */
37
+ cpu->pmsav7_dregion = 8;
38
+ cpu->isar.mvfr0 = 0x10110221;
39
+ cpu->isar.mvfr1 = 0x12000011;
40
+ cpu->isar.mvfr2 = 0x00000040;
41
+ cpu->id_pfr0 = 0x00000030;
42
+ cpu->id_pfr1 = 0x00000200;
43
+ cpu->id_dfr0 = 0x00100000;
44
+ cpu->id_afr0 = 0x00000000;
45
+ cpu->id_mmfr0 = 0x00100030;
46
+ cpu->id_mmfr1 = 0x00000000;
47
+ cpu->id_mmfr2 = 0x01000000;
48
+ cpu->id_mmfr3 = 0x00000000;
49
+ cpu->isar.id_isar0 = 0x01101110;
50
+ cpu->isar.id_isar1 = 0x02112000;
51
+ cpu->isar.id_isar2 = 0x20232231;
52
+ cpu->isar.id_isar3 = 0x01111131;
53
+ cpu->isar.id_isar4 = 0x01310132;
54
+ cpu->isar.id_isar5 = 0x00000000;
55
+ cpu->isar.id_isar6 = 0x00000000;
56
+}
57
+
58
static void cortex_m33_initfn(Object *obj)
59
{
60
ARMCPU *cpu = ARM_CPU(obj);
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
64
.class_init = arm_v7m_class_init },
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
66
+ .class_init = arm_v7m_class_init },
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
68
.class_init = arm_v7m_class_init },
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
New patch
1
From: David Gibson <david@gibson.dropbear.id.au>
1
2
3
exynos4210_gic_realize() prints the number of cpus into some temporary
4
buffers, but it only allows 3 bytes space for it. That's plenty:
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
6
(2). But the compiler can't always figure that out, so some[*] gcc9
7
versions emit -Wformat-truncation warnings.
8
9
We can fix that by hinting the constraint to the compiler with a
10
suitably placed assert().
11
12
[*] The bizarre thing here, is that I've long gotten these warnings
13
compiling in a 32-bit x86 container as host - Fedora 30 with
14
gcc-9.2.1-1.fc30.i686 - but it compiles just fine on my normal
15
x86_64 host - Fedora 30 with and gcc-9.2.1-1.fc30.x86_64.
16
17
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
18
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
[PMM: deleted stray blank line]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/intc/exynos4210_gic.c | 9 ++++++++-
24
1 file changed, 8 insertions(+), 1 deletion(-)
25
26
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
29
+++ b/hw/intc/exynos4210_gic.c
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
33
SysBusDevice *gicbusdev;
34
+ uint32_t n = s->num_cpu;
35
uint32_t i;
36
37
s->gic = qdev_create(NULL, "arm_gic");
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
41
42
- for (i = 0; i < s->num_cpu; i++) {
43
+ /*
44
+ * This clues in gcc that our on-stack buffers do, in fact have
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
47
+ */
48
+ assert(n <= EXYNOS4210_NCPUS);
49
+ for (i = 0; i < n; i++) {
50
/* Map CPU interface per SMP Core */
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
52
memory_region_init_alias(&s->cpu_alias[i], obj,
53
--
54
2.20.1
55
56
diff view generated by jsdifflib
New patch
1
1
From: Cédric Le Goater <clg@kaod.org>
2
3
The Aspeed I2C controller can operate in different transfer modes :
4
5
- Byte Buffer mode, using a dedicated register to transfer a
6
byte. This is what the model supports today.
7
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
9
bytes in the same command sequence.
10
11
Each SoC has different SRAM characteristics. On the AST2400, 2048
12
bytes of SRAM are available at offset 0x800 of the controller AHB
13
window. The pool buffer can be configured from 1 to 256 bytes per bus.
14
15
On the AST2500, the SRAM is at offset 0x200 and the pool buffer is of
16
16 bytes per bus.
17
18
On the AST2600, the SRAM is at offset 0xC00 and the pool buffer is of
19
32 bytes per bus. It can be splitted in two for TX and RX but the
20
current model does not add support for it as it it unused by known
21
drivers.
22
23
Signed-off-by: Cédric Le Goater <clg@kaod.org>
24
Reviewed-by: Joel Stanley <joel@jms.id.au>
25
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
26
Signed-off-by: Cédric Le Goater <clg@kaod.org>
27
Message-id: 20191119141211.25716-2-clg@kaod.org
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
32
2 files changed, 186 insertions(+), 19 deletions(-)
33
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
37
+++ b/include/hw/i2c/aspeed_i2c.h
38
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
40
41
#define ASPEED_I2C_NR_BUSSES 16
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
43
44
struct AspeedI2CState;
45
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
47
uint32_t intr_status;
48
uint32_t cmd;
49
uint32_t buf;
50
+ uint32_t pool_ctrl;
51
} AspeedI2CBus;
52
53
typedef struct AspeedI2CState {
54
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
55
qemu_irq irq;
56
57
uint32_t intr_status;
58
+ MemoryRegion pool_iomem;
59
+ uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
60
61
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
62
} AspeedI2CState;
63
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
64
uint8_t reg_size;
65
uint8_t gap;
66
qemu_irq (*bus_get_irq)(AspeedI2CBus *);
67
+
68
+ uint64_t pool_size;
69
+ hwaddr pool_base;
70
+ uint8_t *(*bus_pool_base)(AspeedI2CBus *);
71
} AspeedI2CClass;
72
73
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
74
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/hw/i2c/aspeed_i2c.c
77
+++ b/hw/i2c/aspeed_i2c.c
78
@@ -XXX,XX +XXX,XX @@
79
/* I2C Device (Bus) Register */
80
81
#define I2CD_FUN_CTRL_REG 0x00 /* I2CD Function Control */
82
-#define I2CD_BUFF_SEL_MASK (0x7 << 20)
83
-#define I2CD_BUFF_SEL(x) (x << 20)
84
+#define I2CD_POOL_PAGE_SEL(x) (((x) >> 20) & 0x7) /* AST2400 */
85
#define I2CD_M_SDA_LOCK_EN (0x1 << 16)
86
#define I2CD_MULTI_MASTER_DIS (0x1 << 15)
87
#define I2CD_M_SCL_DRIVE_EN (0x1 << 14)
88
@@ -XXX,XX +XXX,XX @@
89
#define I2CD_SCL_O_OUT_DIR (0x1 << 12)
90
#define I2CD_BUS_RECOVER_CMD_EN (0x1 << 11)
91
#define I2CD_S_ALT_EN (0x1 << 10)
92
-#define I2CD_RX_DMA_ENABLE (0x1 << 9)
93
-#define I2CD_TX_DMA_ENABLE (0x1 << 8)
94
95
/* Command Bit */
96
+#define I2CD_RX_DMA_ENABLE (0x1 << 9)
97
+#define I2CD_TX_DMA_ENABLE (0x1 << 8)
98
+#define I2CD_RX_BUFF_ENABLE (0x1 << 7)
99
+#define I2CD_TX_BUFF_ENABLE (0x1 << 6)
100
#define I2CD_M_STOP_CMD (0x1 << 5)
101
#define I2CD_M_S_RX_CMD_LAST (0x1 << 4)
102
#define I2CD_M_RX_CMD (0x1 << 3)
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_M_START_CMD (0x1)
105
106
#define I2CD_DEV_ADDR_REG 0x18 /* Slave Device Address */
107
-#define I2CD_BUF_CTRL_REG 0x1c /* Pool Buffer Control */
108
+#define I2CD_POOL_CTRL_REG 0x1c /* Pool Buffer Control */
109
+#define I2CD_POOL_RX_COUNT(x) (((x) >> 24) & 0xff)
110
+#define I2CD_POOL_RX_SIZE(x) ((((x) >> 16) & 0xff) + 1)
111
+#define I2CD_POOL_TX_COUNT(x) ((((x) >> 8) & 0xff) + 1)
112
+#define I2CD_POOL_OFFSET(x) (((x) & 0x3f) << 2) /* AST2400 */
113
#define I2CD_BYTE_BUF_REG 0x20 /* Transmit/Receive Byte Buffer */
114
#define I2CD_BYTE_BUF_TX_SHIFT 0
115
#define I2CD_BYTE_BUF_TX_MASK 0xff
116
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
117
return bus->intr_ctrl;
118
case I2CD_INTR_STS_REG:
119
return bus->intr_status;
120
+ case I2CD_POOL_CTRL_REG:
121
+ return bus->pool_ctrl;
122
case I2CD_BYTE_BUF_REG:
123
return bus->buf;
124
case I2CD_CMD_REG:
125
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
126
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
127
}
128
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
130
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
132
+ int ret = -1;
133
+ int i;
134
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
138
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
140
+ if (ret) {
141
+ break;
142
+ }
143
+ }
144
+ bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
145
+ } else {
146
+ ret = i2c_send(bus->bus, bus->buf);
147
+ }
148
+
149
+ return ret;
150
+}
151
+
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
153
+{
154
+ AspeedI2CState *s = bus->controller;
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
156
+ uint8_t data;
157
+ int i;
158
+
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
160
+ uint8_t *pool_base = aic->bus_pool_base(bus);
161
+
162
+ for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
163
+ pool_base[i] = i2c_recv(bus->bus);
164
+ }
165
+
166
+ /* Update RX count */
167
+ bus->pool_ctrl &= ~(0xff << 24);
168
+ bus->pool_ctrl |= (i & 0xff) << 24;
169
+ bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
170
+ } else {
171
+ data = i2c_recv(bus->bus);
172
+ bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
173
+ }
174
+}
175
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
177
{
178
- uint8_t ret;
179
-
180
aspeed_i2c_set_state(bus, I2CD_MRXD);
181
- ret = i2c_recv(bus->bus);
182
+ aspeed_i2c_bus_recv(bus);
183
bus->intr_status |= I2CD_INTR_RX_DONE;
184
- bus->buf = (ret & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
185
if (bus->cmd & I2CD_M_S_RX_CMD_LAST) {
186
i2c_nack(bus->bus);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
191
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
193
+{
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
195
+
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
198
+
199
+ return pool_base[0];
200
+ } else {
201
+ return bus->buf;
202
+ }
203
+}
204
+
205
/*
206
* The state machine needs some refinement. It is only used to track
207
* invalid STOP commands for the moment.
208
*/
209
static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
210
{
211
+ uint8_t pool_start = 0;
212
+
213
bus->cmd &= ~0xFFFF;
214
bus->cmd |= value & 0xFFFF;
215
216
if (bus->cmd & I2CD_M_START_CMD) {
217
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
218
I2CD_MSTARTR : I2CD_MSTART;
219
+ uint8_t addr;
220
221
aspeed_i2c_set_state(bus, state);
222
223
- if (i2c_start_transfer(bus->bus, extract32(bus->buf, 1, 7),
224
- extract32(bus->buf, 0, 1))) {
225
+ addr = aspeed_i2c_get_addr(bus);
226
+
227
+ if (i2c_start_transfer(bus->bus, extract32(addr, 1, 7),
228
+ extract32(addr, 0, 1))) {
229
bus->intr_status |= I2CD_INTR_TX_NAK;
230
} else {
231
bus->intr_status |= I2CD_INTR_TX_ACK;
232
}
233
234
- /* START command is also a TX command, as the slave address is
235
- * sent on the bus */
236
- bus->cmd &= ~(I2CD_M_START_CMD | I2CD_M_TX_CMD);
237
+ bus->cmd &= ~I2CD_M_START_CMD;
238
+
239
+ /*
240
+ * The START command is also a TX command, as the slave
241
+ * address is sent on the bus. Drop the TX flag if nothing
242
+ * else needs to be sent in this sequence.
243
+ */
244
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
245
+ if (I2CD_POOL_TX_COUNT(bus->pool_ctrl) == 1) {
246
+ bus->cmd &= ~I2CD_M_TX_CMD;
247
+ } else {
248
+ /*
249
+ * Increase the start index in the TX pool buffer to
250
+ * skip the address byte.
251
+ */
252
+ pool_start++;
253
+ }
254
+ } else {
255
+ bus->cmd &= ~I2CD_M_TX_CMD;
256
+ }
257
258
/* No slave found */
259
if (!i2c_bus_busy(bus->bus)) {
260
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
261
262
if (bus->cmd & I2CD_M_TX_CMD) {
263
aspeed_i2c_set_state(bus, I2CD_MTXD);
264
- if (i2c_send(bus->bus, bus->buf)) {
265
+ if (aspeed_i2c_bus_send(bus, pool_start)) {
266
bus->intr_status |= (I2CD_INTR_TX_NAK);
267
i2c_end_transfer(bus->bus);
268
} else {
269
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
270
qemu_log_mask(LOG_UNIMP, "%s: slave mode not implemented\n",
271
__func__);
272
break;
273
+ case I2CD_POOL_CTRL_REG:
274
+ bus->pool_ctrl &= ~0xffffff;
275
+ bus->pool_ctrl |= (value & 0xffffff);
276
+ break;
277
+
278
case I2CD_BYTE_BUF_REG:
279
bus->buf = (value & I2CD_BYTE_BUF_TX_MASK) << I2CD_BYTE_BUF_TX_SHIFT;
280
break;
281
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_ctrl_ops = {
282
.endianness = DEVICE_LITTLE_ENDIAN,
283
};
284
285
+static uint64_t aspeed_i2c_pool_read(void *opaque, hwaddr offset,
286
+ unsigned size)
287
+{
288
+ AspeedI2CState *s = opaque;
289
+ uint64_t ret = 0;
290
+ int i;
291
+
292
+ for (i = 0; i < size; i++) {
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
294
+ }
295
+
296
+ return ret;
297
+}
298
+
299
+static void aspeed_i2c_pool_write(void *opaque, hwaddr offset,
300
+ uint64_t value, unsigned size)
301
+{
302
+ AspeedI2CState *s = opaque;
303
+ int i;
304
+
305
+ for (i = 0; i < size; i++) {
306
+ s->pool[offset + i] = (value >> (8 * i)) & 0xFF;
307
+ }
308
+}
309
+
310
+static const MemoryRegionOps aspeed_i2c_pool_ops = {
311
+ .read = aspeed_i2c_pool_read,
312
+ .write = aspeed_i2c_pool_write,
313
+ .endianness = DEVICE_LITTLE_ENDIAN,
314
+ .valid = {
315
+ .min_access_size = 1,
316
+ .max_access_size = 4,
317
+ },
318
+};
319
+
320
static const VMStateDescription aspeed_i2c_bus_vmstate = {
321
.name = TYPE_ASPEED_I2C,
322
- .version_id = 1,
323
- .minimum_version_id = 1,
324
+ .version_id = 2,
325
+ .minimum_version_id = 2,
326
.fields = (VMStateField[]) {
327
VMSTATE_UINT8(id, AspeedI2CBus),
328
VMSTATE_UINT32(ctrl, AspeedI2CBus),
329
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
330
VMSTATE_UINT32(intr_status, AspeedI2CBus),
331
VMSTATE_UINT32(cmd, AspeedI2CBus),
332
VMSTATE_UINT32(buf, AspeedI2CBus),
333
+ VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
334
VMSTATE_END_OF_LIST()
335
}
336
};
337
338
static const VMStateDescription aspeed_i2c_vmstate = {
339
.name = TYPE_ASPEED_I2C,
340
- .version_id = 1,
341
- .minimum_version_id = 1,
342
+ .version_id = 2,
343
+ .minimum_version_id = 2,
344
.fields = (VMStateField[]) {
345
VMSTATE_UINT32(intr_status, AspeedI2CState),
346
VMSTATE_STRUCT_ARRAY(busses, AspeedI2CState,
347
ASPEED_I2C_NR_BUSSES, 1, aspeed_i2c_bus_vmstate,
348
AspeedI2CBus),
349
+ VMSTATE_UINT8_ARRAY(pool, AspeedI2CState, ASPEED_I2C_MAX_POOL_SIZE),
350
VMSTATE_END_OF_LIST()
351
}
352
};
353
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
354
memory_region_add_subregion(&s->iomem, aic->reg_size * (i + offset),
355
&s->busses[i].mr);
356
}
357
+
358
+ memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
359
+ "aspeed.i2c-pool", aic->pool_size);
360
+ memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
361
}
362
363
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
364
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2400_i2c_bus_get_irq(AspeedI2CBus *bus)
365
return bus->controller->irq;
366
}
367
368
+static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus)
369
+{
370
+ uint8_t *pool_page =
371
+ &bus->controller->pool[I2CD_POOL_PAGE_SEL(bus->ctrl) * 0x100];
372
+
373
+ return &pool_page[I2CD_POOL_OFFSET(bus->pool_ctrl)];
374
+}
375
+
376
static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
377
{
378
DeviceClass *dc = DEVICE_CLASS(klass);
379
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data)
380
aic->reg_size = 0x40;
381
aic->gap = 7;
382
aic->bus_get_irq = aspeed_2400_i2c_bus_get_irq;
383
+ aic->pool_size = 0x800;
384
+ aic->pool_base = 0x800;
385
+ aic->bus_pool_base = aspeed_2400_i2c_bus_pool_base;
386
}
387
388
static const TypeInfo aspeed_2400_i2c_info = {
389
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2500_i2c_bus_get_irq(AspeedI2CBus *bus)
390
return bus->controller->irq;
391
}
392
393
+static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus)
394
+{
395
+ return &bus->controller->pool[bus->id * 0x10];
396
+}
397
+
398
static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
399
{
400
DeviceClass *dc = DEVICE_CLASS(klass);
401
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
402
aic->reg_size = 0x40;
403
aic->gap = 7;
404
aic->bus_get_irq = aspeed_2500_i2c_bus_get_irq;
405
+ aic->pool_size = 0x100;
406
+ aic->pool_base = 0x200;
407
+ aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
408
}
409
410
static const TypeInfo aspeed_2500_i2c_info = {
411
@@ -XXX,XX +XXX,XX @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus)
412
return bus->irq;
413
}
414
415
+static uint8_t *aspeed_2600_i2c_bus_pool_base(AspeedI2CBus *bus)
416
+{
417
+ return &bus->controller->pool[bus->id * 0x20];
418
+}
419
+
420
static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
421
{
422
DeviceClass *dc = DEVICE_CLASS(klass);
423
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
424
aic->reg_size = 0x80;
425
aic->gap = -1; /* no gap */
426
aic->bus_get_irq = aspeed_2600_i2c_bus_get_irq;
427
+ aic->pool_size = 0x200;
428
+ aic->pool_base = 0xC00;
429
+ aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
430
}
431
432
static const TypeInfo aspeed_2600_i2c_info = {
433
--
434
2.20.1
435
436
diff view generated by jsdifflib
1
Provide a VMSTATE_BOOL_SUB_ARRAY to go with VMSTATE_UINT8_SUB_ARRAY
1
From: Cédric Le Goater <clg@kaod.org>
2
and friends.
3
2
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
4
mode. This is not required on other SoCs.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
9
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191119141211.25716-3-clg@kaod.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180521140402.23318-23-peter.maydell@linaro.org
7
---
12
---
8
include/migration/vmstate.h | 3 +++
13
include/hw/i2c/aspeed_i2c.h | 3 +++
9
1 file changed, 3 insertions(+)
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
15
2 files changed, 40 insertions(+)
10
16
11
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/include/migration/vmstate.h
19
--- a/include/hw/i2c/aspeed_i2c.h
14
+++ b/include/migration/vmstate.h
20
+++ b/include/hw/i2c/aspeed_i2c.h
15
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
16
#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
22
qemu_irq irq;
17
VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
23
18
24
uint32_t intr_status;
19
+#define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \
25
+ uint32_t ctrl_global;
20
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool)
26
MemoryRegion pool_iomem;
27
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
28
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
30
uint64_t pool_size;
31
hwaddr pool_base;
32
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
33
+ bool check_sram;
21
+
34
+
22
#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
35
} AspeedI2CClass;
23
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
36
24
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
41
+++ b/hw/i2c/aspeed_i2c.c
42
@@ -XXX,XX +XXX,XX @@
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
45
Assignment */
46
+#define I2C_CTRL_GLOBAL 0x0C /* Global Control Register */
47
+#define I2C_CTRL_SRAM_EN BIT(0)
48
49
/* I2C Device (Bus) Register */
50
51
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
52
}
53
}
54
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
56
+{
57
+ AspeedI2CState *s = bus->controller;
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
59
+
60
+ if (!aic->check_sram) {
61
+ return true;
62
+ }
63
+
64
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
66
+ * DMA mode.
67
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+}
77
+
78
/*
79
* The state machine needs some refinement. It is only used to track
80
* invalid STOP commands for the moment.
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
82
bus->cmd &= ~0xFFFF;
83
bus->cmd |= value & 0xFFFF;
84
85
+ if (!aspeed_i2c_check_sram(bus)) {
86
+ return;
87
+ }
88
+
89
if (bus->cmd & I2CD_M_START_CMD) {
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
91
I2CD_MSTARTR : I2CD_MSTART;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
93
switch (offset) {
94
case I2C_CTRL_STATUS:
95
return s->intr_status;
96
+ case I2C_CTRL_GLOBAL:
97
+ return s->ctrl_global;
98
default:
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
100
__func__, offset);
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
103
uint64_t value, unsigned size)
104
{
105
+ AspeedI2CState *s = opaque;
106
+
107
switch (offset) {
108
+ case I2C_CTRL_GLOBAL:
109
+ s->ctrl_global = value;
110
+ break;
111
case I2C_CTRL_STATUS:
112
default:
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
115
aic->pool_size = 0x100;
116
aic->pool_base = 0x200;
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
118
+ aic->check_sram = true;
119
}
120
121
static const TypeInfo aspeed_2500_i2c_info = {
25
--
122
--
26
2.17.1
123
2.20.1
27
124
28
125
diff view generated by jsdifflib
1
From: Jan Kiszka <jan.kiszka@siemens.com>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
There was a nasty flip in identifying which register group an access is
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
4
targeting. The issue caused spuriously raised priorities of the guest
4
through a property alias at the SoC level. The I2C model will need a
5
when handing CPUs over in the Jailhouse hypervisor.
5
similar region for DMA support, add a DRAM region property at the SoC
6
level for both model to use.
6
7
7
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
9
Message-id: 28b927d3-da58-bce4-cc13-bfec7f9b1cb9@siemens.com
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
14
---
13
hw/intc/arm_gicv3_cpuif.c | 12 ++++++------
15
include/hw/arm/aspeed_soc.h | 1 +
14
1 file changed, 6 insertions(+), 6 deletions(-)
16
hw/arm/aspeed_ast2600.c | 7 +++++--
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
15
19
16
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_cpuif.c
22
--- a/include/hw/arm/aspeed_soc.h
19
+++ b/hw/intc/arm_gicv3_cpuif.c
23
+++ b/include/hw/arm/aspeed_soc.h
20
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
21
{
25
ARMCPU cpu[ASPEED_CPUS_NUM];
22
GICv3CPUState *cs = icc_cs_from_env(env);
26
uint32_t num_cpus;
23
int regno = ri->opc2 & 3;
27
A15MPPrivState a7mpcore;
24
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
28
+ MemoryRegion *dram_mr;
25
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
29
MemoryRegion sram;
26
uint64_t value = cs->ich_apr[grp][regno];
30
AspeedVICState vic;
27
31
AspeedRtcState rtc;
28
trace_gicv3_icv_ap_read(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
29
@@ -XXX,XX +XXX,XX @@ static void icv_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
33
index XXXXXXX..XXXXXXX 100644
30
{
34
--- a/hw/arm/aspeed_ast2600.c
31
GICv3CPUState *cs = icc_cs_from_env(env);
35
+++ b/hw/arm/aspeed_ast2600.c
32
int regno = ri->opc2 & 3;
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
33
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
37
typename);
34
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
35
39
&error_abort);
36
trace_gicv3_icv_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
37
41
- &error_abort);
38
@@ -XXX,XX +XXX,XX @@ static uint64_t icc_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
42
39
uint64_t value;
43
for (i = 0; i < sc->spis_num; i++) {
40
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
41
int regno = ri->opc2 & 3;
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
42
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
46
}
43
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
47
44
48
/* FMC, The number of CS is set at the board level */
45
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
46
return icv_ap_read(env, ri);
50
+ if (err) {
47
@@ -XXX,XX +XXX,XX @@ static void icc_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
51
+ error_propagate(errp, err);
48
GICv3CPUState *cs = icc_cs_from_env(env);
52
+ return;
49
53
+ }
50
int regno = ri->opc2 & 3;
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
51
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1;
55
"sdram-base", &err);
52
+ int grp = (ri->crm & 1) ? GICV3_G1 : GICV3_G0;
56
if (err) {
53
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
54
if (icv_access(env, grp == GICV3_G0 ? HCR_FMO : HCR_IMO)) {
58
index XXXXXXX..XXXXXXX 100644
55
icv_ap_write(env, ri, value);
59
--- a/hw/arm/aspeed_soc.c
56
@@ -XXX,XX +XXX,XX @@ static uint64_t ich_ap_read(CPUARMState *env, const ARMCPRegInfo *ri)
60
+++ b/hw/arm/aspeed_soc.c
57
{
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
58
GICv3CPUState *cs = icc_cs_from_env(env);
62
typename);
59
int regno = ri->opc2 & 3;
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
60
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
64
&error_abort);
61
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
62
uint64_t value;
66
- &error_abort);
63
67
64
value = cs->ich_apr[grp][regno];
68
for (i = 0; i < sc->spis_num; i++) {
65
@@ -XXX,XX +XXX,XX @@ static void ich_ap_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
66
{
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
67
GICv3CPUState *cs = icc_cs_from_env(env);
71
aspeed_soc_get_irq(s, ASPEED_I2C));
68
int regno = ri->opc2 & 3;
72
69
- int grp = ri->crm & 1 ? GICV3_G0 : GICV3_G1NS;
73
/* FMC, The number of CS is set at the board level */
70
+ int grp = (ri->crm & 1) ? GICV3_G1NS : GICV3_G0;
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
71
75
+ if (err) {
72
trace_gicv3_ich_ap_write(ri->crm & 1, regno, gicv3_redist_affid(cs), value);
76
+ error_propagate(errp, err);
77
+ return;
78
+ }
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
80
"sdram-base", &err);
81
if (err) {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
83
}
84
static Property aspeed_soc_properties[] = {
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
87
+ MemoryRegion *),
88
DEFINE_PROP_END_OF_LIST(),
89
};
73
90
74
--
91
--
75
2.17.1
92
2.20.1
76
93
77
94
diff view generated by jsdifflib
New patch
1
1
From: Cédric Le Goater <clg@kaod.org>
2
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
4
transfers to and from DRAM.
5
6
A pair of registers defines the buffer address and the length of the
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
8
length should not exceed 4K. The receive or transmit DMA transfer can
9
then be initiated with specific bits in the Command/Status register of
10
the controller.
11
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
16
Message-id: 20191119141211.25716-5-clg@kaod.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
20
hw/arm/aspeed_ast2600.c | 5 ++
21
hw/arm/aspeed_soc.c | 5 ++
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
23
4 files changed, 138 insertions(+), 3 deletions(-)
24
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
28
+++ b/include/hw/i2c/aspeed_i2c.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
30
uint32_t cmd;
31
uint32_t buf;
32
uint32_t pool_ctrl;
33
+ uint32_t dma_addr;
34
+ uint32_t dma_len;
35
} AspeedI2CBus;
36
37
typedef struct AspeedI2CState {
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
40
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
42
+ MemoryRegion *dram_mr;
43
+ AddressSpace dram_as;
44
} AspeedI2CState;
45
46
#define ASPEED_I2C_CLASS(klass) \
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
48
hwaddr pool_base;
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
50
bool check_sram;
51
+ bool has_dma;
52
53
} AspeedI2CClass;
54
55
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/aspeed_ast2600.c
58
+++ b/hw/arm/aspeed_ast2600.c
59
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
60
}
61
62
/* I2C */
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
64
+ if (err) {
65
+ error_propagate(errp, err);
66
+ return;
67
+ }
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
69
if (err) {
70
error_propagate(errp, err);
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/arm/aspeed_soc.c
74
+++ b/hw/arm/aspeed_soc.c
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
76
}
77
78
/* I2C */
79
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
80
+ if (err) {
81
+ error_propagate(errp, err);
82
+ return;
83
+ }
84
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
85
if (err) {
86
error_propagate(errp, err);
87
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/i2c/aspeed_i2c.c
90
+++ b/hw/i2c/aspeed_i2c.c
91
@@ -XXX,XX +XXX,XX @@
92
#include "migration/vmstate.h"
93
#include "qemu/log.h"
94
#include "qemu/module.h"
95
+#include "qemu/error-report.h"
96
+#include "qapi/error.h"
97
#include "hw/i2c/aspeed_i2c.h"
98
#include "hw/irq.h"
99
+#include "hw/qdev-properties.h"
100
101
/* I2C Global Register */
102
103
@@ -XXX,XX +XXX,XX @@
104
#define I2CD_BYTE_BUF_TX_MASK 0xff
105
#define I2CD_BYTE_BUF_RX_SHIFT 8
106
#define I2CD_BYTE_BUF_RX_MASK 0xff
107
-
108
+#define I2CD_DMA_ADDR 0x24 /* DMA Buffer Address */
109
+#define I2CD_DMA_LEN 0x28 /* DMA Transfer Length < 4KB */
110
111
static inline bool aspeed_i2c_bus_is_master(AspeedI2CBus *bus)
112
{
113
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
114
unsigned size)
115
{
116
AspeedI2CBus *bus = opaque;
117
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
118
119
switch (offset) {
120
case I2CD_FUN_CTRL_REG:
121
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
122
return bus->buf;
123
case I2CD_CMD_REG:
124
return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
125
+ case I2CD_DMA_ADDR:
126
+ if (!aic->has_dma) {
127
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
128
+ return -1;
129
+ }
130
+ return bus->dma_addr;
131
+ case I2CD_DMA_LEN:
132
+ if (!aic->has_dma) {
133
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
134
+ return -1;
135
+ }
136
+ return bus->dma_len;
137
default:
138
qemu_log_mask(LOG_GUEST_ERROR,
139
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
140
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_state(AspeedI2CBus *bus)
141
return (bus->cmd >> I2CD_TX_STATE_SHIFT) & I2CD_TX_STATE_MASK;
142
}
143
144
+static int aspeed_i2c_dma_read(AspeedI2CBus *bus, uint8_t *data)
145
+{
146
+ MemTxResult result;
147
+ AspeedI2CState *s = bus->controller;
148
+
149
+ result = address_space_read(&s->dram_as, bus->dma_addr,
150
+ MEMTXATTRS_UNSPECIFIED, data, 1);
151
+ if (result != MEMTX_OK) {
152
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
153
+ __func__, bus->dma_addr);
154
+ return -1;
155
+ }
156
+
157
+ bus->dma_addr++;
158
+ bus->dma_len--;
159
+ return 0;
160
+}
161
+
162
static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
163
{
164
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
165
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
166
}
167
}
168
bus->cmd &= ~I2CD_TX_BUFF_ENABLE;
169
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
170
+ while (bus->dma_len) {
171
+ uint8_t data;
172
+ aspeed_i2c_dma_read(bus, &data);
173
+ ret = i2c_send(bus->bus, data);
174
+ if (ret) {
175
+ break;
176
+ }
177
+ }
178
+ bus->cmd &= ~I2CD_TX_DMA_ENABLE;
179
} else {
180
ret = i2c_send(bus->bus, bus->buf);
181
}
182
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
183
bus->pool_ctrl &= ~(0xff << 24);
184
bus->pool_ctrl |= (i & 0xff) << 24;
185
bus->cmd &= ~I2CD_RX_BUFF_ENABLE;
186
+ } else if (bus->cmd & I2CD_RX_DMA_ENABLE) {
187
+ uint8_t data;
188
+
189
+ while (bus->dma_len) {
190
+ MemTxResult result;
191
+
192
+ data = i2c_recv(bus->bus);
193
+ result = address_space_write(&s->dram_as, bus->dma_addr,
194
+ MEMTXATTRS_UNSPECIFIED, &data, 1);
195
+ if (result != MEMTX_OK) {
196
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
197
+ __func__, bus->dma_addr);
198
+ return;
199
+ }
200
+ bus->dma_addr++;
201
+ bus->dma_len--;
202
+ }
203
+ bus->cmd &= ~I2CD_RX_DMA_ENABLE;
204
} else {
205
data = i2c_recv(bus->bus);
206
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
207
@@ -XXX,XX +XXX,XX @@ static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
208
uint8_t *pool_base = aic->bus_pool_base(bus);
209
210
return pool_base[0];
211
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
212
+ uint8_t data;
213
+
214
+ aspeed_i2c_dma_read(bus, &data);
215
+ return data;
216
} else {
217
return bus->buf;
218
}
219
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
220
*/
221
pool_start++;
222
}
223
+ } else if (bus->cmd & I2CD_TX_DMA_ENABLE) {
224
+ if (bus->dma_len == 0) {
225
+ bus->cmd &= ~I2CD_M_TX_CMD;
226
+ }
227
} else {
228
bus->cmd &= ~I2CD_M_TX_CMD;
229
}
230
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
231
break;
232
}
233
234
+ if (!aic->has_dma &&
235
+ value & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE)) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
237
+ break;
238
+ }
239
+
240
aspeed_i2c_bus_handle_cmd(bus, value);
241
aspeed_i2c_bus_raise_interrupt(bus);
242
break;
243
+ case I2CD_DMA_ADDR:
244
+ if (!aic->has_dma) {
245
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
246
+ break;
247
+ }
248
+
249
+ bus->dma_addr = value & 0xfffffffc;
250
+ break;
251
+
252
+ case I2CD_DMA_LEN:
253
+ if (!aic->has_dma) {
254
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
255
+ break;
256
+ }
257
+
258
+ bus->dma_len = value & 0xfff;
259
+ if (!bus->dma_len) {
260
+ qemu_log_mask(LOG_UNIMP, "%s: invalid DMA length\n", __func__);
261
+ }
262
+ break;
263
264
default:
265
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
266
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_i2c_pool_ops = {
267
268
static const VMStateDescription aspeed_i2c_bus_vmstate = {
269
.name = TYPE_ASPEED_I2C,
270
- .version_id = 2,
271
- .minimum_version_id = 2,
272
+ .version_id = 3,
273
+ .minimum_version_id = 3,
274
.fields = (VMStateField[]) {
275
VMSTATE_UINT8(id, AspeedI2CBus),
276
VMSTATE_UINT32(ctrl, AspeedI2CBus),
277
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription aspeed_i2c_bus_vmstate = {
278
VMSTATE_UINT32(cmd, AspeedI2CBus),
279
VMSTATE_UINT32(buf, AspeedI2CBus),
280
VMSTATE_UINT32(pool_ctrl, AspeedI2CBus),
281
+ VMSTATE_UINT32(dma_addr, AspeedI2CBus),
282
+ VMSTATE_UINT32(dma_len, AspeedI2CBus),
283
VMSTATE_END_OF_LIST()
284
}
285
};
286
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_reset(DeviceState *dev)
287
s->busses[i].intr_status = 0;
288
s->busses[i].cmd = 0;
289
s->busses[i].buf = 0;
290
+ s->busses[i].dma_addr = 0;
291
+ s->busses[i].dma_len = 0;
292
i2c_end_transfer(s->busses[i].bus);
293
}
294
}
295
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_realize(DeviceState *dev, Error **errp)
296
memory_region_init_io(&s->pool_iomem, OBJECT(s), &aspeed_i2c_pool_ops, s,
297
"aspeed.i2c-pool", aic->pool_size);
298
memory_region_add_subregion(&s->iomem, aic->pool_base, &s->pool_iomem);
299
+
300
+ if (aic->has_dma) {
301
+ if (!s->dram_mr) {
302
+ error_setg(errp, TYPE_ASPEED_I2C ": 'dram' link not set");
303
+ return;
304
+ }
305
+
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
307
+ }
308
}
309
310
+static Property aspeed_i2c_properties[] = {
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
313
+ DEFINE_PROP_END_OF_LIST(),
314
+};
315
+
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
317
{
318
DeviceClass *dc = DEVICE_CLASS(klass);
319
320
dc->vmsd = &aspeed_i2c_vmstate;
321
dc->reset = aspeed_i2c_reset;
322
+ dc->props = aspeed_i2c_properties;
323
dc->realize = aspeed_i2c_realize;
324
dc->desc = "Aspeed I2C Controller";
325
}
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
327
aic->pool_base = 0x200;
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
329
aic->check_sram = true;
330
+ aic->has_dma = true;
331
}
332
333
static const TypeInfo aspeed_2500_i2c_info = {
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
335
aic->pool_size = 0x200;
336
aic->pool_base = 0xC00;
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
338
+ aic->has_dma = true;
339
}
340
341
static const TypeInfo aspeed_2600_i2c_info = {
342
--
343
2.20.1
344
345
diff view generated by jsdifflib
New patch
1
1
From: Cédric Le Goater <clg@kaod.org>
2
3
Signed-off-by: Cédric Le Goater <clg@kaod.org>
4
Reviewed-by: Joel Stanley <joel@jms.id.au>
5
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-6-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
12
hw/i2c/trace-events | 9 +++++
13
2 files changed, 89 insertions(+), 13 deletions(-)
14
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
18
+++ b/hw/i2c/aspeed_i2c.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/i2c/aspeed_i2c.h"
21
#include "hw/irq.h"
22
#include "hw/qdev-properties.h"
23
+#include "trace.h"
24
25
/* I2C Global Register */
26
27
@@ -XXX,XX +XXX,XX @@ static inline void aspeed_i2c_bus_raise_interrupt(AspeedI2CBus *bus)
28
{
29
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
30
31
+ trace_aspeed_i2c_bus_raise_interrupt(bus->intr_status,
32
+ bus->intr_status & I2CD_INTR_TX_NAK ? "nak|" : "",
33
+ bus->intr_status & I2CD_INTR_TX_ACK ? "ack|" : "",
34
+ bus->intr_status & I2CD_INTR_RX_DONE ? "done|" : "",
35
+ bus->intr_status & I2CD_INTR_NORMAL_STOP ? "normal|" : "",
36
+ bus->intr_status & I2CD_INTR_ABNORMAL ? "abnormal" : "");
37
+
38
bus->intr_status &= bus->intr_ctrl;
39
if (bus->intr_status) {
40
bus->controller->intr_status |= 1 << bus->id;
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
42
{
43
AspeedI2CBus *bus = opaque;
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
45
+ uint64_t value = -1;
46
47
switch (offset) {
48
case I2CD_FUN_CTRL_REG:
49
- return bus->ctrl;
50
+ value = bus->ctrl;
51
+ break;
52
case I2CD_AC_TIMING_REG1:
53
- return bus->timing[0];
54
+ value = bus->timing[0];
55
+ break;
56
case I2CD_AC_TIMING_REG2:
57
- return bus->timing[1];
58
+ value = bus->timing[1];
59
+ break;
60
case I2CD_INTR_CTRL_REG:
61
- return bus->intr_ctrl;
62
+ value = bus->intr_ctrl;
63
+ break;
64
case I2CD_INTR_STS_REG:
65
- return bus->intr_status;
66
+ value = bus->intr_status;
67
+ break;
68
case I2CD_POOL_CTRL_REG:
69
- return bus->pool_ctrl;
70
+ value = bus->pool_ctrl;
71
+ break;
72
case I2CD_BYTE_BUF_REG:
73
- return bus->buf;
74
+ value = bus->buf;
75
+ break;
76
case I2CD_CMD_REG:
77
- return bus->cmd | (i2c_bus_busy(bus->bus) << 16);
78
+ value = bus->cmd | (i2c_bus_busy(bus->bus) << 16);
79
+ break;
80
case I2CD_DMA_ADDR:
81
if (!aic->has_dma) {
82
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
83
- return -1;
84
+ break;
85
}
86
- return bus->dma_addr;
87
+ value = bus->dma_addr;
88
+ break;
89
case I2CD_DMA_LEN:
90
if (!aic->has_dma) {
91
qemu_log_mask(LOG_GUEST_ERROR, "%s: No DMA support\n", __func__);
92
- return -1;
93
+ break;
94
}
95
- return bus->dma_len;
96
+ value = bus->dma_len;
97
+ break;
98
+
99
default:
100
qemu_log_mask(LOG_GUEST_ERROR,
101
"%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, offset);
102
- return -1;
103
+ value = -1;
104
+ break;
105
}
106
+
107
+ trace_aspeed_i2c_bus_read(bus->id, offset, size, value);
108
+ return value;
109
}
110
111
static void aspeed_i2c_set_state(AspeedI2CBus *bus, uint8_t state)
112
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
113
for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
114
uint8_t *pool_base = aic->bus_pool_base(bus);
115
116
+ trace_aspeed_i2c_bus_send("BUF", i + 1,
117
+ I2CD_POOL_TX_COUNT(bus->pool_ctrl),
118
+ pool_base[i]);
119
ret = i2c_send(bus->bus, pool_base[i]);
120
if (ret) {
121
break;
122
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
123
while (bus->dma_len) {
124
uint8_t data;
125
aspeed_i2c_dma_read(bus, &data);
126
+ trace_aspeed_i2c_bus_send("DMA", bus->dma_len, bus->dma_len, data);
127
ret = i2c_send(bus->bus, data);
128
if (ret) {
129
break;
130
@@ -XXX,XX +XXX,XX @@ static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
131
}
132
bus->cmd &= ~I2CD_TX_DMA_ENABLE;
133
} else {
134
+ trace_aspeed_i2c_bus_send("BYTE", pool_start, 1, bus->buf);
135
ret = i2c_send(bus->bus, bus->buf);
136
}
137
138
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
139
140
for (i = 0; i < I2CD_POOL_RX_SIZE(bus->pool_ctrl); i++) {
141
pool_base[i] = i2c_recv(bus->bus);
142
+ trace_aspeed_i2c_bus_recv("BUF", i + 1,
143
+ I2CD_POOL_RX_SIZE(bus->pool_ctrl),
144
+ pool_base[i]);
145
}
146
147
/* Update RX count */
148
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
149
MemTxResult result;
150
151
data = i2c_recv(bus->bus);
152
+ trace_aspeed_i2c_bus_recv("DMA", bus->dma_len, bus->dma_len, data);
153
result = address_space_write(&s->dram_as, bus->dma_addr,
154
MEMTXATTRS_UNSPECIFIED, &data, 1);
155
if (result != MEMTX_OK) {
156
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
157
bus->cmd &= ~I2CD_RX_DMA_ENABLE;
158
} else {
159
data = i2c_recv(bus->bus);
160
+ trace_aspeed_i2c_bus_recv("BYTE", 1, 1, bus->buf);
161
bus->buf = (data & I2CD_BYTE_BUF_RX_MASK) << I2CD_BYTE_BUF_RX_SHIFT;
162
}
163
}
164
@@ -XXX,XX +XXX,XX @@ static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
165
return true;
166
}
167
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
169
+{
170
+ g_autofree char *cmd_flags;
171
+ uint32_t count;
172
+
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
175
+ } else if (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_RX_DMA_ENABLE)) {
176
+ count = bus->dma_len;
177
+ } else { /* BYTE mode */
178
+ count = 1;
179
+ }
180
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
185
+ bus->cmd & I2CD_RX_BUFF_ENABLE ? "rxbuf|" : "",
186
+ bus->cmd & I2CD_TX_BUFF_ENABLE ? "txbuf|" : "",
187
+ bus->cmd & I2CD_M_TX_CMD ? "tx|" : "",
188
+ bus->cmd & I2CD_M_RX_CMD ? "rx|" : "",
189
+ bus->cmd & I2CD_M_S_RX_CMD_LAST ? "last|" : "",
190
+ bus->cmd & I2CD_M_STOP_CMD ? "stop" : "");
191
+
192
+ trace_aspeed_i2c_bus_cmd(bus->cmd, cmd_flags, count, bus->intr_status);
193
+}
194
+
195
/*
196
* The state machine needs some refinement. It is only used to track
197
* invalid STOP commands for the moment.
198
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
199
return;
200
}
201
202
+ if (trace_event_get_state_backends(TRACE_ASPEED_I2C_BUS_CMD)) {
203
+ aspeed_i2c_bus_cmd_dump(bus);
204
+ }
205
+
206
if (bus->cmd & I2CD_M_START_CMD) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
208
I2CD_MSTARTR : I2CD_MSTART;
209
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_write(void *opaque, hwaddr offset,
210
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
211
bool handle_rx;
212
213
+ trace_aspeed_i2c_bus_write(bus->id, offset, size, value);
214
+
215
switch (offset) {
216
case I2CD_FUN_CTRL_REG:
217
if (value & I2CD_SLAVE_EN) {
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
221
+++ b/hw/i2c/trace-events
222
@@ -XXX,XX +XXX,XX @@
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
226
+
227
+# aspeed_i2c.c
228
+
229
+aspeed_i2c_bus_cmd(uint32_t cmd, const char *cmd_flags, uint32_t count, uint32_t intr_status) "handling cmd=0x%x %s count=%d intr=0x%x"
230
+aspeed_i2c_bus_raise_interrupt(uint32_t intr_status, const char *str1, const char *str2, const char *str3, const char *str4, const char *str5) "handled intr=0x%x %s%s%s%s%s"
231
+aspeed_i2c_bus_read(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
232
+aspeed_i2c_bus_write(uint32_t busid, uint64_t offset, unsigned size, uint64_t value) "bus[%d]: To 0x%" PRIx64 " of size %u: 0x%" PRIx64
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
235
--
236
2.20.1
237
238
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
Most boards have this much.
4
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-7-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
18
+++ b/hw/misc/aspeed_sdmc.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
20
}
21
22
/* use a common default */
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
25
s->ram_size);
26
- s->ram_size = 512 << 20;
27
- return ASPEED_SDMC_AST2600_512MB;
28
+ s->ram_size = 1024 << 20;
29
+ return ASPEED_SDMC_AST2600_1024MB;
30
}
31
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Joel Stanley <joel@jms.id.au>
2
add MemTxAttrs as an argument to memory_region_access_valid().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
6
The callsite in flatview_access_valid() is part of a recursive
3
This models the clock write one to clear registers, and fixes up some
7
loop flatview_access_valid() -> memory_region_access_valid() ->
4
incorrect behavior in all of the write to clear registers.
8
subpage_accepts() -> flatview_access_valid(); we make it pass
9
MEMTXATTRS_UNSPECIFIED for now, until the next several commits
10
have plumbed an attrs parameter through the rest of the loop
11
and we can add an attrs parameter to flatview_access_valid().
12
5
6
There was also a typo in one of the register definitions.
7
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-8-clg@kaod.org
13
[clg: checkpatch.pl fixes ]
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20180521140402.23318-8-peter.maydell@linaro.org
17
---
16
---
18
include/exec/memory-internal.h | 3 ++-
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
19
exec.c | 4 +++-
18
1 file changed, 14 insertions(+), 5 deletions(-)
20
hw/s390x/s390-pci-inst.c | 3 ++-
21
memory.c | 7 ++++---
22
4 files changed, 11 insertions(+), 6 deletions(-)
23
19
24
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory-internal.h
22
--- a/hw/misc/aspeed_scu.c
27
+++ b/include/exec/memory-internal.h
23
+++ b/hw/misc/aspeed_scu.c
28
@@ -XXX,XX +XXX,XX @@ void flatview_unref(FlatView *view);
24
@@ -XXX,XX +XXX,XX @@
29
extern const MemoryRegionOps unassigned_mem_ops;
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
30
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
31
bool memory_region_access_valid(MemoryRegion *mr, hwaddr addr,
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
32
- unsigned size, bool is_write);
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
33
+ unsigned size, bool is_write,
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
34
+ MemTxAttrs attrs);
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
35
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
36
void flatview_add_to_dispatch(FlatView *fv, MemoryRegionSection *section);
32
#define AST2600_HPLL_EXT TO_REG(0x204)
37
AddressSpaceDispatch *address_space_dispatch_new(FlatView *fv);
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
38
diff --git a/exec.c b/exec.c
34
return s->regs[reg];
39
index XXXXXXX..XXXXXXX 100644
35
}
40
--- a/exec.c
36
41
+++ b/exec.c
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
42
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
38
- unsigned size)
43
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
44
if (!memory_access_is_direct(mr, is_write)) {
40
+ uint64_t data64, unsigned size)
45
l = memory_access_size(mr, l, addr);
46
- if (!memory_region_access_valid(mr, xlat, l, is_write)) {
47
+ /* When our callers all have attrs we'll pass them through here */
48
+ if (!memory_region_access_valid(mr, xlat, l, is_write,
49
+ MEMTXATTRS_UNSPECIFIED)) {
50
return false;
51
}
52
}
53
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/s390x/s390-pci-inst.c
56
+++ b/hw/s390x/s390-pci-inst.c
57
@@ -XXX,XX +XXX,XX @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr,
58
mr = s390_get_subregion(mr, offset, len);
59
offset -= mr->addr;
60
61
- if (!memory_region_access_valid(mr, offset, len, true)) {
62
+ if (!memory_region_access_valid(mr, offset, len, true,
63
+ MEMTXATTRS_UNSPECIFIED)) {
64
s390_program_interrupt(env, PGM_OPERAND, 6, ra);
65
return 0;
66
}
67
diff --git a/memory.c b/memory.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/memory.c
70
+++ b/memory.c
71
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps ram_device_mem_ops = {
72
bool memory_region_access_valid(MemoryRegion *mr,
73
hwaddr addr,
74
unsigned size,
75
- bool is_write)
76
+ bool is_write,
77
+ MemTxAttrs attrs)
78
{
41
{
79
int access_size_min, access_size_max;
42
AspeedSCUState *s = ASPEED_SCU(opaque);
80
int access_size, i;
43
int reg = TO_REG(offset);
81
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
44
+ /* Truncate here so bitwise operations below behave as expected */
82
{
45
+ uint32_t data = data64;
83
MemTxResult r;
46
84
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
85
- if (!memory_region_access_valid(mr, addr, size, false)) {
48
qemu_log_mask(LOG_GUEST_ERROR,
86
+ if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
87
*pval = unassigned_mem_read(mr, addr, size);
50
/* fall through */
88
return MEMTX_DECODE_ERROR;
51
case AST2600_SYS_RST_CTRL:
89
}
52
case AST2600_SYS_RST_CTRL2:
90
@@ -XXX,XX +XXX,XX @@ MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
53
+ case AST2600_CLK_STOP_CTRL:
91
unsigned size,
54
+ case AST2600_CLK_STOP_CTRL2:
92
MemTxAttrs attrs)
55
/* W1S (Write 1 to set) registers */
93
{
56
s->regs[reg] |= data;
94
- if (!memory_region_access_valid(mr, addr, size, true)) {
57
return;
95
+ if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
58
case AST2600_SYS_RST_CTRL_CLR:
96
unassigned_mem_write(mr, addr, data, size);
59
case AST2600_SYS_RST_CTRL2_CLR:
97
return MEMTX_DECODE_ERROR;
60
+ case AST2600_CLK_STOP_CTRL_CLR:
98
}
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
62
case AST2600_HW_STRAP1_CLR:
63
case AST2600_HW_STRAP2_CLR:
64
- /* W1C (Write 1 to clear) registers */
65
- s->regs[reg] &= ~data;
66
+ /*
67
+ * W1C (Write 1 to clear) registers are offset by one address from
68
+ * the data register
69
+ */
70
+ s->regs[reg - 1] &= ~data;
71
return;
72
73
case AST2600_RNG_DATA:
99
--
74
--
100
2.17.1
75
2.20.1
101
76
102
77
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
kvm_irqchip_create called by kvm_init will call kvm_init_irq_routing to
3
Users benefit from knowing which watchdog timer has expired. The address
4
initialize global capability variables. If we call kvm_init_irq_routing in
4
of the watchdog's registers unambiguously indicates which has expired,
5
GIC realize function, previous allocated memory will leak.
5
so log that.
6
6
7
Fix this by deleting the unnecessary call.
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
8
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 1527750994-14360-1-git-send-email-zhaoshenglong@huawei.com
11
Message-id: 20191119141211.25716-9-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/intc/arm_gic_kvm.c | 1 -
14
hw/watchdog/wdt_aspeed.c | 3 ++-
15
hw/intc/arm_gicv3_kvm.c | 1 -
15
1 file changed, 2 insertions(+), 1 deletion(-)
16
2 files changed, 2 deletions(-)
17
16
18
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic_kvm.c
19
--- a/hw/watchdog/wdt_aspeed.c
21
+++ b/hw/intc/arm_gic_kvm.c
20
+++ b/hw/watchdog/wdt_aspeed.c
22
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
23
22
return;
24
if (kvm_has_gsi_routing()) {
23
}
25
/* set up irq routing */
24
26
- kvm_init_irq_routing(kvm_state);
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
27
for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
28
kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
27
+ s->iomem.addr);
29
}
28
watchdog_perform_action();
30
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
29
timer_del(s->timer);
31
index XXXXXXX..XXXXXXX 100644
30
}
32
--- a/hw/intc/arm_gicv3_kvm.c
33
+++ b/hw/intc/arm_gicv3_kvm.c
34
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
35
36
if (kvm_has_gsi_routing()) {
37
/* set up irq routing */
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
}
42
--
31
--
43
2.17.1
32
2.20.1
44
33
45
34
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
Depending on the host abi, float16, aka uint16_t, values are
3
The AST2600 control register sneakily changed the meaning of bit 4
4
passed and returned either zero-extended in the host register
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
5
or with garbage at the top of the host register.
5
select, and instead always runs at 1MHz.
6
6
7
The tcg code generator has so far been assuming garbage, as that
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
8
matches the x86 abi, but this is incorrect for other host abis.
8
only. We can model both using the same fixed 1MHz calculation.
9
Further, target/arm has so far been assuming zero-extended results,
10
so that it may store the 16-bit value into a 32-bit slot with the
11
high 16-bits already clear.
12
9
13
Rectify both problems by mapping "f16" in the helper definition
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
14
to uint32_t instead of (a typedef for) uint16_t. This forces
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
15
the host compiler to assume garbage in the upper 16 bits on input
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
16
and to zero-extend the result on output.
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
17
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
18
Cc: qemu-stable@nongnu.org
15
Message-id: 20191119141211.25716-10-clg@kaod.org
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
22
Message-id: 20180522175629.24932-1-richard.henderson@linaro.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
17
---
26
include/exec/helper-head.h | 2 +-
18
include/hw/watchdog/wdt_aspeed.h | 1 +
27
target/arm/helper-a64.c | 35 +++++++++--------
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
28
target/arm/helper.c | 80 +++++++++++++++++++-------------------
20
2 files changed, 18 insertions(+), 4 deletions(-)
29
3 files changed, 59 insertions(+), 58 deletions(-)
30
21
31
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
32
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
33
--- a/include/exec/helper-head.h
24
--- a/include/hw/watchdog/wdt_aspeed.h
34
+++ b/include/exec/helper-head.h
25
+++ b/include/hw/watchdog/wdt_aspeed.h
35
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
36
#define dh_ctype_int int
27
uint32_t ext_pulse_width_mask;
37
#define dh_ctype_i64 uint64_t
28
uint32_t reset_ctrl_reg;
38
#define dh_ctype_s64 int64_t
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
39
-#define dh_ctype_f16 float16
30
+ void (*wdt_reload)(AspeedWDTState *s);
40
+#define dh_ctype_f16 uint32_t
31
} AspeedWDTClass;
41
#define dh_ctype_f32 float32
32
42
#define dh_ctype_f64 float64
33
#endif /* WDT_ASPEED_H */
43
#define dh_ctype_ptr void *
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
44
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
45
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/helper-a64.c
36
--- a/hw/watchdog/wdt_aspeed.c
47
+++ b/target/arm/helper-a64.c
37
+++ b/hw/watchdog/wdt_aspeed.c
48
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
49
return flags;
39
50
}
40
}
51
41
52
-uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
53
+uint64_t HELPER(vfp_cmph_a64)(uint32_t x, uint32_t y, void *fp_status)
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
54
{
44
{
55
return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
45
uint64_t reload;
56
}
46
57
47
- if (pclk) {
58
-uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
59
+uint64_t HELPER(vfp_cmpeh_a64)(uint32_t x, uint32_t y, void *fp_status)
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
60
{
50
s->pclk_freq);
61
return float_rel_to_flags(float16_compare(x, y, fp_status));
51
} else {
62
}
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
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
194
diff --git a/target/arm/helper.c b/target/arm/helper.c
195
index XXXXXXX..XXXXXXX 100644
196
--- a/target/arm/helper.c
197
+++ b/target/arm/helper.c
198
@@ -XXX,XX +XXX,XX @@ DO_VFP_cmp(d, float64)
199
200
/* Integer to float and float to integer conversions */
201
202
-#define CONV_ITOF(name, fsz, sign) \
203
- float##fsz HELPER(name)(uint32_t x, void *fpstp) \
204
-{ \
205
- float_status *fpst = fpstp; \
206
- return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
207
+#define CONV_ITOF(name, ftype, fsz, sign) \
208
+ftype HELPER(name)(uint32_t x, void *fpstp) \
209
+{ \
210
+ float_status *fpst = fpstp; \
211
+ return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
212
}
213
214
-#define CONV_FTOI(name, fsz, sign, round) \
215
-uint32_t HELPER(name)(float##fsz x, void *fpstp) \
216
-{ \
217
- float_status *fpst = fpstp; \
218
- if (float##fsz##_is_any_nan(x)) { \
219
- float_raise(float_flag_invalid, fpst); \
220
- return 0; \
221
- } \
222
- return float##fsz##_to_##sign##int32##round(x, fpst); \
223
+#define CONV_FTOI(name, ftype, fsz, sign, round) \
224
+uint32_t HELPER(name)(ftype x, void *fpstp) \
225
+{ \
226
+ float_status *fpst = fpstp; \
227
+ if (float##fsz##_is_any_nan(x)) { \
228
+ float_raise(float_flag_invalid, fpst); \
229
+ return 0; \
230
+ } \
231
+ return float##fsz##_to_##sign##int32##round(x, fpst); \
232
}
233
234
-#define FLOAT_CONVS(name, p, fsz, sign) \
235
-CONV_ITOF(vfp_##name##to##p, fsz, sign) \
236
-CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
237
-CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
238
+#define FLOAT_CONVS(name, p, ftype, fsz, sign) \
239
+ CONV_ITOF(vfp_##name##to##p, ftype, fsz, sign) \
240
+ CONV_FTOI(vfp_to##name##p, ftype, fsz, sign, ) \
241
+ CONV_FTOI(vfp_to##name##z##p, ftype, fsz, sign, _round_to_zero)
242
243
-FLOAT_CONVS(si, h, 16, )
244
-FLOAT_CONVS(si, s, 32, )
245
-FLOAT_CONVS(si, d, 64, )
246
-FLOAT_CONVS(ui, h, 16, u)
247
-FLOAT_CONVS(ui, s, 32, u)
248
-FLOAT_CONVS(ui, d, 64, u)
249
+FLOAT_CONVS(si, h, uint32_t, 16, )
250
+FLOAT_CONVS(si, s, float32, 32, )
251
+FLOAT_CONVS(si, d, float64, 64, )
252
+FLOAT_CONVS(ui, h, uint32_t, 16, u)
253
+FLOAT_CONVS(ui, s, float32, 32, u)
254
+FLOAT_CONVS(ui, d, float64, 64, u)
255
256
#undef CONV_ITOF
257
#undef CONV_FTOI
258
@@ -XXX,XX +XXX,XX @@ static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
259
return float64_to_float16(float64_scalbn(f, -shift, fpst), true, fpst);
260
}
261
262
-float16 HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
263
+uint32_t HELPER(vfp_sltoh)(uint32_t x, uint32_t shift, void *fpst)
264
{
265
return do_postscale_fp16(int32_to_float64(x, fpst), shift, fpst);
266
}
267
268
-float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
269
+uint32_t HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
270
{
271
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
272
}
273
274
-float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
275
+uint32_t HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
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)
286
}
53
}
287
}
54
}
288
55
289
-uint32_t HELPER(vfp_toshh)(float16 x, uint32_t shift, void *fpst)
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
290
+uint32_t HELPER(vfp_toshh)(uint32_t x, uint32_t shift, void *fpst)
57
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
59
+
60
+ if (aspeed_wdt_is_enabled(s)) {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
62
+ }
63
+}
64
+
65
+
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
67
unsigned size)
291
{
68
{
292
return float64_to_int16(do_prescale_fp16(x, shift, fpst), fpst);
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
70
case WDT_RESTART:
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
74
+ awc->wdt_reload(s);
75
}
76
break;
77
case WDT_CTRL:
78
if (enable && !aspeed_wdt_is_enabled(s)) {
79
s->regs[WDT_CTRL] = data;
80
- aspeed_wdt_reload(s, !(data & WDT_CTRL_1MHZ_CLK));
81
+ awc->wdt_reload(s);
82
} else if (!enable && aspeed_wdt_is_enabled(s)) {
83
s->regs[WDT_CTRL] = data;
84
timer_del(s->timer);
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
86
awc->offset = 0x20;
87
awc->ext_pulse_width_mask = 0xff;
88
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
89
+ awc->wdt_reload = aspeed_wdt_reload;
293
}
90
}
294
91
295
-uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
92
static const TypeInfo aspeed_2400_wdt_info = {
296
+uint32_t HELPER(vfp_touhh)(uint32_t x, uint32_t shift, void *fpst)
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
297
{
94
awc->ext_pulse_width_mask = 0xfffff;
298
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
95
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
96
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
97
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
299
}
98
}
300
99
301
-uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
100
static const TypeInfo aspeed_2500_wdt_info = {
302
+uint32_t HELPER(vfp_toslh)(uint32_t x, uint32_t shift, void *fpst)
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
303
{
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
304
return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
103
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
104
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
105
+ awc->wdt_reload = aspeed_wdt_reload_1mhz;
305
}
106
}
306
107
307
-uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
108
static const TypeInfo aspeed_2600_wdt_info = {
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);
378
--
109
--
379
2.17.1
110
2.20.1
380
111
381
112
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Cédric Le Goater <clg@kaod.org>
2
add MemTxAttrs as an argument to flatview_translate(); all its
3
callers now have attrs available.
4
2
3
The current model only restores the Segment Register values but leaves
4
the previous CS mapping behind. Introduce a helper setting the
5
register value and mapping the region at the requested address. Use
6
this helper when a Segment register is set and at reset.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-11-clg@kaod.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180521140402.23318-11-peter.maydell@linaro.org
9
---
13
---
10
include/exec/memory.h | 7 ++++---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
11
exec.c | 17 +++++++++--------
15
1 file changed, 21 insertions(+), 11 deletions(-)
12
2 files changed, 13 insertions(+), 11 deletions(-)
13
16
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
19
--- a/hw/ssi/aspeed_smc.c
17
+++ b/include/exec/memory.h
20
+++ b/hw/ssi/aspeed_smc.c
18
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
19
*/
22
return false;
20
MemoryRegion *flatview_translate(FlatView *fv,
23
}
21
hwaddr addr, hwaddr *xlat,
24
22
- hwaddr *len, bool is_write);
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
23
+ hwaddr *len, bool is_write,
26
+ uint64_t regval)
24
+ MemTxAttrs attrs);
27
+{
25
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
26
static inline MemoryRegion *address_space_translate(AddressSpace *as,
29
+ AspeedSegments seg;
27
hwaddr addr, hwaddr *xlat,
30
+
28
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
29
MemTxAttrs attrs)
32
+
33
+ memory_region_transaction_begin();
34
+ memory_region_set_size(&fl->mmio, seg.size);
35
+ memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
36
+ memory_region_set_enabled(&fl->mmio, true);
37
+ memory_region_transaction_commit();
38
+
39
+ s->regs[R_SEG_ADDR0 + cs] = regval;
40
+}
41
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
43
uint64_t new)
30
{
44
{
31
return flatview_translate(address_space_to_flatview(as),
45
- AspeedSMCFlash *fl = &s->flashes[cs];
32
- addr, xlat, len, is_write);
46
AspeedSegments seg;
33
+ addr, xlat, len, is_write, attrs);
47
48
s->ctrl->reg_to_segment(s, new, &seg);
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
aspeed_smc_flash_overlap(s, &seg, cs);
51
52
/* All should be fine now to move the region */
53
- memory_region_transaction_begin();
54
- memory_region_set_size(&fl->mmio, seg.size);
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
56
- memory_region_set_enabled(&fl->mmio, true);
57
- memory_region_transaction_commit();
58
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
34
}
61
}
35
62
36
/* address_space_access_valid: check for validity of accessing an address
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
37
@@ -XXX,XX +XXX,XX @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
38
rcu_read_lock();
65
qemu_set_irq(s->cs_lines[i], true);
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);
66
}
66
}
67
67
68
return result;
68
- /* setup default segment register values for all */
69
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
69
+ /* setup the default segment register values and regions for all */
70
MemTxResult result = MEMTX_OK;
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
71
71
- s->regs[R_SEG_ADDR0 + i] =
72
l = len;
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
73
- mr = flatview_translate(fv, addr, &addr1, &l, true);
73
+ aspeed_smc_flash_set_segment_region(s, i,
74
+ mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
75
result = flatview_write_continue(fv, addr, attrs, buf, len,
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);
84
}
75
}
85
76
86
return result;
77
/* HW strapping flash type for the AST2600 controllers */
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)) {
123
--
78
--
124
2.17.1
79
2.20.1
125
80
126
81
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Cédric Le Goater <clg@kaod.org>
2
add MemTxAttrs as an argument to flatview_do_translate().
3
2
3
The segments can be disabled on the AST2600 (zero register value).
4
CS0 is open by default but not the other CS. This is closing the
5
access to the flash device in user mode and forbids scanning.
6
7
In the model, check the segment size and disable the associated region
8
when the value is zero.
9
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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
8
---
16
---
9
exec.c | 9 ++++++---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
10
1 file changed, 6 insertions(+), 3 deletions(-)
18
1 file changed, 11 insertions(+), 5 deletions(-)
11
19
12
diff --git a/exec.c b/exec.c
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
13
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
22
--- a/hw/ssi/aspeed_smc.c
15
+++ b/exec.c
23
+++ b/hw/ssi/aspeed_smc.c
16
@@ -XXX,XX +XXX,XX @@ unassigned:
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
17
* @is_write: whether the translation operation is for write
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
18
* @is_mmio: whether this can be MMIO, set true if it can
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
19
* @target_as: the address space targeted by the IOMMU
27
20
+ * @attrs: memory transaction attributes
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
21
*
29
- seg->size = end_offset + MiB - start_offset;
22
* This function is called from RCU critical section
30
+ if (reg) {
23
*/
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
32
+ seg->size = end_offset + MiB - start_offset;
25
hwaddr *page_mask_out,
33
+ } else {
26
bool is_write,
34
+ seg->addr = s->ctrl->flash_window_base;
27
bool is_mmio,
35
+ seg->size = 0;
28
- AddressSpace **target_as)
36
+ }
29
+ AddressSpace **target_as,
37
}
30
+ MemTxAttrs attrs)
38
31
{
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
32
MemoryRegionSection *section;
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
33
IOMMUMemoryRegion *iommu_mr;
41
memory_region_transaction_begin();
34
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
42
memory_region_set_size(&fl->mmio, seg.size);
35
* but page mask.
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
36
*/
44
- memory_region_set_enabled(&fl->mmio, true);
37
section = flatview_do_translate(address_space_to_flatview(as), addr, &xlat,
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
38
- NULL, &page_mask, is_write, false, &as);
46
memory_region_transaction_commit();
39
+ NULL, &page_mask, is_write, false, &as,
47
40
+ attrs);
48
s->regs[R_SEG_ADDR0 + cs] = regval;
41
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
42
/* Illegal translation */
50
}
43
if (section.mr == &io_mem_unassigned) {
51
44
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv, hwaddr addr, hwaddr *xlat,
52
/* Keep the segment in the overall flash window */
45
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
46
/* This can be MMIO, so setup MMIO bit. */
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
47
section = flatview_do_translate(fv, addr, xlat, plen, NULL,
55
+ if (seg.size &&
48
- is_write, true, &as);
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
49
+ is_write, true, &as, attrs);
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
50
mr = section.mr;
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
51
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
52
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
53
--
61
--
54
2.17.1
62
2.20.1
55
63
56
64
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Cédric Le Goater <clg@kaod.org>
2
add MemTxAttrs as an argument to address_space_get_iotlb_entry().
3
2
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
4
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Joel Stanley <joel@jms.id.au>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20191119141211.25716-13-clg@kaod.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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-12-peter.maydell@linaro.org
8
---
10
---
9
include/exec/memory.h | 2 +-
11
include/hw/ssi/aspeed_smc.h | 1 +
10
exec.c | 2 +-
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
11
hw/virtio/vhost.c | 3 ++-
13
2 files changed, 15 insertions(+), 3 deletions(-)
12
3 files changed, 4 insertions(+), 3 deletions(-)
13
14
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
17
--- a/include/hw/ssi/aspeed_smc.h
17
+++ b/include/exec/memory.h
18
+++ b/include/hw/ssi/aspeed_smc.h
18
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache);
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
19
* entry. Should be called from an RCU critical section.
20
uint8_t r_ce_ctrl;
20
*/
21
uint8_t r_ctrl0;
21
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
22
uint8_t r_timings;
22
- bool is_write);
23
+ uint8_t nregs_timings;
23
+ bool is_write, MemTxAttrs attrs);
24
uint8_t conf_enable_w0;
24
25
uint8_t max_slaves;
25
/* address_space_translate: translate an address range into an address space
26
const AspeedSegments *segments;
26
* into a MemoryRegion and an address range into that section. Should be
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
27
diff --git a/exec.c b/exec.c
28
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
29
--- a/exec.c
29
--- a/hw/ssi/aspeed_smc.c
30
+++ b/exec.c
30
+++ b/hw/ssi/aspeed_smc.c
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
31
@@ -XXX,XX +XXX,XX @@
32
32
/* Checksum Calculation Result */
33
/* Called from RCU critical section */
33
#define R_DMA_CHECKSUM (0x90 / 4)
34
IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
34
35
- bool is_write)
35
-/* Misc Control Register #2 */
36
+ bool is_write, MemTxAttrs attrs)
36
+/* Read Timing Compensation Register */
37
{
37
#define R_TIMINGS (0x94 / 4)
38
MemoryRegionSection section;
38
39
hwaddr xlat, page_mask;
39
/* SPI controller registers and bits (AST2400) */
40
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
41
index XXXXXXX..XXXXXXX 100644
41
.r_ce_ctrl = R_CE_CTRL,
42
--- a/hw/virtio/vhost.c
42
.r_ctrl0 = R_CTRL0,
43
+++ b/hw/virtio/vhost.c
43
.r_timings = R_TIMINGS,
44
@@ -XXX,XX +XXX,XX @@ int vhost_device_iotlb_miss(struct vhost_dev *dev, uint64_t iova, int write)
44
+ .nregs_timings = 1,
45
trace_vhost_iotlb_miss(dev, 1);
45
.conf_enable_w0 = CONF_ENABLE_W0,
46
46
.max_slaves = 5,
47
iotlb = address_space_get_iotlb_entry(dev->vdev->dma_as,
47
.segments = aspeed_segments_legacy,
48
- iova, write);
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
49
+ iova, write,
49
.r_ce_ctrl = R_CE_CTRL,
50
+ MEMTXATTRS_UNSPECIFIED);
50
.r_ctrl0 = R_CTRL0,
51
if (iotlb.target_as != NULL) {
51
.r_timings = R_TIMINGS,
52
ret = vhost_memory_region_lookup(dev, iotlb.translated_addr,
52
+ .nregs_timings = 1,
53
&uaddr, &len);
53
.conf_enable_w0 = CONF_ENABLE_W0,
54
.max_slaves = 5,
55
.segments = aspeed_segments_fmc,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
57
.r_ce_ctrl = 0xff,
58
.r_ctrl0 = R_SPI_CTRL0,
59
.r_timings = R_SPI_TIMINGS,
60
+ .nregs_timings = 1,
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
62
.max_slaves = 1,
63
.segments = aspeed_segments_spi,
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
65
.r_ce_ctrl = R_CE_CTRL,
66
.r_ctrl0 = R_CTRL0,
67
.r_timings = R_TIMINGS,
68
+ .nregs_timings = 1,
69
.conf_enable_w0 = CONF_ENABLE_W0,
70
.max_slaves = 3,
71
.segments = aspeed_segments_ast2500_fmc,
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
73
.r_ce_ctrl = R_CE_CTRL,
74
.r_ctrl0 = R_CTRL0,
75
.r_timings = R_TIMINGS,
76
+ .nregs_timings = 1,
77
.conf_enable_w0 = CONF_ENABLE_W0,
78
.max_slaves = 2,
79
.segments = aspeed_segments_ast2500_spi1,
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
81
.r_ce_ctrl = R_CE_CTRL,
82
.r_ctrl0 = R_CTRL0,
83
.r_timings = R_TIMINGS,
84
+ .nregs_timings = 1,
85
.conf_enable_w0 = CONF_ENABLE_W0,
86
.max_slaves = 2,
87
.segments = aspeed_segments_ast2500_spi2,
88
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
89
.r_ce_ctrl = R_CE_CTRL,
90
.r_ctrl0 = R_CTRL0,
91
.r_timings = R_TIMINGS,
92
+ .nregs_timings = 1,
93
.conf_enable_w0 = CONF_ENABLE_W0,
94
.max_slaves = 3,
95
.segments = aspeed_segments_ast2600_fmc,
96
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
97
.r_ce_ctrl = R_CE_CTRL,
98
.r_ctrl0 = R_CTRL0,
99
.r_timings = R_TIMINGS,
100
+ .nregs_timings = 2,
101
.conf_enable_w0 = CONF_ENABLE_W0,
102
.max_slaves = 2,
103
.segments = aspeed_segments_ast2600_spi1,
104
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
105
.r_ce_ctrl = R_CE_CTRL,
106
.r_ctrl0 = R_CTRL0,
107
.r_timings = R_TIMINGS,
108
+ .nregs_timings = 3,
109
.conf_enable_w0 = CONF_ENABLE_W0,
110
.max_slaves = 3,
111
.segments = aspeed_segments_ast2600_spi2,
112
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
113
addr >>= 2;
114
115
if (addr == s->r_conf ||
116
- addr == s->r_timings ||
117
+ (addr >= s->r_timings &&
118
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
119
addr == s->r_ce_ctrl ||
120
addr == R_INTR_CTRL ||
121
addr == R_DUMMY_DATA ||
122
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
123
addr >>= 2;
124
125
if (addr == s->r_conf ||
126
- addr == s->r_timings ||
127
+ (addr >= s->r_timings &&
128
+ addr < s->r_timings + s->ctrl->nregs_timings) ||
129
addr == s->r_ce_ctrl) {
130
s->regs[addr] = value;
131
} else if (addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->num_cs) {
54
--
132
--
55
2.17.1
133
2.20.1
56
134
57
135
diff view generated by jsdifflib
New patch
1
1
From: Cédric Le Goater <clg@kaod.org>
2
3
AspeedBoardConfig is a redundant way to define class attributes and it
4
complexifies the machine definition and initialization.
5
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Joel Stanley <joel@jms.id.au>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20191119141211.25716-14-clg@kaod.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/aspeed.h | 24 ++--
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
14
2 files changed, 143 insertions(+), 124 deletions(-)
15
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
19
+++ b/include/hw/arm/aspeed.h
20
@@ -XXX,XX +XXX,XX @@
21
22
typedef struct AspeedBoardState AspeedBoardState;
23
24
-typedef struct AspeedBoardConfig {
25
- const char *name;
26
- const char *desc;
27
- const char *soc_name;
28
- uint32_t hw_strap1;
29
- uint32_t hw_strap2;
30
- const char *fmc_model;
31
- const char *spi_model;
32
- uint32_t num_cs;
33
- void (*i2c_init)(AspeedBoardState *bmc);
34
- uint32_t ram;
35
-} AspeedBoardConfig;
36
-
37
#define TYPE_ASPEED_MACHINE MACHINE_TYPE_NAME("aspeed")
38
#define ASPEED_MACHINE(obj) \
39
OBJECT_CHECK(AspeedMachine, (obj), TYPE_ASPEED_MACHINE)
40
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedMachine {
41
42
typedef struct AspeedMachineClass {
43
MachineClass parent_obj;
44
- const AspeedBoardConfig *board;
45
+
46
+ const char *name;
47
+ const char *desc;
48
+ const char *soc_name;
49
+ uint32_t hw_strap1;
50
+ uint32_t hw_strap2;
51
+ const char *fmc_model;
52
+ const char *spi_model;
53
+ uint32_t num_cs;
54
+ void (*i2c_init)(AspeedBoardState *bmc);
55
} AspeedMachineClass;
56
57
58
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/aspeed.c
61
+++ b/hw/arm/aspeed.c
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
63
}
64
}
65
66
-static void aspeed_board_init(MachineState *machine,
67
- const AspeedBoardConfig *cfg)
68
+static void aspeed_machine_init(MachineState *machine)
69
{
70
AspeedBoardState *bmc;
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
72
AspeedSoCClass *sc;
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
74
ram_addr_t max_ram_size;
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
76
UINT32_MAX);
77
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
81
NULL);
82
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
84
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
86
&error_abort);
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
89
&error_abort);
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
92
&error_abort);
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
95
&error_abort);
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
97
&error_abort);
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
99
"max_ram", max_ram_size - ram_size);
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
101
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
106
107
/* Install first FMC flash content as a boot rom. */
108
if (drive0) {
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
112
113
- if (cfg->i2c_init) {
114
- cfg->i2c_init(bmc);
115
+ if (amc->i2c_init) {
116
+ amc->i2c_init(bmc);
117
}
118
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
121
0x60);
122
}
123
124
-static void aspeed_machine_init(MachineState *machine)
125
-{
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
127
-
128
- aspeed_board_init(machine, amc->board);
129
-}
130
-
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
132
{
133
MachineClass *mc = MACHINE_CLASS(oc);
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
135
- const AspeedBoardConfig *board = data;
136
137
- mc->desc = board->desc;
138
mc->init = aspeed_machine_init;
139
mc->max_cpus = ASPEED_CPUS_NUM;
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->no_parallel = 1;
143
- if (board->ram) {
144
- mc->default_ram_size = board->ram;
145
- }
146
- amc->board = board;
147
}
148
149
-static const TypeInfo aspeed_machine_type = {
150
- .name = TYPE_ASPEED_MACHINE,
151
- .parent = TYPE_MACHINE,
152
- .instance_size = sizeof(AspeedMachine),
153
- .class_size = sizeof(AspeedMachineClass),
154
- .abstract = true,
155
-};
156
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
158
- {
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
161
- .soc_name = "ast2400-a1",
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
163
- .fmc_model = "n25q256a",
164
- .spi_model = "mx25l25635e",
165
- .num_cs = 1,
166
- .i2c_init = palmetto_bmc_i2c_init,
167
- .ram = 256 * MiB,
168
- }, {
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
171
- .soc_name = "ast2500-a1",
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
173
- .fmc_model = "w25q256",
174
- .spi_model = "mx25l25635e",
175
- .num_cs = 1,
176
- .i2c_init = ast2500_evb_i2c_init,
177
- .ram = 512 * MiB,
178
- }, {
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
181
- .soc_name = "ast2500-a1",
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
183
- .fmc_model = "n25q256a",
184
- .spi_model = "mx66l1g45g",
185
- .num_cs = 2,
186
- .i2c_init = romulus_bmc_i2c_init,
187
- .ram = 512 * MiB,
188
- }, {
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
191
- .soc_name = "ast2500-a1",
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
193
- .fmc_model = "mx66l1g45g",
194
- .spi_model = "mx66l1g45g",
195
- .num_cs = 2,
196
- .i2c_init = swift_bmc_i2c_init,
197
- .ram = 512 * MiB,
198
- }, {
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
201
- .soc_name = "ast2500-a1",
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
203
- .fmc_model = "mx25l25635e",
204
- .spi_model = "mx66l1g45g",
205
- .num_cs = 2,
206
- .i2c_init = witherspoon_bmc_i2c_init,
207
- .ram = 512 * MiB,
208
- }, {
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
211
- .soc_name = "ast2600-a0",
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
214
- .fmc_model = "w25q512jv",
215
- .spi_model = "mx66u51235f",
216
- .num_cs = 1,
217
- .i2c_init = ast2600_evb_i2c_init,
218
- .ram = 1 * GiB,
219
- },
220
-};
221
-
222
-static void aspeed_machine_types(void)
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
224
{
225
- int i;
226
+ MachineClass *mc = MACHINE_CLASS(oc);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
228
229
- type_register_static(&aspeed_machine_type);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
231
- TypeInfo ti = {
232
- .name = aspeed_boards[i].name,
233
- .parent = TYPE_ASPEED_MACHINE,
234
- .class_init = aspeed_machine_class_init,
235
- .class_data = (void *)&aspeed_boards[i],
236
- };
237
- type_register(&ti);
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
239
+ amc->soc_name = "ast2400-a1";
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
241
+ amc->fmc_model = "n25q256a";
242
+ amc->spi_model = "mx25l25635e";
243
+ amc->num_cs = 1;
244
+ amc->i2c_init = palmetto_bmc_i2c_init;
245
+ mc->default_ram_size = 256 * MiB;
246
+};
247
+
248
+static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data)
249
+{
250
+ MachineClass *mc = MACHINE_CLASS(oc);
251
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
252
+
253
+ mc->desc = "Aspeed AST2500 EVB (ARM1176)";
254
+ amc->soc_name = "ast2500-a1";
255
+ amc->hw_strap1 = AST2500_EVB_HW_STRAP1;
256
+ amc->fmc_model = "w25q256";
257
+ amc->spi_model = "mx25l25635e";
258
+ amc->num_cs = 1;
259
+ amc->i2c_init = ast2500_evb_i2c_init;
260
+ mc->default_ram_size = 512 * MiB;
261
+};
262
+
263
+static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data)
264
+{
265
+ MachineClass *mc = MACHINE_CLASS(oc);
266
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
+
268
+ mc->desc = "OpenPOWER Romulus BMC (ARM1176)";
269
+ amc->soc_name = "ast2500-a1";
270
+ amc->hw_strap1 = ROMULUS_BMC_HW_STRAP1;
271
+ amc->fmc_model = "n25q256a";
272
+ amc->spi_model = "mx66l1g45g";
273
+ amc->num_cs = 2;
274
+ amc->i2c_init = romulus_bmc_i2c_init;
275
+ mc->default_ram_size = 512 * MiB;
276
+};
277
+
278
+static void aspeed_machine_swift_class_init(ObjectClass *oc, void *data)
279
+{
280
+ MachineClass *mc = MACHINE_CLASS(oc);
281
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
282
+
283
+ mc->desc = "OpenPOWER Swift BMC (ARM1176)";
284
+ amc->soc_name = "ast2500-a1";
285
+ amc->hw_strap1 = SWIFT_BMC_HW_STRAP1;
286
+ amc->fmc_model = "mx66l1g45g";
287
+ amc->spi_model = "mx66l1g45g";
288
+ amc->num_cs = 2;
289
+ amc->i2c_init = swift_bmc_i2c_init;
290
+ mc->default_ram_size = 512 * MiB;
291
+};
292
+
293
+static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data)
294
+{
295
+ MachineClass *mc = MACHINE_CLASS(oc);
296
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
297
+
298
+ mc->desc = "OpenPOWER Witherspoon BMC (ARM1176)";
299
+ amc->soc_name = "ast2500-a1";
300
+ amc->hw_strap1 = WITHERSPOON_BMC_HW_STRAP1;
301
+ amc->fmc_model = "mx25l25635e";
302
+ amc->spi_model = "mx66l1g45g";
303
+ amc->num_cs = 2;
304
+ amc->i2c_init = witherspoon_bmc_i2c_init;
305
+ mc->default_ram_size = 512 * MiB;
306
+};
307
+
308
+static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
309
+{
310
+ MachineClass *mc = MACHINE_CLASS(oc);
311
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
312
+
313
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
314
+ amc->soc_name = "ast2600-a0";
315
+ amc->hw_strap1 = AST2600_EVB_HW_STRAP1;
316
+ amc->hw_strap2 = AST2600_EVB_HW_STRAP2;
317
+ amc->fmc_model = "w25q512jv";
318
+ amc->spi_model = "mx66u51235f";
319
+ amc->num_cs = 1;
320
+ amc->i2c_init = ast2600_evb_i2c_init;
321
+ mc->default_ram_size = 1 * GiB;
322
+};
323
+
324
+static const TypeInfo aspeed_machine_types[] = {
325
+ {
326
+ .name = MACHINE_TYPE_NAME("palmetto-bmc"),
327
+ .parent = TYPE_ASPEED_MACHINE,
328
+ .class_init = aspeed_machine_palmetto_class_init,
329
+ }, {
330
+ .name = MACHINE_TYPE_NAME("ast2500-evb"),
331
+ .parent = TYPE_ASPEED_MACHINE,
332
+ .class_init = aspeed_machine_ast2500_evb_class_init,
333
+ }, {
334
+ .name = MACHINE_TYPE_NAME("romulus-bmc"),
335
+ .parent = TYPE_ASPEED_MACHINE,
336
+ .class_init = aspeed_machine_romulus_class_init,
337
+ }, {
338
+ .name = MACHINE_TYPE_NAME("swift-bmc"),
339
+ .parent = TYPE_ASPEED_MACHINE,
340
+ .class_init = aspeed_machine_swift_class_init,
341
+ }, {
342
+ .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
343
+ .parent = TYPE_ASPEED_MACHINE,
344
+ .class_init = aspeed_machine_witherspoon_class_init,
345
+ }, {
346
+ .name = MACHINE_TYPE_NAME("ast2600-evb"),
347
+ .parent = TYPE_ASPEED_MACHINE,
348
+ .class_init = aspeed_machine_ast2600_evb_class_init,
349
+ }, {
350
+ .name = TYPE_ASPEED_MACHINE,
351
+ .parent = TYPE_MACHINE,
352
+ .instance_size = sizeof(AspeedMachine),
353
+ .class_size = sizeof(AspeedMachineClass),
354
+ .class_init = aspeed_machine_class_init,
355
+ .abstract = true,
356
}
357
-}
358
+};
359
360
-type_init(aspeed_machine_types)
361
+DEFINE_TYPES(aspeed_machine_types)
362
--
363
2.20.1
364
365
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Cédric Le Goater <clg@kaod.org>
2
add MemTxAttrs as an argument to address_space_translate_iommu().
3
2
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
4
Witherspoon system. It uses a AST2600 SoC instead of a AST2500 and the
5
I2C layout is the same as it controls the same main board. Used for HW
6
bringup.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20191119141211.25716-15-clg@kaod.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
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-14-peter.maydell@linaro.org
8
---
13
---
9
exec.c | 8 +++++---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
10
1 file changed, 5 insertions(+), 3 deletions(-)
15
1 file changed, 28 insertions(+)
11
16
12
diff --git a/exec.c b/exec.c
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/exec.c
19
--- a/hw/arm/aspeed.c
15
+++ b/exec.c
20
+++ b/hw/arm/aspeed.c
16
@@ -XXX,XX +XXX,XX @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
17
* @is_write: whether the translation operation is for write
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
18
* @is_mmio: whether this can be MMIO, set true if it can
23
#define AST2600_EVB_HW_STRAP2 0x00000003
19
* @target_as: the address space targeted by the IOMMU
24
20
+ * @attrs: transaction attributes
25
+/* Tacoma hardware value */
21
*
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
22
* This function is called from RCU critical section. It is the common
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
23
* part of flatview_do_translate and address_space_translate_cached.
28
+
24
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection address_space_translate_iommu(IOMMUMemoryRegion *iomm
29
/*
25
hwaddr *page_mask_out,
30
* The max ram region is for firmwares that scan the address space
26
bool is_write,
31
* with load/store to guess how much RAM the SoC has.
27
bool is_mmio,
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
28
- AddressSpace **target_as)
33
AspeedSoCState *soc = &bmc->soc;
29
+ AddressSpace **target_as,
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
30
+ MemTxAttrs attrs)
35
31
{
36
+ /* Bus 3: TODO bmp280@77 */
32
MemoryRegionSection *section;
37
+ /* Bus 3: TODO max31785@52 */
33
hwaddr page_mask = (hwaddr)-1;
38
+ /* Bus 3: TODO dps310@76 */
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegionSection flatview_do_translate(FlatView *fv,
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
35
return address_space_translate_iommu(iommu_mr, xlat,
40
0x60);
36
plen_out, page_mask_out,
41
37
is_write, is_mmio,
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
38
- target_as);
43
eeprom_buf);
39
+ target_as, attrs);
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
40
}
45
0x60);
41
if (page_mask_out) {
46
+ /* Bus 11: TODO ucd90160@64 */
42
/* Not behind an IOMMU, use default page size. */
43
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate_cached(
44
45
section = address_space_translate_iommu(iommu_mr, xlat, plen,
46
NULL, is_write, true,
47
- &target_as);
48
+ &target_as, attrs);
49
return section.mr;
50
}
47
}
51
48
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
50
@@ -XXX,XX +XXX,XX @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data)
51
mc->default_ram_size = 1 * GiB;
52
};
53
54
+static void aspeed_machine_tacoma_class_init(ObjectClass *oc, void *data)
55
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
58
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
60
+ amc->soc_name = "ast2600-a0";
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
63
+ amc->fmc_model = "mx66l1g45g";
64
+ amc->spi_model = "mx66l1g45g";
65
+ amc->num_cs = 2;
66
+ amc->i2c_init = witherspoon_bmc_i2c_init; /* Same board layout */
67
+ mc->default_ram_size = 1 * GiB;
68
+};
69
+
70
static const TypeInfo aspeed_machine_types[] = {
71
{
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
75
.parent = TYPE_ASPEED_MACHINE,
76
.class_init = aspeed_machine_ast2600_evb_class_init,
77
+ }, {
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
79
+ .parent = TYPE_ASPEED_MACHINE,
80
+ .class_init = aspeed_machine_tacoma_class_init,
81
}, {
82
.name = TYPE_ASPEED_MACHINE,
83
.parent = TYPE_MACHINE,
52
--
84
--
53
2.17.1
85
2.20.1
54
86
55
87
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: PanNengyuan <pannengyuan@huawei.com>
2
2
3
It forgot to increase clroffset during the loop. So it only clear the
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
4
first 4 bytes.
5
4
6
Fixes: 367b9f527becdd20ddf116e17a3c0c2bbc486920
5
Reported-by: Euler Robot <euler.robot@huawei.com>
7
Cc: qemu-stable@nongnu.org
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
8
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 1527047633-12368-1-git-send-email-zhaoshenglong@huawei.com
9
Message-id: 20191119141211.25716-16-clg@kaod.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/intc/arm_gicv3_kvm.c | 1 +
12
hw/gpio/aspeed_gpio.c | 1 +
15
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+)
16
14
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
17
--- a/hw/gpio/aspeed_gpio.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
18
+++ b/hw/gpio/aspeed_gpio.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
22
if (clroffset != 0) {
20
pin_idx % GPIOS_PER_GROUP);
23
reg = 0;
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
24
kvm_gicd_access(s, clroffset, &reg, true);
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
25
+ clroffset += 4;
23
+ g_free(name);
26
}
24
}
27
reg = *gic_bmp_ptr32(bmp, irq);
25
}
28
kvm_gicd_access(s, offset, &reg, true);
26
29
--
27
--
30
2.17.1
28
2.20.1
31
29
32
30
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Cédric Le Goater <clg@kaod.org>
2
add MemTxAttrs as an argument to address_space_map().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
4
controller model of the machine.
5
6
Change the "scu" property definition so that it explicitly sets the
7
pointer. The property isn't optional : not being able to set the link
8
is a bug and QEMU should rather abort than exit in this case.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Greg Kurz <groug@kaod.org>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-17-clg@kaod.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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-5-peter.maydell@linaro.org
10
---
16
---
11
include/exec/memory.h | 3 ++-
17
hw/arm/aspeed_ast2600.c | 8 ++++----
12
include/sysemu/dma.h | 3 ++-
18
hw/arm/aspeed_soc.c | 8 ++++----
13
exec.c | 6 ++++--
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
14
target/ppc/mmu-hash64.c | 3 ++-
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
15
4 files changed, 10 insertions(+), 5 deletions(-)
21
4 files changed, 25 insertions(+), 25 deletions(-)
16
22
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/memory.h
25
--- a/hw/arm/aspeed_ast2600.c
20
+++ b/include/exec/memory.h
26
+++ b/hw/arm/aspeed_ast2600.c
21
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
22
* @addr: address within that address space
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
23
* @plen: pointer to length of buffer; updated on return
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
24
* @is_write: indicates the transfer direction
30
sizeof(s->timerctrl), typename);
25
+ * @attrs: memory attributes
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
26
*/
32
- OBJECT(&s->scu), &error_abort);
27
void *address_space_map(AddressSpace *as, hwaddr addr,
33
28
- hwaddr *plen, bool is_write);
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
29
+ hwaddr *plen, bool is_write, MemTxAttrs attrs);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
30
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
31
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
32
*
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
33
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
43
44
for (i = 0; i < sc->macs_num; i++) {
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
46
aspeed_soc_get_irq(s, ASPEED_RTC));
47
48
/* Timer */
49
+ object_property_set_link(OBJECT(&s->timerctrl),
50
+ OBJECT(&s->scu), "scu", &error_abort);
51
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
52
if (err) {
53
error_propagate(errp, err);
54
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
55
for (i = 0; i < sc->wdts_num; i++) {
56
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
57
58
+ object_property_set_link(OBJECT(&s->wdt[i]),
59
+ OBJECT(&s->scu), "scu", &error_abort);
60
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
61
if (err) {
62
error_propagate(errp, err);
63
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
34
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
35
--- a/include/sysemu/dma.h
65
--- a/hw/arm/aspeed_soc.c
36
+++ b/include/sysemu/dma.h
66
+++ b/hw/arm/aspeed_soc.c
37
@@ -XXX,XX +XXX,XX @@ static inline void *dma_memory_map(AddressSpace *as,
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
38
hwaddr xlen = *len;
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
39
void *p;
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
40
70
sizeof(s->timerctrl), typename);
41
- p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
42
+ p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE,
72
- OBJECT(&s->scu), &error_abort);
43
+ MEMTXATTRS_UNSPECIFIED);
73
44
*len = xlen;
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
45
return p;
75
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
78
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
79
sizeof(s->wdt[i]), typename);
80
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
81
- OBJECT(&s->scu), &error_abort);
82
}
83
84
for (i = 0; i < sc->macs_num; i++) {
85
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
aspeed_soc_get_irq(s, ASPEED_RTC));
87
88
/* Timer */
89
+ object_property_set_link(OBJECT(&s->timerctrl),
90
+ OBJECT(&s->scu), "scu", &error_abort);
91
object_property_set_bool(OBJECT(&s->timerctrl), true, "realized", &err);
92
if (err) {
93
error_propagate(errp, err);
94
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
95
for (i = 0; i < sc->wdts_num; i++) {
96
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(&s->wdt[i]);
97
98
+ object_property_set_link(OBJECT(&s->wdt[i]),
99
+ OBJECT(&s->scu), "scu", &error_abort);
100
object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
101
if (err) {
102
error_propagate(errp, err);
103
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/timer/aspeed_timer.c
106
+++ b/hw/timer/aspeed_timer.c
107
@@ -XXX,XX +XXX,XX @@
108
#include "qemu/timer.h"
109
#include "qemu/log.h"
110
#include "qemu/module.h"
111
+#include "hw/qdev-properties.h"
112
#include "trace.h"
113
114
#define TIMER_NR_REGS 4
115
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_realize(DeviceState *dev, Error **errp)
116
int i;
117
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
118
AspeedTimerCtrlState *s = ASPEED_TIMER(dev);
119
- Object *obj;
120
- Error *err = NULL;
121
122
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
123
- if (!obj) {
124
- error_propagate_prepend(errp, err, "required link 'scu' not found: ");
125
- return;
126
- }
127
- s->scu = ASPEED_SCU(obj);
128
+ assert(s->scu);
129
130
for (i = 0; i < ASPEED_TIMER_NR_TIMERS; i++) {
131
aspeed_init_one_timer(s, i);
132
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_timer_state = {
133
}
134
};
135
136
+static Property aspeed_timer_properties[] = {
137
+ DEFINE_PROP_LINK("scu", AspeedTimerCtrlState, scu, TYPE_ASPEED_SCU,
138
+ AspeedSCUState *),
139
+ DEFINE_PROP_END_OF_LIST(),
140
+};
141
+
142
static void timer_class_init(ObjectClass *klass, void *data)
143
{
144
DeviceClass *dc = DEVICE_CLASS(klass);
145
@@ -XXX,XX +XXX,XX @@ static void timer_class_init(ObjectClass *klass, void *data)
146
dc->reset = aspeed_timer_reset;
147
dc->desc = "ASPEED Timer";
148
dc->vmsd = &vmstate_aspeed_timer_state;
149
+ dc->props = aspeed_timer_properties;
46
}
150
}
47
diff --git a/exec.c b/exec.c
151
152
static const TypeInfo aspeed_timer_info = {
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
48
index XXXXXXX..XXXXXXX 100644
154
index XXXXXXX..XXXXXXX 100644
49
--- a/exec.c
155
--- a/hw/watchdog/wdt_aspeed.c
50
+++ b/exec.c
156
+++ b/hw/watchdog/wdt_aspeed.c
51
@@ -XXX,XX +XXX,XX @@ flatview_extend_translation(FlatView *fv, hwaddr addr,
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
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
{
158
{
59
hwaddr len = *plen;
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
60
hwaddr l, xlat;
160
AspeedWDTState *s = ASPEED_WDT(dev);
61
@@ -XXX,XX +XXX,XX @@ void *cpu_physical_memory_map(hwaddr addr,
161
- Error *err = NULL;
62
hwaddr *plen,
162
- Object *obj;
63
int is_write)
163
164
- obj = object_property_get_link(OBJECT(dev), "scu", &err);
165
- if (!obj) {
166
- error_propagate(errp, err);
167
- error_prepend(errp, "required link 'scu' not found: ");
168
- return;
169
- }
170
- s->scu = ASPEED_SCU(obj);
171
+ assert(s->scu);
172
173
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, aspeed_wdt_timer_expired, dev);
174
175
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
176
sysbus_init_mmio(sbd, &s->iomem);
177
}
178
179
+static Property aspeed_wdt_properties[] = {
180
+ DEFINE_PROP_LINK("scu", AspeedWDTState, scu, TYPE_ASPEED_SCU,
181
+ AspeedSCUState *),
182
+ DEFINE_PROP_END_OF_LIST(),
183
+};
184
+
185
static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
64
{
186
{
65
- return address_space_map(&address_space_memory, addr, plen, is_write);
187
DeviceClass *dc = DEVICE_CLASS(klass);
66
+ return address_space_map(&address_space_memory, addr, plen, is_write,
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
67
+ MEMTXATTRS_UNSPECIFIED);
189
dc->reset = aspeed_wdt_reset;
190
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
191
dc->vmsd = &vmstate_aspeed_wdt;
192
+ dc->props = aspeed_wdt_properties;
68
}
193
}
69
194
70
void cpu_physical_memory_unmap(void *buffer, hwaddr len,
195
static const TypeInfo aspeed_wdt_info = {
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;
77
}
78
79
- hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false);
80
+ hptes = address_space_map(CPU(cpu)->as, base + pte_offset, &plen, false,
81
+ MEMTXATTRS_UNSPECIFIED);
82
if (plen < (n * HASH_PTE_SIZE_64)) {
83
hw_error("%s: Unable to map all requested HPTEs\n", __func__);
84
}
85
--
196
--
86
2.17.1
197
2.20.1
87
198
88
199
diff view generated by jsdifflib
1
From: Igor Mammedov <imammedo@redhat.com>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
When QEMU is started with following CLI
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
4
-machine virt,gic-version=3,accel=kvm -cpu host -bios AAVMF_CODE.fd
4
NIC in the machine.
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
8
5
9
Which is caused by implicit dependency of kvm_arm_gicv3_reset() on
6
Change the "nic" property definition so that it explicitly sets the
10
arm_gicv3_icc_reset() where the later is called by CPU reset
7
pointer. The property isn't optional : not being able to set the link
11
reset callback.
8
is a bug and QEMU should rather abort than exit in this case.
12
9
13
However commit:
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
3b77f6c arm/boot: split load_dtb() from arm_load_kernel()
11
Reviewed-by: Greg Kurz <groug@kaod.org>
15
broke CPU reset callback registration in case
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
16
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
17
arm_load_kernel()
14
Message-id: 20191119141211.25716-18-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>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
---
16
---
43
hw/arm/boot.c | 18 +++++++++---------
17
hw/arm/aspeed_ast2600.c | 5 ++---
44
1 file changed, 9 insertions(+), 9 deletions(-)
18
hw/net/ftgmac100.c | 19 +++++++++----------
19
2 files changed, 11 insertions(+), 13 deletions(-)
45
20
46
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
47
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/boot.c
23
--- a/hw/arm/aspeed_ast2600.c
49
+++ b/hw/arm/boot.c
24
+++ b/hw/arm/aspeed_ast2600.c
50
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
51
static const ARMInsnFixup *primary_loader;
26
52
AddressSpace *as = arm_boot_address_space(cpu, info);
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
53
28
TYPE_ASPEED_MII);
54
+ /* CPU objects (unlike devices) are not automatically reset on system
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
55
+ * reset, so we must always register a handler to do so. If we're
30
- OBJECT(&s->ftgmac100[i]),
56
+ * actually loading a kernel, the handler is also responsible for
31
- &error_abort);
57
+ * arranging that we start it correctly.
58
+ */
59
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
60
+ qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
61
+ }
62
+
63
/* The board code is not supposed to set secure_board_setup unless
64
* running its code in secure mode is actually possible, and KVM
65
* doesn't support secure.
66
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
67
ARM_CPU(cs)->env.boot_info = info;
68
}
32
}
69
33
70
- /* CPU objects (unlike devices) are not automatically reset on system
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
71
- * reset, so we must always register a handler to do so. If we're
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
72
- * actually loading a kernel, the handler is also responsible for
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
73
- * arranging that we start it correctly.
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
74
- */
38
75
- for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
76
- qemu_register_reset(do_cpu_reset, ARM_CPU(cs));
40
+ "nic", &error_abort);
41
object_property_set_bool(OBJECT(&s->mii[i]), true, "realized",
42
&err);
43
if (err) {
44
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/net/ftgmac100.c
47
+++ b/hw/net/ftgmac100.c
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_realize(DeviceState *dev, Error **errp)
49
{
50
AspeedMiiState *s = ASPEED_MII(dev);
51
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
52
- Object *obj;
53
- Error *local_err = NULL;
54
55
- obj = object_property_get_link(OBJECT(dev), "nic", &local_err);
56
- if (!obj) {
57
- error_propagate(errp, local_err);
58
- error_prepend(errp, "required link 'nic' not found: ");
59
- return;
77
- }
60
- }
78
-
61
-
79
if (!info->skip_dtb_autoload && have_dtb(info)) {
62
- s->nic = FTGMAC100(obj);
80
if (arm_load_dtb(info->dtb_start, info, info->dtb_limit, as) < 0) {
63
+ assert(s->nic);
81
exit(1);
64
65
memory_region_init_io(&s->iomem, OBJECT(dev), &aspeed_mii_ops, s,
66
TYPE_ASPEED_MII, 0x8);
67
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_mii = {
68
VMSTATE_END_OF_LIST()
69
}
70
};
71
+
72
+static Property aspeed_mii_properties[] = {
73
+ DEFINE_PROP_LINK("nic", AspeedMiiState, nic, TYPE_FTGMAC100,
74
+ FTGMAC100State *),
75
+ DEFINE_PROP_END_OF_LIST(),
76
+};
77
+
78
static void aspeed_mii_class_init(ObjectClass *klass, void *data)
79
{
80
DeviceClass *dc = DEVICE_CLASS(klass);
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_mii_class_init(ObjectClass *klass, void *data)
82
dc->reset = aspeed_mii_reset;
83
dc->realize = aspeed_mii_realize;
84
dc->desc = "Aspeed MII controller";
85
+ dc->props = aspeed_mii_properties;
86
}
87
88
static const TypeInfo aspeed_mii_info = {
82
--
89
--
83
2.17.1
90
2.20.1
84
91
85
92
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Marc Zyngier <maz@kernel.org>
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.
5
2
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
5
completely ignores it, making it impossible for hypervisors to
6
virtualize the cache hierarchy.
7
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
9
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
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
---
15
---
11
exec.c | 12 +++++-------
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
12
1 file changed, 5 insertions(+), 7 deletions(-)
17
1 file changed, 27 insertions(+), 4 deletions(-)
13
18
14
diff --git a/exec.c b/exec.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
21
--- a/target/arm/helper.c
17
+++ b/exec.c
22
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
19
static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
24
raw_write(env, ri, value);
20
const uint8_t *buf, int len);
21
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
22
- bool is_write);
23
+ bool is_write, MemTxAttrs attrs);
24
25
static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data,
26
unsigned len, MemTxAttrs attrs)
27
@@ -XXX,XX +XXX,XX @@ static bool subpage_accepts(void *opaque, hwaddr addr,
28
#endif
29
30
return flatview_access_valid(subpage->fv, addr + subpage->base,
31
- len, is_write);
32
+ len, is_write, attrs);
33
}
25
}
34
26
35
static const MemoryRegionOps subpage_ops = {
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
36
@@ -XXX,XX +XXX,XX @@ static void cpu_notify_map_clients(void)
28
+ const ARMCPRegInfo *ri,
29
+ bool isread)
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
34
+
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
{
40
ARMCPU *cpu = env_archcpu(env);
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
42
.writefn = pmintenclr_write },
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
46
+ .access = PL1_R,
47
+ .accessfn = access_aa64_tid2,
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
52
+ .access = PL1_RW,
53
+ .accessfn = access_aa64_tid2,
54
+ .writefn = csselr_write, .resetvalue = 0,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
56
offsetof(CPUARMState, cp15.csselr_ns) } },
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
60
return CP_ACCESS_TRAP;
61
}
62
+
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
64
+ return CP_ACCESS_TRAP_EL2;
65
+ }
66
+
67
return CP_ACCESS_OK;
37
}
68
}
38
69
39
static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
40
- bool is_write)
71
ARMCPRegInfo clidr = {
41
+ bool is_write, MemTxAttrs attrs)
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
42
{
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
43
MemoryRegion *mr;
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
44
hwaddr l, xlat;
75
+ .access = PL1_R, .type = ARM_CP_CONST,
45
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
76
+ .accessfn = access_aa64_tid2,
46
mr = flatview_translate(fv, addr, &xlat, &l, is_write);
77
+ .resetvalue = cpu->clidr
47
if (!memory_access_is_direct(mr, is_write)) {
78
};
48
l = memory_access_size(mr, l, addr);
79
define_one_arm_cp_reg(cpu, &clidr);
49
- /* When our callers all have attrs we'll pass them through here */
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
50
- if (!memory_region_access_valid(mr, xlat, l, is_write,
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
51
- MEMTXATTRS_UNSPECIFIED)) {
82
/* These are common to v8 and pre-v8 */
52
+ if (!memory_region_access_valid(mr, xlat, l, is_write, attrs)) {
83
{ .name = "CTR",
53
return false;
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
54
}
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
55
}
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
56
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
57
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
58
rcu_read_lock();
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
59
fv = address_space_to_flatview(as);
90
.access = PL0_R, .accessfn = ctr_el0_access,
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
}
65
--
91
--
66
2.17.1
92
2.20.1
67
93
68
94
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Marc Zyngier <maz@kernel.org>
2
add MemTxAttrs as an argument to flatview_extend_translation().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
6
virtualize the HW (though to be fair, no known hypervisor actually
7
cares).
8
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-3-maz@kernel.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
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-7-peter.maydell@linaro.org
10
---
16
---
11
exec.c | 15 ++++++++++-----
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
12
1 file changed, 10 insertions(+), 5 deletions(-)
18
1 file changed, 32 insertions(+), 4 deletions(-)
13
19
14
diff --git a/exec.c b/exec.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/exec.c
22
--- a/target/arm/helper.c
17
+++ b/exec.c
23
+++ b/target/arm/helper.c
18
@@ -XXX,XX +XXX,XX @@ bool address_space_access_valid(AddressSpace *as, hwaddr addr,
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
19
25
return ret;
20
static hwaddr
26
}
21
flatview_extend_translation(FlatView *fv, hwaddr addr,
27
22
- hwaddr target_len,
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
23
- MemoryRegion *mr, hwaddr base, hwaddr len,
29
+ bool isread)
24
- bool is_write)
30
+{
25
+ hwaddr target_len,
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
26
+ MemoryRegion *mr, hwaddr base, hwaddr len,
32
+ return CP_ACCESS_TRAP_EL2;
27
+ bool is_write, MemTxAttrs attrs)
33
+ }
28
{
34
+
29
hwaddr done = 0;
35
+ return CP_ACCESS_OK;
30
hwaddr xlat;
36
+}
31
@@ -XXX,XX +XXX,XX @@ void *address_space_map(AddressSpace *as,
37
+
32
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
33
memory_region_ref(mr);
39
+ bool isread)
34
*plen = flatview_extend_translation(fv, addr, len, mr, xlat,
40
+{
35
- l, is_write);
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
36
+ l, is_write, attrs);
42
+ return access_aa64_tid1(env, ri, isread);
37
ptr = qemu_ram_ptr_length(mr->ram_block, xlat, plen, true);
43
+ }
38
rcu_read_unlock();
44
+
39
45
+ return CP_ACCESS_OK;
40
@@ -XXX,XX +XXX,XX @@ int64_t address_space_cache_init(MemoryRegionCache *cache,
46
+}
41
mr = cache->mrs.mr;
47
+
42
memory_region_ref(mr);
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
43
if (memory_access_is_direct(mr, is_write)) {
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
44
+ /* We don't care about the memory attributes here as we're only
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
45
+ * doing this if we found actual RAM, which behaves the same
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
46
+ * regardless of attributes; so UNSPECIFIED is fine.
52
*/
47
+ */
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
48
l = flatview_extend_translation(cache->fv, addr, len, mr,
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
49
- cache->xlat, l, is_write);
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
50
+ cache->xlat, l, is_write,
56
+ .access = PL1_R, .type = ARM_CP_CONST,
51
+ MEMTXATTRS_UNSPECIFIED);
57
+ .accessfn = access_aa64_tid1,
52
cache->ptr = qemu_ram_ptr_length(mr->ram_block, cache->xlat, &l, true);
58
+ .resetvalue = 0 },
53
} else {
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
54
cache->ptr = NULL;
60
* choose to RAZ/WI for all cores.
61
*/
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
.access = PL1_R, .resetvalue = cpu->midr },
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
67
+ .access = PL1_R,
68
+ .accessfn = access_aa64_tid1,
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
70
REGINFO_SENTINEL
71
};
72
ARMCPRegInfo id_cp_reginfo[] = {
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
/* TCMTR and TLBTR exist in v8 but have no 64-bit versions */
75
{ .name = "TCMTR",
76
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 2,
77
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ .access = PL1_R,
79
+ .accessfn = access_aa32_tid1,
80
+ .type = ARM_CP_CONST, .resetvalue = 0 },
81
REGINFO_SENTINEL
82
};
83
/* TLBTR is specific to VMSA */
84
ARMCPRegInfo id_tlbtr_reginfo = {
85
.name = "TLBTR",
86
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 3,
87
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0,
88
+ .access = PL1_R,
89
+ .accessfn = access_aa32_tid1,
90
+ .type = ARM_CP_CONST, .resetvalue = 0,
91
};
92
/* MPUIR is specific to PMSA V6+ */
93
ARMCPRegInfo id_mpuir_reginfo = {
55
--
94
--
56
2.17.1
95
2.20.1
57
96
58
97
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Marc Zyngier <maz@kernel.org>
2
add MemTxAttrs as an argument to address_space_translate()
3
and address_space_translate_cached(). Callers either have an
4
attrs value to hand, or don't care and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
5
In order to handle this, introduce a new TCG helper function that
6
checks for these control bits before executing the VMRC instruction.
7
8
Tested with a hacked-up version of KVM/arm64 that sets the control
9
bits for 32bit guests.
10
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Signed-off-by: Marc Zyngier <maz@kernel.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
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-4-peter.maydell@linaro.org
10
---
18
---
11
include/exec/memory.h | 4 +++-
19
target/arm/helper.h | 2 ++
12
accel/tcg/translate-all.c | 2 +-
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
13
exec.c | 14 +++++++++-----
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
14
hw/vfio/common.c | 3 ++-
22
3 files changed, 47 insertions(+), 4 deletions(-)
15
memory_ldst.inc.c | 18 +++++++++---------
16
target/riscv/helper.c | 2 +-
17
6 files changed, 25 insertions(+), 18 deletions(-)
18
23
19
diff --git a/include/exec/memory.h b/include/exec/memory.h
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/include/exec/memory.h
26
--- a/target/arm/helper.h
22
+++ b/include/exec/memory.h
27
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ IOMMUTLBEntry address_space_get_iotlb_entry(AddressSpace *as, hwaddr addr,
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
24
* #MemoryRegion.
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
25
* @len: pointer to length
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
26
* @is_write: indicates the transfer direction
31
27
+ * @attrs: memory attributes
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
28
*/
33
+
29
MemoryRegion *flatview_translate(FlatView *fv,
34
/* neon_helper.c */
30
hwaddr addr, hwaddr *xlat,
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
31
@@ -XXX,XX +XXX,XX @@ MemoryRegion *flatview_translate(FlatView *fv,
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
32
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
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)
38
{
39
return flatview_translate(address_space_to_flatview(as),
40
addr, xlat, len, is_write);
41
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
42
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
43
--- a/accel/tcg/translate-all.c
39
--- a/target/arm/translate-vfp.inc.c
44
+++ b/accel/tcg/translate-all.c
40
+++ b/target/arm/translate-vfp.inc.c
45
@@ -XXX,XX +XXX,XX @@ void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr, MemTxAttrs attrs)
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
46
hwaddr l = 1;
42
if (a->l) {
47
43
/* VMRS, move VFP special register to gp register */
48
rcu_read_lock();
44
switch (a->reg) {
49
- mr = address_space_translate(as, addr, &addr, &l, false);
45
- case ARM_VFP_FPSID:
50
+ mr = address_space_translate(as, addr, &addr, &l, false, attrs);
46
- case ARM_VFP_FPEXC:
51
if (!(memory_region_is_ram(mr)
47
- case ARM_VFP_FPINST:
52
|| memory_region_is_romd(mr))) {
48
- case ARM_VFP_FPINST2:
53
rcu_read_unlock();
49
case ARM_VFP_MVFR0:
54
diff --git a/exec.c b/exec.c
50
case ARM_VFP_MVFR1:
51
case ARM_VFP_MVFR2:
52
+ case ARM_VFP_FPSID:
53
+ if (s->current_el == 1) {
54
+ TCGv_i32 tcg_reg, tcg_rt;
55
+
56
+ gen_set_condexec(s);
57
+ gen_set_pc_im(s, s->pc_curr);
58
+ tcg_reg = tcg_const_i32(a->reg);
59
+ tcg_rt = tcg_const_i32(a->rt);
60
+ gen_helper_check_hcr_el2_trap(cpu_env, tcg_rt, tcg_reg);
61
+ tcg_temp_free_i32(tcg_reg);
62
+ tcg_temp_free_i32(tcg_rt);
63
+ }
64
+ /* fall through */
65
+ case ARM_VFP_FPEXC:
66
+ case ARM_VFP_FPINST:
67
+ case ARM_VFP_FPINST2:
68
tmp = load_cpu_field(vfp.xregs[a->reg]);
69
break;
70
case ARM_VFP_FPSCR:
71
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
55
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
56
--- a/exec.c
73
--- a/target/arm/vfp_helper.c
57
+++ b/exec.c
74
+++ b/target/arm/vfp_helper.c
58
@@ -XXX,XX +XXX,XX @@ static inline void cpu_physical_memory_write_rom_internal(AddressSpace *as,
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
59
rcu_read_lock();
76
return frint_d(f, fpst, 64);
60
while (len > 0) {
77
}
61
l = len;
78
62
- mr = address_space_translate(as, addr, &addr1, &l, true);
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
63
+ mr = address_space_translate(as, addr, &addr1, &l, true,
80
+{
64
+ MEMTXATTRS_UNSPECIFIED);
81
+ uint32_t syndrome;
65
82
+
66
if (!(memory_region_is_ram(mr) ||
83
+ switch (reg) {
67
memory_region_is_romd(mr))) {
84
+ case ARM_VFP_MVFR0:
68
@@ -XXX,XX +XXX,XX @@ void address_space_cache_destroy(MemoryRegionCache *cache)
85
+ case ARM_VFP_MVFR1:
69
*/
86
+ case ARM_VFP_MVFR2:
70
static inline MemoryRegion *address_space_translate_cached(
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
71
MemoryRegionCache *cache, hwaddr addr, hwaddr *xlat,
88
+ return;
72
- hwaddr *plen, bool is_write)
89
+ }
73
+ hwaddr *plen, bool is_write, MemTxAttrs attrs)
90
+ break;
74
{
91
+ case ARM_VFP_FPSID:
75
MemoryRegionSection section;
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
76
MemoryRegion *mr;
93
+ return;
77
@@ -XXX,XX +XXX,XX @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr,
94
+ }
78
MemoryRegion *mr;
95
+ break;
79
96
+ default:
80
l = len;
97
+ g_assert_not_reached();
81
- mr = address_space_translate_cached(cache, addr, &addr1, &l, false);
98
+ }
82
+ mr = address_space_translate_cached(cache, addr, &addr1, &l, false,
99
+
83
+ MEMTXATTRS_UNSPECIFIED);
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
84
flatview_read_continue(cache->fv,
101
+ | ARM_EL_IL
85
addr, MEMTXATTRS_UNSPECIFIED, buf, len,
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
86
addr1, l, mr);
103
+ | (reg << 10) | (rt << 5) | 1);
87
@@ -XXX,XX +XXX,XX @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr,
104
+
88
MemoryRegion *mr;
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
89
106
+}
90
l = len;
107
+
91
- mr = address_space_translate_cached(cache, addr, &addr1, &l, true);
108
#endif
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);
219
--
109
--
220
2.17.1
110
2.20.1
221
111
222
112
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Marc Zyngier <maz@kernel.org>
2
add MemTxAttrs as an argument to address_space_access_valid().
3
Its callers either have an attrs value to hand, or don't care
4
and can use MEMTXATTRS_UNSPECIFIED.
5
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
4
accesses to EL2, and it looks like this register is completely
5
ignored by QEMU.
6
7
To avoid adding extra .accessfn filters all over the place (which
8
would have a direct performance impact), let's add a new TB flag
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
10
a context where this trap has a chance to apply, and only generate
11
the extra access check if the hypervisor is actively using this feature.
12
13
Tested with a hand-crafted KVM guest accessing CBAR.
14
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20191201122018.25808-5-maz@kernel.org
18
[PMM: use is_a64(); fix comment syntax]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
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-6-peter.maydell@linaro.org
10
---
20
---
11
include/exec/memory.h | 4 +++-
21
target/arm/cpu.h | 2 ++
12
include/sysemu/dma.h | 3 ++-
22
target/arm/translate.h | 2 ++
13
exec.c | 3 ++-
23
target/arm/helper.c | 6 ++++++
14
target/s390x/diag.c | 6 ++++--
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
15
target/s390x/excp_helper.c | 3 ++-
25
target/arm/translate.c | 3 ++-
16
target/s390x/mmu_helper.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
17
target/s390x/sigp.c | 3 ++-
18
7 files changed, 17 insertions(+), 8 deletions(-)
19
27
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
30
--- a/target/arm/cpu.h
23
+++ b/include/exec/memory.h
31
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static inline MemoryRegion *address_space_translate(AddressSpace *as,
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
25
* @addr: address within that address space
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
26
* @len: length of the area to be checked
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
27
* @is_write: indicates the transfer direction
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
28
+ * @attrs: memory attributes
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
29
*/
37
+
30
-bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);
38
/* For M profile only, set if FPCCR.LSPACT is set */
31
+bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len,
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
32
+ bool is_write, MemTxAttrs attrs);
40
/* For M profile only, set if we must create a new FP context */
33
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
34
/* address_space_map: map a physical memory region into a host virtual address
35
*
36
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
37
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
38
--- a/include/sysemu/dma.h
43
--- a/target/arm/translate.h
39
+++ b/include/sysemu/dma.h
44
+++ b/target/arm/translate.h
40
@@ -XXX,XX +XXX,XX @@ static inline bool dma_memory_valid(AddressSpace *as,
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
41
DMADirection dir)
46
bool pauth_active;
42
{
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
43
return address_space_access_valid(as, addr, len,
48
bool bt;
44
- dir == DMA_DIRECTION_FROM_DEVICE);
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
45
+ dir == DMA_DIRECTION_FROM_DEVICE,
50
+ bool hstr_active;
46
+ MEMTXATTRS_UNSPECIFIED);
51
/*
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
53
* < 0, set by the current instruction.
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
57
+++ b/target/arm/helper.c
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
59
if (arm_el_is_aa64(env, 1)) {
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
61
}
62
+
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
66
+ }
67
+
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
47
}
69
}
48
70
49
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
50
diff --git a/exec.c b/exec.c
51
index XXXXXXX..XXXXXXX 100644
72
index XXXXXXX..XXXXXXX 100644
52
--- a/exec.c
73
--- a/target/arm/op_helper.c
53
+++ b/exec.c
74
+++ b/target/arm/op_helper.c
54
@@ -XXX,XX +XXX,XX @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len,
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
55
}
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
56
77
}
57
bool address_space_access_valid(AddressSpace *as, hwaddr addr,
78
58
- int len, bool is_write)
79
+ /*
59
+ int len, bool is_write,
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
60
+ MemTxAttrs attrs)
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
61
{
82
+ */
62
FlatView *fv;
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
63
bool result;
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
64
diff --git a/target/s390x/diag.c b/target/s390x/diag.c
85
+ uint32_t mask = 1 << ri->crn;
65
index XXXXXXX..XXXXXXX 100644
86
+
66
--- a/target/s390x/diag.c
87
+ if (ri->type & ARM_CP_64BIT) {
67
+++ b/target/s390x/diag.c
88
+ mask = 1 << ri->crm;
68
@@ -XXX,XX +XXX,XX @@ void handle_diag_308(CPUS390XState *env, uint64_t r1, uint64_t r3, uintptr_t ra)
89
+ }
69
return;
90
+
70
}
91
+ /* T4 and T14 are RES0 */
71
if (!address_space_access_valid(&address_space_memory, addr,
92
+ mask &= ~((1 << 4) | (1 << 14));
72
- sizeof(IplParameterBlock), false)) {
93
+
73
+ sizeof(IplParameterBlock), false,
94
+ if (env->cp15.hstr_el2 & mask) {
74
+ MEMTXATTRS_UNSPECIFIED)) {
95
+ target_el = 2;
75
s390_program_interrupt(env, PGM_ADDRESSING, ILEN_AUTO, ra);
96
+ goto exept;
76
return;
97
+ }
77
}
98
+ }
78
@@ -XXX,XX +XXX,XX @@ out:
99
+
79
return;
100
if (!ri->accessfn) {
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;
101
return;
129
}
102
}
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
104
g_assert_not_reached();
105
}
106
107
+exept:
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
109
}
110
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
116
return 1;
117
}
118
119
- if (ri->accessfn ||
120
+ if (s->hstr_active || ri->accessfn ||
121
(arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
122
/* Emit code to perform further access permissions checks at
123
* runtime; this may result in an exception.
124
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
125
!arm_el_is_aa64(env, 3);
126
dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
127
dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
128
+ dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
129
dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
130
condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
131
dc->condexec_mask = (condexec & 0xf) << 1;
130
--
132
--
131
2.17.1
133
2.20.1
132
134
133
135
diff view generated by jsdifflib
1
In commit f0aff255700 we made cpacr_write() enforce that some CPACR
1
From: Marc Zyngier <maz@kernel.org>
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.
9
2
10
Implement reset for the CPACR using a custom reset function
3
QEMU lacks the minimum Jazelle implementation that is required
11
that just calls cpacr_write(), to avoid having to duplicate
4
by the architecture (everything is RAZ or RAZ/WI). Add it
12
the logic for which bits are RAO.
5
together with the HCR_EL2.TID0 trapping that goes with it.
13
6
14
This bug would affect migration for TCG CPUs which are ARMv7
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
15
with VFP but without one of Neon or VFPv3.
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
16
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Reported-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
11
[PMM: moved ARMCPRegInfo array to file scope, marked it
12
'static global', moved new condition down in
13
register_cp_regs_for_features() to go with other feature
14
things rather than up with the v6/v7/v8 stuff]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Tested-by: Cédric Le Goater <clg@kaod.org>
20
Message-id: 20180522173713.26282-1-peter.maydell@linaro.org
21
---
16
---
22
target/arm/helper.c | 10 +++++++++-
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
23
1 file changed, 9 insertions(+), 1 deletion(-)
18
1 file changed, 27 insertions(+)
24
19
25
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
26
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper.c
22
--- a/target/arm/helper.c
28
+++ b/target/arm/helper.c
23
+++ b/target/arm/helper.c
29
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
30
env->cp15.cpacr_el1 = value;
25
return CP_ACCESS_OK;
31
}
26
}
32
27
33
+static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
29
+ bool isread)
34
+{
30
+{
35
+ /* Call cpacr_write() so that we reset with the correct RAO bits set
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
36
+ * for our CPU features.
32
+ return CP_ACCESS_TRAP_EL2;
37
+ */
33
+ }
38
+ cpacr_write(env, ri, 0);
34
+
35
+ return CP_ACCESS_OK;
39
+}
36
+}
40
+
37
+
41
static CPAccessResult cpacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
38
+static const ARMCPRegInfo jazelle_regs[] = {
42
bool isread)
39
+ { .name = "JIDR",
40
+ .cp = 14, .crn = 0, .crm = 0, .opc1 = 7, .opc2 = 0,
41
+ .access = PL1_R, .accessfn = access_jazelle,
42
+ .type = ARM_CP_CONST, .resetvalue = 0 },
43
+ { .name = "JOSCR",
44
+ .cp = 14, .crn = 1, .crm = 0, .opc1 = 7, .opc2 = 0,
45
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
46
+ { .name = "JMCR",
47
+ .cp = 14, .crn = 2, .crm = 0, .opc1 = 7, .opc2 = 0,
48
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
49
+ REGINFO_SENTINEL
50
+};
51
+
52
void register_cp_regs_for_features(ARMCPU *cpu)
43
{
53
{
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
54
/* Register all the coprocessor registers based on feature bits */
45
{ .name = "CPACR", .state = ARM_CP_STATE_BOTH, .opc0 = 3,
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
.crn = 1, .crm = 0, .opc1 = 0, .opc2 = 2, .accessfn = cpacr_access,
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
47
.access = PL1_RW, .fieldoffset = offsetof(CPUARMState, cp15.cpacr_el1),
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
48
- .resetvalue = 0, .writefn = cpacr_write },
58
}
49
+ .resetfn = cpacr_reset, .writefn = cpacr_write },
59
+ if (cpu_isar_feature(jazelle, cpu)) {
50
REGINFO_SENTINEL
60
+ define_arm_cp_regs(cpu, jazelle_regs);
51
};
61
+ }
52
62
/* Slightly awkwardly, the OMAP and StrongARM cores need all of
63
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
64
* be read-only (ie write causes UNDEF exception).
53
--
65
--
54
2.17.1
66
2.20.1
55
67
56
68
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
2
3
Coverity found that the string return by 'object_get_canonical_path' was not
3
This change ensures that the FPU can be accessed in Non-Secure mode
4
being freed at two locations in the model (CID 1391294 and CID 1391293) and
4
when the CPU core is reset using the arm_set_cpu_on() function call.
5
also that a memset was being called with a value greater than the max of a byte
5
The NSACR.{CP11,CP10} bits define the exception level required to
6
on the second argument (CID 1391286). This patch corrects this by adding the
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
7
freeing of the strings and also changing to memset to zero instead on
7
will give an undefined exception trap on the first FPU access for the
8
descriptor unaligned errors.
8
secondary cores under Linux.
9
9
10
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
10
This is necessary because in this power-control codepath QEMU
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
is effectively emulating a bit of EL3 firmware, and has to set
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
the CPU up as the EL3 firmware would.
13
Message-id: 20180528184859.3530-1-frasse.iglesias@gmail.com
13
14
Fixes: fc1120a7f5
15
Cc: qemu-stable@nongnu.org
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
[PMM: added clarifying para to commit message]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
20
---
17
hw/dma/xlnx-zdma.c | 10 +++++++---
21
target/arm/arm-powerctl.c | 3 +++
18
1 file changed, 7 insertions(+), 3 deletions(-)
22
1 file changed, 3 insertions(+)
19
23
20
diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
21
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/dma/xlnx-zdma.c
26
--- a/target/arm/arm-powerctl.c
23
+++ b/hw/dma/xlnx-zdma.c
27
+++ b/target/arm/arm-powerctl.c
24
@@ -XXX,XX +XXX,XX @@ static bool zdma_load_descriptor(XlnxZDMA *s, uint64_t addr, void *buf)
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
25
qemu_log_mask(LOG_GUEST_ERROR,
29
/* Processor is not in secure mode */
26
"zdma: unaligned descriptor at %" PRIx64,
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
27
addr);
31
28
- memset(buf, 0xdeadbeef, sizeof(XlnxZDMADescr));
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
29
+ memset(buf, 0x0, sizeof(XlnxZDMADescr));
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
30
s->error = true;
34
+
31
return false;
35
/*
32
}
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
33
@@ -XXX,XX +XXX,XX @@ static uint64_t zdma_read(void *opaque, hwaddr addr, unsigned size)
37
* to make sure a CPU targeting EL2 comes out of reset with a
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;
59
--
38
--
60
2.17.1
39
2.20.1
61
40
62
41
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Beata Michalska <beata.michalska@linaro.org>
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.
5
2
3
Add probe_read alongside the write probing equivalent.
4
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180521140402.23318-3-peter.maydell@linaro.org
10
---
10
---
11
include/exec/exec-all.h | 5 +++--
11
include/exec/exec-all.h | 6 ++++++
12
accel/tcg/translate-all.c | 2 +-
12
1 file changed, 6 insertions(+)
13
exec.c | 2 +-
14
target/xtensa/op_helper.c | 3 ++-
15
4 files changed, 7 insertions(+), 5 deletions(-)
16
13
17
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/include/exec/exec-all.h
16
--- a/include/exec/exec-all.h
20
+++ b/include/exec/exec-all.h
17
+++ b/include/exec/exec-all.h
21
@@ -XXX,XX +XXX,XX @@ void tlb_set_page_with_attrs(CPUState *cpu, target_ulong vaddr,
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
22
void tlb_set_page(CPUState *cpu, target_ulong vaddr,
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
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
}
20
}
34
-static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
21
35
+static inline void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr,
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
36
+ MemTxAttrs attrs)
23
+ int mmu_idx, uintptr_t retaddr)
37
{
24
+{
38
}
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
39
#endif
26
+}
40
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
27
+
41
index XXXXXXX..XXXXXXX 100644
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
42
--- a/accel/tcg/translate-all.c
29
43
+++ b/accel/tcg/translate-all.c
30
/* Estimated block size for TB allocation. */
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);
63
}
64
}
65
#endif
66
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/xtensa/op_helper.c
69
+++ b/target/xtensa/op_helper.c
70
@@ -XXX,XX +XXX,XX @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr)
71
int ret = xtensa_get_physical_addr(env, false, vaddr, 2, 0,
72
&paddr, &page_size, &access);
73
if (ret == 0) {
74
- tb_invalidate_phys_addr(&address_space_memory, paddr);
75
+ tb_invalidate_phys_addr(&address_space_memory, paddr,
76
+ MEMTXATTRS_UNSPECIFIED);
77
}
78
}
79
80
--
31
--
81
2.17.1
32
2.20.1
82
33
83
34
diff view generated by jsdifflib
1
As part of plumbing MemTxAttrs down to the IOMMU translate method,
1
From: Beata Michalska <beata.michalska@linaro.org>
2
add MemTxAttrs as an argument to the MemoryRegion valid.accepts
3
callback. We'll need this for subpage_accepts().
4
2
5
We could take the approach we used with the read and write
3
Add an option to trigger memory writeback to sync given memory region
6
callbacks and add new a new _with_attrs version, but since there
4
with the corresponding backing store, case one is available.
7
are so few implementations of the accepts hook we just change
5
This extends the support for persistent memory, allowing syncing on-demand.
8
them all.
9
6
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <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
14
---
11
---
15
include/exec/memory.h | 3 ++-
12
include/exec/memory.h | 6 ++++++
16
exec.c | 9 ++++++---
13
include/exec/ram_addr.h | 8 ++++++++
17
hw/hppa/dino.c | 3 ++-
14
include/qemu/cutils.h | 1 +
18
hw/nvram/fw_cfg.c | 12 ++++++++----
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
19
hw/scsi/esp.c | 3 ++-
16
memory.c | 12 ++++++++++++
20
hw/xen/xen_pt_msi.c | 3 ++-
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
21
memory.c | 5 +++--
18
6 files changed, 101 insertions(+)
22
7 files changed, 25 insertions(+), 13 deletions(-)
23
19
24
diff --git a/include/exec/memory.h b/include/exec/memory.h
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/include/exec/memory.h
22
--- a/include/exec/memory.h
27
+++ b/include/exec/memory.h
23
+++ b/include/exec/memory.h
28
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
29
* as a machine check exception).
25
*/
30
*/
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
31
bool (*accepts)(void *opaque, hwaddr addr,
27
Error **errp);
32
- unsigned size, bool is_write);
28
+/**
33
+ unsigned size, bool is_write,
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
34
+ MemTxAttrs attrs);
30
+ * [addr, addr + size]
35
} valid;
31
+ *
36
/* Internal implementation constraints: */
32
+ */
37
struct {
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
34
35
/**
36
* memory_region_set_log: Turn dirty logging on or off for a region.
37
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
40
+++ b/include/exec/ram_addr.h
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
42
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
44
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
46
+
47
+/* Clear whole block of mem */
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
49
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
51
+}
52
+
53
#define DIRTY_CLIENTS_ALL ((1 << DIRTY_MEMORY_NUM) - 1)
54
#define DIRTY_CLIENTS_NOCODE (DIRTY_CLIENTS_ALL & ~(1 << DIRTY_MEMORY_CODE))
55
56
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
57
index XXXXXXX..XXXXXXX 100644
58
--- a/include/qemu/cutils.h
59
+++ b/include/qemu/cutils.h
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
61
#endif
62
time_t mktimegm(struct tm *tm);
63
int qemu_fdatasync(int fd);
64
+int qemu_msync(void *addr, size_t length, int fd);
65
int fcntl_setfl(int fd, int flag);
66
int qemu_parse_fd(const char *param);
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
38
diff --git a/exec.c b/exec.c
68
diff --git a/exec.c b/exec.c
39
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
40
--- a/exec.c
70
--- a/exec.c
41
+++ b/exec.c
71
+++ b/exec.c
42
@@ -XXX,XX +XXX,XX @@ static void notdirty_mem_write(void *opaque, hwaddr ram_addr,
72
@@ -XXX,XX +XXX,XX @@
73
#include "exec/ram_addr.h"
74
#include "exec/log.h"
75
76
+#include "qemu/pmem.h"
77
+
78
#include "migration/vmstate.h"
79
80
#include "qemu/range.h"
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
82
return 0;
43
}
83
}
44
84
45
static bool notdirty_mem_accepts(void *opaque, hwaddr addr,
85
+/*
46
- unsigned size, bool is_write)
86
+ * Trigger sync on the given ram block for range [start, start + length]
47
+ unsigned size, bool is_write,
87
+ * with the backing store if one is available.
48
+ MemTxAttrs attrs)
88
+ * Otherwise no-op.
49
{
89
+ * @Note: this is supposed to be a synchronous op.
50
return is_write;
90
+ */
51
}
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
52
@@ -XXX,XX +XXX,XX @@ static MemTxResult subpage_write(void *opaque, hwaddr addr,
92
+{
53
}
93
+ void *addr = ramblock_ptr(block, start);
54
94
+
55
static bool subpage_accepts(void *opaque, hwaddr addr,
95
+ /* The requested range should fit in within the block range */
56
- unsigned len, bool is_write)
96
+ g_assert((start + length) <= block->used_length);
57
+ unsigned len, bool is_write,
97
+
58
+ MemTxAttrs attrs)
98
+#ifdef CONFIG_LIBPMEM
59
{
99
+ /* The lack of support for pmem should not block the sync */
60
subpage_t *subpage = opaque;
100
+ if (ramblock_is_pmem(block)) {
61
#if defined(DEBUG_SUBPAGE)
101
+ pmem_persist(addr, length);
62
@@ -XXX,XX +XXX,XX @@ static void readonly_mem_write(void *opaque, hwaddr addr,
102
+ return;
63
}
103
+ }
64
104
+#endif
65
static bool readonly_mem_accepts(void *opaque, hwaddr addr,
105
+ if (block->fd >= 0) {
66
- unsigned size, bool is_write)
106
+ /**
67
+ unsigned size, bool is_write,
107
+ * Case there is no support for PMEM or the memory has not been
68
+ MemTxAttrs attrs)
108
+ * specified as persistent (or is not one) - use the msync.
69
{
109
+ * Less optimal but still achieves the same goal
70
return is_write;
110
+ */
71
}
111
+ if (qemu_msync(addr, length, block->fd)) {
72
diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c
112
+ warn_report("%s: failed to sync memory range: start: "
73
index XXXXXXX..XXXXXXX 100644
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
74
--- a/hw/hppa/dino.c
114
+ __func__, start, length);
75
+++ b/hw/hppa/dino.c
115
+ }
76
@@ -XXX,XX +XXX,XX @@ static void gsc_to_pci_forwarding(DinoState *s)
116
+ }
77
}
117
+}
78
118
+
79
static bool dino_chip_mem_valid(void *opaque, hwaddr addr,
119
/* Called with ram_list.mutex held */
80
- unsigned size, bool is_write)
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
81
+ unsigned size, bool is_write,
121
ram_addr_t new_ram_size)
82
+ MemTxAttrs attrs)
83
{
84
switch (addr) {
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,
91
}
92
93
static bool fw_cfg_dma_mem_valid(void *opaque, hwaddr addr,
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
130
index XXXXXXX..XXXXXXX 100644
131
--- a/hw/scsi/esp.c
132
+++ b/hw/scsi/esp.c
133
@@ -XXX,XX +XXX,XX @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
134
}
135
136
static bool esp_mem_accepts(void *opaque, hwaddr addr,
137
- unsigned size, bool is_write)
138
+ unsigned size, bool is_write,
139
+ MemTxAttrs attrs)
140
{
141
return (size == 1) || (is_write && size == 4);
142
}
143
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/hw/xen/xen_pt_msi.c
146
+++ b/hw/xen/xen_pt_msi.c
147
@@ -XXX,XX +XXX,XX @@ static uint64_t pci_msix_read(void *opaque, hwaddr addr,
148
}
149
150
static bool pci_msix_accepts(void *opaque, hwaddr addr,
151
- unsigned size, bool is_write)
152
+ unsigned size, bool is_write,
153
+ MemTxAttrs attrs)
154
{
155
return !(addr & (size - 1));
156
}
157
diff --git a/memory.c b/memory.c
122
diff --git a/memory.c b/memory.c
158
index XXXXXXX..XXXXXXX 100644
123
index XXXXXXX..XXXXXXX 100644
159
--- a/memory.c
124
--- a/memory.c
160
+++ b/memory.c
125
+++ b/memory.c
161
@@ -XXX,XX +XXX,XX @@ static void unassigned_mem_write(void *opaque, hwaddr addr,
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
127
qemu_ram_resize(mr->ram_block, newsize, errp);
162
}
128
}
163
129
164
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
130
+
165
- unsigned size, bool is_write)
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
166
+ unsigned size, bool is_write,
132
+{
167
+ MemTxAttrs attrs)
133
+ /*
168
{
134
+ * Might be extended case needed to cover
169
return false;
135
+ * different types of memory regions
136
+ */
137
+ if (mr->ram_block && mr->dirty_log_mask) {
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
139
+ }
140
+}
141
+
142
/*
143
* Call proper memory listeners about the change on the newly
144
* added/removed CoalescedMemoryRange.
145
diff --git a/util/cutils.c b/util/cutils.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/util/cutils.c
148
+++ b/util/cutils.c
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
150
#endif
170
}
151
}
171
@@ -XXX,XX +XXX,XX @@ bool memory_region_access_valid(MemoryRegion *mr,
152
172
access_size = MAX(MIN(size, access_size_max), access_size_min);
153
+/**
173
for (i = 0; i < size; i += access_size) {
154
+ * Sync changes made to the memory mapped file back to the backing
174
if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size,
155
+ * storage. For POSIX compliant systems this will fallback
175
- is_write)) {
156
+ * to regular msync call. Otherwise it will trigger whole file sync
176
+ is_write, attrs)) {
157
+ * (including the metadata case there is no support to skip that otherwise)
177
return false;
158
+ *
178
}
159
+ * @addr - start of the memory area to be synced
179
}
160
+ * @length - length of the are to be synced
161
+ * @fd - file descriptor for the file to be synced
162
+ * (mandatory only for POSIX non-compliant systems)
163
+ */
164
+int qemu_msync(void *addr, size_t length, int fd)
165
+{
166
+#ifdef CONFIG_POSIX
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
168
+
169
+ /**
170
+ * There are no strict reqs as per the length of mapping
171
+ * to be synced. Still the length needs to follow the address
172
+ * alignment changes. Additionally - round the size to the multiple
173
+ * of PAGE_SIZE
174
+ */
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
176
+ length = (length + ~align_mask) & align_mask;
177
+
178
+ addr = (void *)((uintptr_t)addr & align_mask);
179
+
180
+ return msync(addr, length, MS_SYNC);
181
+#else /* CONFIG_POSIX */
182
+ /**
183
+ * Perform the sync based on the file descriptor
184
+ * The sync range will most probably be wider than the one
185
+ * requested - but it will still get the job done
186
+ */
187
+ return qemu_fdatasync(fd);
188
+#endif /* CONFIG_POSIX */
189
+}
190
+
191
#ifndef _WIN32
192
/* Sets a specific flag */
193
int fcntl_setfl(int fd, int flag)
180
--
194
--
181
2.17.1
195
2.20.1
182
196
183
197
diff view generated by jsdifflib
1
The FRECPX instructions should (like most other floating point operations)
1
From: Beata Michalska <beata.michalska@linaro.org>
2
honour the FPCR.FZ bit which specifies whether input denormals should
3
be flushed to zero (or FZ16 for the half-precision version).
4
We forgot to implement this, which doesn't affect the results (since
5
the calculation doesn't actually care about the mantissa bits) but did
6
mean we were failing to set the FPSR.IDC bit.
7
2
3
Switch to ram block writeback for pmem migration.
4
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 20191121000843.24844-4-beata.michalska@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180521172712.19930-1-peter.maydell@linaro.org
11
---
11
---
12
target/arm/helper-a64.c | 6 ++++++
12
migration/ram.c | 5 +----
13
1 file changed, 6 insertions(+)
13
1 file changed, 1 insertion(+), 4 deletions(-)
14
14
15
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
15
diff --git a/migration/ram.c b/migration/ram.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.c
17
--- a/migration/ram.c
18
+++ b/target/arm/helper-a64.c
18
+++ b/migration/ram.c
19
@@ -XXX,XX +XXX,XX @@ float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
19
@@ -XXX,XX +XXX,XX @@
20
return nan;
20
#include "qemu/bitops.h"
21
#include "qemu/bitmap.h"
22
#include "qemu/main-loop.h"
23
-#include "qemu/pmem.h"
24
#include "xbzrle.h"
25
#include "ram.h"
26
#include "migration.h"
27
@@ -XXX,XX +XXX,XX @@ static int ram_load_cleanup(void *opaque)
28
RAMBlock *rb;
29
30
RAMBLOCK_FOREACH_NOT_IGNORED(rb) {
31
- if (ramblock_is_pmem(rb)) {
32
- pmem_persist(rb->host, rb->used_length);
33
- }
34
+ qemu_ram_block_writeback(rb);
21
}
35
}
22
36
23
+ a = float16_squash_input_denormal(a, fpst);
37
xbzrle_load_cleanup();
24
+
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;
30
}
31
32
+ a = float32_squash_input_denormal(a, fpst);
33
+
34
val32 = float32_val(a);
35
sbit = 0x80000000ULL & val32;
36
exp = extract32(val32, 23, 8);
37
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frecpx_f64)(float64 a, void *fpstp)
38
return nan;
39
}
40
41
+ a = float64_squash_input_denormal(a, fpst);
42
+
43
val64 = float64_val(a);
44
sbit = 0x8000000000000000ULL & val64;
45
exp = extract64(float64_val(a), 52, 11);
46
--
38
--
47
2.17.1
39
2.20.1
48
40
49
41
diff view generated by jsdifflib
1
Add more detail to the documentation for memory_region_init_iommu()
1
From: Beata Michalska <beata.michalska@linaro.org>
2
and other IOMMU-related functions and data structures.
3
2
3
ARMv8.2 introduced support for Data Cache Clean instructions
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
5
- DV CVADP. Both specify conceptual points in a memory system where all writes
6
that are to reach them are considered persistent.
7
The support provided considers both to be actually the same so there is no
8
distinction between the two. If none is available (there is no backing store
9
for given memory) both will result in Data Cache Clean up to the point of
10
coherency. Otherwise sync for the specified range shall be performed.
11
12
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
16
---
10
include/exec/memory.h | 105 ++++++++++++++++++++++++++++++++++++++----
17
target/arm/cpu.h | 10 ++++++++
11
1 file changed, 95 insertions(+), 10 deletions(-)
18
linux-user/elfload.c | 2 ++
19
target/arm/cpu64.c | 1 +
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
21
4 files changed, 69 insertions(+)
12
22
13
diff --git a/include/exec/memory.h b/include/exec/memory.h
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/memory.h
25
--- a/target/arm/cpu.h
16
+++ b/include/exec/memory.h
26
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ enum IOMMUMemoryRegionAttr {
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
18
IOMMU_ATTR_SPAPR_TCE_FD
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
29
}
30
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
32
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
34
+}
35
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
39
+}
40
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
42
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
53
54
return hwcaps;
55
}
56
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
57
ARMCPU *cpu = ARM_CPU(thread_cpu);
58
uint32_t hwcaps = 0;
59
60
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
61
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
62
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
63
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
70
71
t = cpu->isar.id_aa64isar1;
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
81
.access = PL0_R, .readfn = rndr_readfn },
82
REGINFO_SENTINEL
19
};
83
};
20
84
+
21
+/**
85
+#ifndef CONFIG_USER_ONLY
22
+ * IOMMUMemoryRegionClass:
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
23
+ *
87
+ uint64_t value)
24
+ * All IOMMU implementations need to subclass TYPE_IOMMU_MEMORY_REGION
88
+{
25
+ * and provide an implementation of at least the @translate method here
89
+ ARMCPU *cpu = env_archcpu(env);
26
+ * to handle requests to the memory region. Other methods are optional.
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
27
+ *
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
28
+ * The IOMMU implementation must use the IOMMU notifier infrastructure
92
+ uint64_t vaddr_in = (uint64_t) value;
29
+ * to report whenever mappings are changed, by calling
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
30
+ * memory_region_notify_iommu() (or, if necessary, by calling
94
+ void *haddr;
31
+ * memory_region_notify_one() for each registered notifier).
95
+ int mem_idx = cpu_mmu_index(env, false);
32
+ */
96
+
33
typedef struct IOMMUMemoryRegionClass {
97
+ /* This won't be crossing page boundaries */
34
/* private */
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
35
struct DeviceClass parent_class;
99
+ if (haddr) {
100
+
101
+ ram_addr_t offset;
102
+ MemoryRegion *mr;
103
+
104
+ /* RCU lock is already being held */
105
+ mr = memory_region_from_host(haddr, &offset);
106
+
107
+ if (mr) {
108
+ memory_region_do_writeback(mr, offset, dline_size);
109
+ }
110
+ }
111
+}
112
+
113
+static const ARMCPRegInfo dcpop_reg[] = {
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
116
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
117
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
118
+ REGINFO_SENTINEL
119
+};
120
+
121
+static const ARMCPRegInfo dcpodp_reg[] = {
122
+ { .name = "DC_CVADP", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 13, .opc2 = 1,
124
+ .access = PL0_W, .type = ARM_CP_NO_RAW | ARM_CP_SUPPRESS_TB_END,
125
+ .accessfn = aa64_cacheop_access, .writefn = dccvap_writefn },
126
+ REGINFO_SENTINEL
127
+};
128
+#endif /*CONFIG_USER_ONLY*/
129
+
130
#endif
131
132
static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
133
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
134
if (cpu_isar_feature(aa64_rndr, cpu)) {
135
define_arm_cp_regs(cpu, rndr_reginfo);
136
}
137
+#ifndef CONFIG_USER_ONLY
138
+ /* Data Cache clean instructions up to PoP */
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
141
+
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
144
+ }
145
+ }
146
+#endif /*CONFIG_USER_ONLY*/
147
#endif
36
148
37
/*
149
/*
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
171
--
150
--
172
2.17.1
151
2.20.1
173
152
174
153
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Make the gic a field in the machine state, and instead of filling
4
an array of qemu_irq and passing it around, directly call
5
qdev_get_gpio_in() on the gic field.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
13
1 file changed, 42 insertions(+), 44 deletions(-)
14
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
18
+++ b/hw/arm/sbsa-ref.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
20
void *fdt;
21
int fdt_size;
22
int psci_conduit;
23
+ DeviceState *gic;
24
PFlashCFI01 *flash[2];
25
} SBSAMachineState;
26
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
28
memory_region_add_subregion(secure_sysmem, base, secram);
29
}
30
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
32
+static void create_gic(SBSAMachineState *sms)
33
{
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
35
- DeviceState *gicdev;
36
SysBusDevice *gicbusdev;
37
const char *gictype;
38
uint32_t redist0_capacity, redist0_count;
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
40
41
gictype = gicv3_class_name();
42
43
- gicdev = qdev_create(NULL, gictype);
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
46
+ sms->gic = qdev_create(NULL, gictype);
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
49
/*
50
* Note that the num-irq property counts both internal and external
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
52
*/
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
57
58
redist0_capacity =
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
60
redist0_count = MIN(smp_cpus, redist0_capacity);
61
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
66
67
- qdev_init_nofail(gicdev);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
69
+ qdev_init_nofail(sms->gic);
70
+ gicbusdev = SYS_BUS_DEVICE(sms->gic);
71
sysbus_mmio_map(gicbusdev, 0, sbsa_ref_memmap[SBSA_GIC_DIST].base);
72
sysbus_mmio_map(gicbusdev, 1, sbsa_ref_memmap[SBSA_GIC_REDIST].base);
73
74
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
75
76
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
77
qdev_connect_gpio_out(cpudev, irq,
78
- qdev_get_gpio_in(gicdev,
79
+ qdev_get_gpio_in(sms->gic,
80
ppibase + timer_irq[irq]));
81
}
82
83
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
84
- qdev_get_gpio_in(gicdev, ppibase
85
+ qdev_get_gpio_in(sms->gic, ppibase
86
+ ARCH_GIC_MAINT_IRQ));
87
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
88
- qdev_get_gpio_in(gicdev, ppibase
89
+ qdev_get_gpio_in(sms->gic, ppibase
90
+ VIRTUAL_PMU_IRQ));
91
92
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
93
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
94
sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
95
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
96
}
97
-
98
- for (i = 0; i < NUM_IRQS; i++) {
99
- pic[i] = qdev_get_gpio_in(gicdev, i);
100
- }
101
}
102
103
-static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
104
+static void create_uart(const SBSAMachineState *sms, int uart,
105
MemoryRegion *mem, Chardev *chr)
106
{
107
hwaddr base = sbsa_ref_memmap[uart].base;
108
@@ -XXX,XX +XXX,XX @@ static void create_uart(const SBSAMachineState *sms, qemu_irq *pic, int uart,
109
qdev_init_nofail(dev);
110
memory_region_add_subregion(mem, base,
111
sysbus_mmio_get_region(s, 0));
112
- sysbus_connect_irq(s, 0, pic[irq]);
113
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(sms->gic, irq));
114
}
115
116
-static void create_rtc(const SBSAMachineState *sms, qemu_irq *pic)
117
+static void create_rtc(const SBSAMachineState *sms)
118
{
119
hwaddr base = sbsa_ref_memmap[SBSA_RTC].base;
120
int irq = sbsa_ref_irqmap[SBSA_RTC];
121
122
- sysbus_create_simple("pl031", base, pic[irq]);
123
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(sms->gic, irq));
124
}
125
126
static DeviceState *gpio_key_dev;
127
@@ -XXX,XX +XXX,XX @@ static Notifier sbsa_ref_powerdown_notifier = {
128
.notify = sbsa_ref_powerdown_req
129
};
130
131
-static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
132
+static void create_gpio(const SBSAMachineState *sms)
133
{
134
DeviceState *pl061_dev;
135
hwaddr base = sbsa_ref_memmap[SBSA_GPIO].base;
136
int irq = sbsa_ref_irqmap[SBSA_GPIO];
137
138
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
139
+ pl061_dev = sysbus_create_simple("pl061", base,
140
+ qdev_get_gpio_in(sms->gic, irq));
141
142
gpio_key_dev = sysbus_create_simple("gpio-key", -1,
143
qdev_get_gpio_in(pl061_dev, 3));
144
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const SBSAMachineState *sms, qemu_irq *pic)
145
qemu_register_powerdown_notifier(&sbsa_ref_powerdown_notifier);
146
}
147
148
-static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
149
+static void create_ahci(const SBSAMachineState *sms)
150
{
151
hwaddr base = sbsa_ref_memmap[SBSA_AHCI].base;
152
int irq = sbsa_ref_irqmap[SBSA_AHCI];
153
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
154
qdev_prop_set_uint32(dev, "num-ports", NUM_SATA_PORTS);
155
qdev_init_nofail(dev);
156
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
157
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
158
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(sms->gic, irq));
159
160
sysahci = SYSBUS_AHCI(dev);
161
ahci = &sysahci->ahci;
162
@@ -XXX,XX +XXX,XX @@ static void create_ahci(const SBSAMachineState *sms, qemu_irq *pic)
163
}
164
}
165
166
-static void create_ehci(const SBSAMachineState *sms, qemu_irq *pic)
167
+static void create_ehci(const SBSAMachineState *sms)
168
{
169
hwaddr base = sbsa_ref_memmap[SBSA_EHCI].base;
170
int irq = sbsa_ref_irqmap[SBSA_EHCI];
171
172
- sysbus_create_simple("platform-ehci-usb", base, pic[irq]);
173
+ sysbus_create_simple("platform-ehci-usb", base,
174
+ qdev_get_gpio_in(sms->gic, irq));
175
}
176
177
-static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
178
- PCIBus *bus)
179
+static void create_smmu(const SBSAMachineState *sms, PCIBus *bus)
180
{
181
hwaddr base = sbsa_ref_memmap[SBSA_SMMU].base;
182
int irq = sbsa_ref_irqmap[SBSA_SMMU];
183
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const SBSAMachineState *sms, qemu_irq *pic,
184
qdev_init_nofail(dev);
185
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
186
for (i = 0; i < NUM_SMMU_IRQS; i++) {
187
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
188
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
189
+ qdev_get_gpio_in(sms->gic, irq + 1));
190
}
191
}
192
193
-static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
194
+static void create_pcie(SBSAMachineState *sms)
195
{
196
hwaddr base_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].base;
197
hwaddr size_ecam = sbsa_ref_memmap[SBSA_PCIE_ECAM].size;
198
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
199
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
200
201
for (i = 0; i < GPEX_NUM_IRQS; i++) {
202
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
203
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
204
+ qdev_get_gpio_in(sms->gic, irq + 1));
205
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
206
}
207
208
@@ -XXX,XX +XXX,XX @@ static void create_pcie(SBSAMachineState *sms, qemu_irq *pic)
209
210
pci_create_simple(pci->bus, -1, "VGA");
211
212
- create_smmu(sms, pic, pci->bus);
213
+ create_smmu(sms, pci->bus);
214
}
215
216
static void *sbsa_ref_dtb(const struct arm_boot_info *binfo, int *fdt_size)
217
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
218
bool firmware_loaded;
219
const CPUArchIdList *possible_cpus;
220
int n, sbsa_max_cpus;
221
- qemu_irq pic[NUM_IRQS];
222
223
if (strcmp(machine->cpu_type, ARM_CPU_TYPE_NAME("cortex-a57"))) {
224
error_report("sbsa-ref: CPU type other than the built-in "
225
@@ -XXX,XX +XXX,XX @@ static void sbsa_ref_init(MachineState *machine)
226
227
create_secure_ram(sms, secure_sysmem);
228
229
- create_gic(sms, pic);
230
+ create_gic(sms);
231
232
- create_uart(sms, pic, SBSA_UART, sysmem, serial_hd(0));
233
- create_uart(sms, pic, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
234
+ create_uart(sms, SBSA_UART, sysmem, serial_hd(0));
235
+ create_uart(sms, SBSA_SECURE_UART, secure_sysmem, serial_hd(1));
236
/* Second secure UART for RAS and MM from EL0 */
237
- create_uart(sms, pic, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
238
+ create_uart(sms, SBSA_SECURE_UART_MM, secure_sysmem, serial_hd(2));
239
240
- create_rtc(sms, pic);
241
+ create_rtc(sms);
242
243
- create_gpio(sms, pic);
244
+ create_gpio(sms);
245
246
- create_ahci(sms, pic);
247
+ create_ahci(sms);
248
249
- create_ehci(sms, pic);
250
+ create_ehci(sms);
251
252
- create_pcie(sms, pic);
253
+ create_pcie(sms);
254
255
sms->bootinfo.ram_size = machine->ram_size;
256
sms->bootinfo.nb_cpus = smp_cpus;
257
--
258
2.20.1
259
260
diff view generated by jsdifflib
1
From: Paolo Bonzini <pbonzini@redhat.com>
1
From: Heyi Guo <guoheyi@huawei.com>
2
2
3
cpregs_keys is an uint32_t* so the allocation should use uint32_t.
3
The last argument of AML bit and/or statement is the target variable,
4
g_new is even better because it is type-safe.
4
so we don't need to use a NULL target and then an additional store
5
operation; using just aml_and() or aml_or() statement is enough.
5
6
6
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Suggested-by: Igor Mammedov <imammedo@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-2-guoheyi@huawei.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
18
---
11
target/arm/gdbstub.c | 3 +--
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
12
1 file changed, 1 insertion(+), 2 deletions(-)
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
21
tests/data/acpi/virt/DSDT.memhp | Bin 19807 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18470 -> 18462 bytes
23
4 files changed, 8 insertions(+), 8 deletions(-)
13
24
14
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/gdbstub.c
27
--- a/hw/arm/virt-acpi-build.c
17
+++ b/target/arm/gdbstub.c
28
+++ b/hw/arm/virt-acpi-build.c
18
@@ -XXX,XX +XXX,XX @@ int arm_gen_dynamic_xml(CPUState *cs)
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
19
RegisterSysregXmlParam param = {cs, s};
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
20
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
21
cpu->dyn_xml.num_cpregs = 0;
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
22
- cpu->dyn_xml.cpregs_keys = g_malloc(sizeof(uint32_t *) *
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
23
- g_hash_table_size(cpu->cp_regs));
34
- aml_name("CTRL")));
24
+ cpu->dyn_xml.cpregs_keys = g_new(uint32_t, g_hash_table_size(cpu->cp_regs));
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
25
g_string_printf(s, "<?xml version=\"1.0\"?>");
36
+ aml_name("CTRL")));
26
g_string_append_printf(s, "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">");
37
27
g_string_append_printf(s, "<feature name=\"org.qemu.gdb.arm.sys.regs\">");
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
40
- aml_name("CDW1")));
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
42
+ aml_name("CDW1")));
43
aml_append(ifctx, ifctx1);
44
45
ifctx1 = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), aml_name("CTRL"))));
46
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x10), NULL),
47
- aml_name("CDW1")));
48
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x10),
49
+ aml_name("CDW1")));
50
aml_append(ifctx, ifctx1);
51
52
aml_append(ifctx, aml_store(aml_name("CTRL"), aml_name("CDW3")));
53
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
54
aml_append(method, ifctx);
55
56
elsectx = aml_else();
57
- aml_append(elsectx, aml_store(aml_or(aml_name("CDW1"), aml_int(4), NULL),
58
- aml_name("CDW1")));
59
+ aml_append(elsectx, aml_or(aml_name("CDW1"), aml_int(4),
60
+ aml_name("CDW1")));
61
aml_append(elsectx, aml_return(aml_arg(3)));
62
aml_append(method, elsectx);
63
aml_append(dev, method);
64
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
65
index XXXXXXX..XXXXXXX 100644
66
GIT binary patch
67
delta 133
68
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
69
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
70
MAmS{W8QoPG0j8@bzW@LL
71
72
delta 141
73
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
74
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
75
R$zCV`m0@An{L@X95dZ+BD!u>!
76
77
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
78
index XXXXXXX..XXXXXXX 100644
79
GIT binary patch
80
delta 132
81
zcmcaVi}Cs_MlP3NmymE@1_ma@iCof*O&is^IGH-{Zr;SX-A2HTGu}VgnWZb6!PzC;
82
zaDm6<N;gaQYUhw3A1+xCxj<mj<V?m|kR%reSc%xA$w1l|Bnc4~00|d>_#p8m*$ep~
83
L;w+mP-Q(B*s{AMU
84
85
delta 140
86
zcmcaUi}C&}MlP3Nmymd01_maViCof*T^rT9IGGynZQjJW-A2HVGu}VgnWZb6!PzC;
87
zaDm_CN;gaYf@<fGARjJS1`xGCXwu|N#)4XqJQoK<nZ%^YK&~-J8Y&?GmM8#;fMk|r
88
QFBE{vurO@?=@!QZ00dYn_y7O^
89
90
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
91
index XXXXXXX..XXXXXXX 100644
92
GIT binary patch
93
delta 133
94
zcmZ2BfpOjhMlP3Nmk>D*1_q|2iCof5o%I{lJ2{y;?{412x!p#<jWgaq*qNm(o59&7
95
z+;D-%<VrV7_iE>mARjJS5V=5L(&S9WT970c2Uv;Nq{%?q7$gZ1761tsfcPNsCD{x4
96
MAmS{W8QoPG0j8@bzW@LL
97
98
delta 141
99
zcmbO?fpOUcMlP3Nmk>1%1_q`n6S<_B8XGpMcXBc{-rKy1bGwazA7{LOuro_nHiNTE
100
zxZwi7$(3%F{sq;}AwfP|vJ4<<fzYJMnT!RsAbBnhh%$*ulYv}gkTg_604z}e5&_99
101
R$zCV`m0@An{L@X95dZ+BD!u>!
102
28
--
103
--
29
2.17.1
104
2.20.1
30
105
31
106
diff view generated by jsdifflib
1
From: Shannon Zhao <zhaoshenglong@huawei.com>
1
From: Heyi Guo <guoheyi@huawei.com>
2
2
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
4
is no enough contiguous memory, the address will be changed. So previous
4
we will also have SHPC controller on ARM, so just enable SHPC native
5
pointer could not be used any more. It must update the pointer and use
5
hot plug.
6
the new one.
7
6
8
Also, previous codes wrongly use le32 conversion of iort->node_offset
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
9
for subsequent computations that will result incorrect value if host is
10
not litlle endian. So use the non-converted one instead.
11
8
12
Signed-off-by: Shannon Zhao <zhaoshenglong@huawei.com>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1527663951-14552-1-git-send-email-zhaoshenglong@huawei.com
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
12
Cc: Igor Mammedov <imammedo@redhat.com>
13
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
14
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
15
Signed-off-by: Heyi Guo <guoheyi@huawei.com>
16
Message-id: 20191209063719.23086-3-guoheyi@huawei.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
hw/arm/virt-acpi-build.c | 20 +++++++++++++++-----
19
hw/arm/virt-acpi-build.c | 7 ++++++-
18
1 file changed, 15 insertions(+), 5 deletions(-)
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
21
tests/data/acpi/virt/DSDT.memhp | Bin 19799 -> 19799 bytes
22
tests/data/acpi/virt/DSDT.numamem | Bin 18462 -> 18462 bytes
23
4 files changed, 6 insertions(+), 1 deletion(-)
19
24
20
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
21
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt-acpi-build.c
27
--- a/hw/arm/virt-acpi-build.c
23
+++ b/hw/arm/virt-acpi-build.c
28
+++ b/hw/arm/virt-acpi-build.c
24
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
25
AcpiIortItsGroup *its;
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
26
AcpiIortTable *iort;
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
27
AcpiIortSmmu3 *smmu;
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
28
- size_t node_size, iort_length, smmu_offset = 0;
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
29
+ size_t node_size, iort_node_offset, iort_length, smmu_offset = 0;
34
+
30
AcpiIortRC *rc;
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
+ /*
35
+ /*
39
+ * Use a copy in case table_data->data moves during acpi_data_push
36
+ * Allow OS control for all 5 features:
40
+ * operations.
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
41
+ */
38
+ */
42
+ iort_node_offset = sizeof(*iort);
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
43
+ iort->node_offset = cpu_to_le32(iort_node_offset);
40
aml_name("CTRL")));
44
41
45
/* ITS group node */
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
46
node_size = sizeof(*its) + sizeof(uint32_t);
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
47
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
44
index XXXXXXX..XXXXXXX 100644
48
int irq = vms->irqmap[VIRT_SMMU];
45
GIT binary patch
49
46
delta 28
50
/* SMMUv3 node */
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
51
- smmu_offset = iort->node_offset + node_size;
48
52
+ smmu_offset = iort_node_offset + node_size;
49
delta 28
53
node_size = sizeof(*smmu) + sizeof(*idmap);
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
54
iort_length += node_size;
51
55
smmu = acpi_data_push(table_data, node_size);
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
56
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
53
index XXXXXXX..XXXXXXX 100644
57
idmap->id_count = cpu_to_le32(0xFFFF);
54
GIT binary patch
58
idmap->output_base = 0;
55
delta 28
59
/* output IORT node is the ITS group node (the first node) */
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
60
- idmap->output_reference = cpu_to_le32(iort->node_offset);
57
61
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
58
delta 28
62
}
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
63
60
64
/* Root Complex Node */
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
65
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
62
index XXXXXXX..XXXXXXX 100644
66
idmap->output_reference = cpu_to_le32(smmu_offset);
63
GIT binary patch
67
} else {
64
delta 28
68
/* output IORT node is the ITS group node (the first node) */
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
69
- idmap->output_reference = cpu_to_le32(iort->node_offset);
66
70
+ idmap->output_reference = cpu_to_le32(iort_node_offset);
67
delta 28
71
}
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
72
69
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),
81
--
70
--
82
2.17.1
71
2.20.1
83
72
84
73
diff view generated by jsdifflib
New patch
1
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
3
Make the gic a field in the machine state, and instead of filling
4
an array of qemu_irq and passing it around, directly call
5
qdev_get_gpio_in() on the gic field.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20191209090306.20433-1-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/virt.h | 1 +
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
20
+++ b/include/hw/arm/virt.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
22
uint32_t iommu_phandle;
23
int psci_conduit;
24
hwaddr highest_gpa;
25
+ DeviceState *gic;
26
DeviceState *acpi_dev;
27
Notifier powerdown_notifier;
28
} VirtMachineState;
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
32
+++ b/hw/arm/virt.c
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
34
}
35
}
36
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
39
{
40
DeviceState *dev;
41
MachineState *ms = MACHINE(vms);
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
43
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
48
49
qdev_init_nofail(dev);
50
51
return dev;
52
}
53
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
55
+static void create_its(VirtMachineState *vms)
56
{
57
const char *itsclass = its_class_name();
58
DeviceState *dev;
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
60
61
dev = qdev_create(NULL, itsclass);
62
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
65
&error_abort);
66
qdev_init_nofail(dev);
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
69
fdt_add_its_gic_node(vms);
70
}
71
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
73
+static void create_v2m(VirtMachineState *vms)
74
{
75
int i;
76
int irq = vms->irqmap[VIRT_GIC_V2M];
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
78
qdev_init_nofail(dev);
79
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
82
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
83
+ qdev_get_gpio_in(vms->gic, irq + i));
84
}
85
86
fdt_add_v2m_gic_node(vms);
87
}
88
89
-static void create_gic(VirtMachineState *vms, qemu_irq *pic)
90
+static void create_gic(VirtMachineState *vms)
91
{
92
MachineState *ms = MACHINE(vms);
93
/* We create a standalone GIC */
94
- DeviceState *gicdev;
95
SysBusDevice *gicbusdev;
96
const char *gictype;
97
int type = vms->gic_version, i;
98
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
99
100
gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
101
102
- gicdev = qdev_create(NULL, gictype);
103
- qdev_prop_set_uint32(gicdev, "revision", type);
104
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
105
+ vms->gic = qdev_create(NULL, gictype);
106
+ qdev_prop_set_uint32(vms->gic, "revision", type);
107
+ qdev_prop_set_uint32(vms->gic, "num-cpu", smp_cpus);
108
/* Note that the num-irq property counts both internal and external
109
* interrupts; there are always 32 of the former (mandated by GIC spec).
110
*/
111
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
112
+ qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
113
if (!kvm_irqchip_in_kernel()) {
114
- qdev_prop_set_bit(gicdev, "has-security-extensions", vms->secure);
115
+ qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
116
}
117
118
if (type == 3) {
119
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
120
121
nb_redist_regions = virt_gicv3_redist_region_count(vms);
122
123
- qdev_prop_set_uint32(gicdev, "len-redist-region-count",
124
+ qdev_prop_set_uint32(vms->gic, "len-redist-region-count",
125
nb_redist_regions);
126
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
127
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
128
129
if (nb_redist_regions == 2) {
130
uint32_t redist1_capacity =
131
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
132
133
- qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
134
+ qdev_prop_set_uint32(vms->gic, "redist-region-count[1]",
135
MIN(smp_cpus - redist0_count, redist1_capacity));
136
}
137
} else {
138
if (!kvm_irqchip_in_kernel()) {
139
- qdev_prop_set_bit(gicdev, "has-virtualization-extensions",
140
+ qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
141
vms->virt);
142
}
143
}
144
- qdev_init_nofail(gicdev);
145
- gicbusdev = SYS_BUS_DEVICE(gicdev);
146
+ qdev_init_nofail(vms->gic);
147
+ gicbusdev = SYS_BUS_DEVICE(vms->gic);
148
sysbus_mmio_map(gicbusdev, 0, vms->memmap[VIRT_GIC_DIST].base);
149
if (type == 3) {
150
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
151
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
152
153
for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
154
qdev_connect_gpio_out(cpudev, irq,
155
- qdev_get_gpio_in(gicdev,
156
+ qdev_get_gpio_in(vms->gic,
157
ppibase + timer_irq[irq]));
158
}
159
160
if (type == 3) {
161
- qemu_irq irq = qdev_get_gpio_in(gicdev,
162
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
163
ppibase + ARCH_GIC_MAINT_IRQ);
164
qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
165
0, irq);
166
} else if (vms->virt) {
167
- qemu_irq irq = qdev_get_gpio_in(gicdev,
168
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
169
ppibase + ARCH_GIC_MAINT_IRQ);
170
sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
171
}
172
173
qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
174
- qdev_get_gpio_in(gicdev, ppibase
175
+ qdev_get_gpio_in(vms->gic, ppibase
176
+ VIRTUAL_PMU_IRQ));
177
178
sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
180
qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
181
}
182
183
- for (i = 0; i < NUM_IRQS; i++) {
184
- pic[i] = qdev_get_gpio_in(gicdev, i);
185
- }
186
-
187
fdt_add_gic_node(vms);
188
189
if (type == 3 && vms->its) {
190
- create_its(vms, gicdev);
191
+ create_its(vms);
192
} else if (type == 2) {
193
- create_v2m(vms, pic);
194
+ create_v2m(vms);
195
}
196
}
197
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
199
+static void create_uart(const VirtMachineState *vms, int uart,
200
MemoryRegion *mem, Chardev *chr)
201
{
202
char *nodename;
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
204
qdev_init_nofail(dev);
205
memory_region_add_subregion(mem, base,
206
sysbus_mmio_get_region(s, 0));
207
- sysbus_connect_irq(s, 0, pic[irq]);
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
209
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
211
qemu_fdt_add_subnode(vms->fdt, nodename);
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
213
g_free(nodename);
214
}
215
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
217
+static void create_rtc(const VirtMachineState *vms)
218
{
219
char *nodename;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
222
int irq = vms->irqmap[VIRT_RTC];
223
const char compat[] = "arm,pl031\0arm,primecell";
224
225
- sysbus_create_simple("pl031", base, pic[irq]);
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
227
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
229
qemu_fdt_add_subnode(vms->fdt, nodename);
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
231
}
232
}
233
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
235
+static void create_gpio(const VirtMachineState *vms)
236
{
237
char *nodename;
238
DeviceState *pl061_dev;
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
240
int irq = vms->irqmap[VIRT_GPIO];
241
const char compat[] = "arm,pl061\0arm,primecell";
242
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
244
+ pl061_dev = sysbus_create_simple("pl061", base,
245
+ qdev_get_gpio_in(vms->gic, irq));
246
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
250
g_free(nodename);
251
}
252
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
254
+static void create_virtio_devices(const VirtMachineState *vms)
255
{
256
int i;
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
259
int irq = vms->irqmap[VIRT_MMIO] + i;
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
261
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
263
+ sysbus_create_simple("virtio-mmio", base,
264
+ qdev_get_gpio_in(vms->gic, irq));
265
}
266
267
/* We add dtb nodes in reverse order so that they appear in the finished
268
@@ -XXX,XX +XXX,XX @@ static void create_pcie_irq_map(const VirtMachineState *vms,
269
0x7 /* PCI irq */);
270
}
271
272
-static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
273
+static void create_smmu(const VirtMachineState *vms,
274
PCIBus *bus)
275
{
276
char *node;
277
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
278
qdev_init_nofail(dev);
279
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
280
for (i = 0; i < NUM_SMMU_IRQS; i++) {
281
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
282
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
283
+ qdev_get_gpio_in(vms->gic, irq + i));
284
}
285
286
node = g_strdup_printf("/smmuv3@%" PRIx64, base);
287
@@ -XXX,XX +XXX,XX @@ static void create_smmu(const VirtMachineState *vms, qemu_irq *pic,
288
g_free(node);
289
}
290
291
-static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
292
+static void create_pcie(VirtMachineState *vms)
293
{
294
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
295
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
296
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
297
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, base_pio);
298
299
for (i = 0; i < GPEX_NUM_IRQS; i++) {
300
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
301
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
302
+ qdev_get_gpio_in(vms->gic, irq + i));
303
gpex_set_irq_num(GPEX_HOST(dev), i, irq + i);
304
}
305
306
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
307
if (vms->iommu) {
308
vms->iommu_phandle = qemu_fdt_alloc_phandle(vms->fdt);
309
310
- create_smmu(vms, pic, pci->bus);
311
+ create_smmu(vms, pci->bus);
312
313
qemu_fdt_setprop_cells(vms->fdt, nodename, "iommu-map",
314
0x0, vms->iommu_phandle, 0x0, 0x10000);
315
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
316
g_free(nodename);
317
}
318
319
-static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
320
+static void create_platform_bus(VirtMachineState *vms)
321
{
322
DeviceState *dev;
323
SysBusDevice *s;
324
@@ -XXX,XX +XXX,XX @@ static void create_platform_bus(VirtMachineState *vms, qemu_irq *pic)
325
326
s = SYS_BUS_DEVICE(dev);
327
for (i = 0; i < PLATFORM_BUS_NUM_IRQS; i++) {
328
- int irqn = vms->irqmap[VIRT_PLATFORM_BUS] + i;
329
- sysbus_connect_irq(s, i, pic[irqn]);
330
+ int irq = vms->irqmap[VIRT_PLATFORM_BUS] + i;
331
+ sysbus_connect_irq(s, i, qdev_get_gpio_in(vms->gic, irq));
332
}
333
334
memory_region_add_subregion(sysmem,
335
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
336
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(machine);
337
MachineClass *mc = MACHINE_GET_CLASS(machine);
338
const CPUArchIdList *possible_cpus;
339
- qemu_irq pic[NUM_IRQS];
340
MemoryRegion *sysmem = get_system_memory();
341
MemoryRegion *secure_sysmem = NULL;
342
int n, virt_max_cpus;
343
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
344
345
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
346
347
- create_gic(vms, pic);
348
+ create_gic(vms);
349
350
fdt_add_pmu_nodes(vms);
351
352
- create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0));
353
+ create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
354
355
if (vms->secure) {
356
create_secure_ram(vms, secure_sysmem);
357
- create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
358
+ create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
359
}
360
361
vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64);
362
363
- create_rtc(vms, pic);
364
+ create_rtc(vms);
365
366
- create_pcie(vms, pic);
367
+ create_pcie(vms);
368
369
if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
370
- vms->acpi_dev = create_acpi_ged(vms, pic);
371
+ vms->acpi_dev = create_acpi_ged(vms);
372
} else {
373
- create_gpio(vms, pic);
374
+ create_gpio(vms);
375
}
376
377
/* connect powerdown request */
378
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
379
* (which will be automatically plugged in to the transports). If
380
* no backend is created the transport will just sit harmlessly idle.
381
*/
382
- create_virtio_devices(vms, pic);
383
+ create_virtio_devices(vms);
384
385
vms->fw_cfg = create_fw_cfg(vms, &address_space_memory);
386
rom_set_fw(vms->fw_cfg);
387
388
- create_platform_bus(vms, pic);
389
+ create_platform_bus(vms);
390
391
vms->bootinfo.ram_size = machine->ram_size;
392
vms->bootinfo.nb_cpus = smp_cpus;
393
--
394
2.20.1
395
396
diff view generated by jsdifflib
1
Add entries to MAINTAINERS to cover the newer MPS2 boards and
1
From: Alex Bennée <alex.bennee@linaro.org>
2
the new devices they use.
3
2
3
A write to the SCR can change the effective EL by droppping the system
4
from secure to non-secure mode. However if we use a cached current_el
5
from before the change we'll rebuild the flags incorrectly. To fix
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
7
should be used when recomputing the flags.
8
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
13
Cc: Richard Henderson <richard.henderson@linaro.org>
14
Message-Id: <20191209143723.6368-1-alex.bennee@linaro.org>
15
Cc: qemu-stable@nongnu.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20180518153157.14899-1-peter.maydell@linaro.org
6
---
17
---
7
MAINTAINERS | 9 +++++++--
18
target/arm/cpu.h | 8 ++++++--
8
1 file changed, 7 insertions(+), 2 deletions(-)
19
target/arm/helper.h | 1 +
20
target/arm/helper.c | 14 +++++++++++++-
21
target/arm/translate.c | 6 +++++-
22
4 files changed, 25 insertions(+), 4 deletions(-)
9
23
10
diff --git a/MAINTAINERS b/MAINTAINERS
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
12
--- a/MAINTAINERS
26
--- a/target/arm/cpu.h
13
+++ b/MAINTAINERS
27
+++ b/target/arm/cpu.h
14
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
15
F: include/hw/timer/cmsdk-apb-timer.h
29
* RAISES_EXC is for when the read or write hook might raise an exception;
16
F: hw/char/cmsdk-apb-uart.c
30
* the generated code will synchronize the CPU state before calling the hook
17
F: include/hw/char/cmsdk-apb-uart.h
31
* so that it is safe for the hook to call raise_exception().
18
+F: hw/misc/tz-ppc.c
32
+ * NEWEL is for writes to registers that might change the exception
19
+F: include/hw/misc/tz-ppc.h
33
+ * level - typically on older ARM chips. For those cases we need to
20
34
+ * re-read the new el when recomputing the translation flags.
21
ARM cores
35
*/
22
M: Peter Maydell <peter.maydell@linaro.org>
36
#define ARM_CP_SPECIAL 0x0001
23
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
37
#define ARM_CP_CONST 0x0002
24
L: qemu-arm@nongnu.org
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
25
S: Maintained
39
#define ARM_CP_SVE 0x2000
26
F: hw/arm/mps2.c
40
#define ARM_CP_NO_GDB 0x4000
27
-F: hw/misc/mps2-scc.c
41
#define ARM_CP_RAISES_EXC 0x8000
28
-F: include/hw/misc/mps2-scc.h
42
+#define ARM_CP_NEWEL 0x10000
29
+F: hw/arm/mps2-tz.c
43
/* Used only as a terminator for ARMCPRegInfo lists */
30
+F: hw/misc/mps2-*.c
44
-#define ARM_CP_SENTINEL 0xffff
31
+F: include/hw/misc/mps2-*.h
45
+#define ARM_CP_SENTINEL 0xfffff
32
+F: hw/arm/iotkit.c
46
/* Mask of only the flag bits in a type field */
33
+F: include/hw/arm/iotkit.h
47
-#define ARM_CP_FLAG_MASK 0xf0ff
34
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
35
Musicpal
49
36
M: Jan Kiszka <jan.kiszka@web.de>
50
/* Valid values for ARMCPRegInfo state field, indicating which of
51
* the AArch32 and AArch64 execution states this register is visible in.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/helper.h
55
+++ b/target/arm/helper.h
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
58
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
63
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
67
+++ b/target/arm/helper.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
71
.resetvalue = 0, .writefn = scr_write },
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
75
.access = PL1_RW, .accessfn = access_trap_aa32s_el1,
76
.fieldoffset = offsetoflow32(CPUARMState, cp15.scr_el3),
77
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32)(CPUARMState *env, int el)
78
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
79
}
80
81
+/*
82
+ * If we have triggered a EL state change we can't rely on the
83
+ * translator having passed it too us, we need to recompute.
84
+ */
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
86
+{
87
+ int el = arm_current_el(env);
88
+ int fp_el = fp_exception_el(env, el);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
91
+}
92
+
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
94
{
95
int fp_el = fp_exception_el(env, el);
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate.c
99
+++ b/target/arm/translate.c
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
103
} else {
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
105
+ if (ri->type & ARM_CP_NEWEL) {
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
107
+ } else {
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
109
+ }
110
}
111
tcg_temp_free_i32(tcg_el);
112
/*
37
--
113
--
38
2.17.1
114
2.20.1
39
115
40
116
diff view generated by jsdifflib