1
First arm pullreq of 5.0!
1
Most of this is the Neon decodetree patches, followed by Edgar's versal cleanups.
2
2
3
The following changes since commit 084a398bf8aa7634738e6c6c0103236ee1b3b72f:
3
thanks
4
-- PMM
4
5
5
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging (2019-12-13 18:14:07 +0000)
6
7
The following changes since commit 2ef486e76d64436be90f7359a3071fb2a56ce835:
8
9
Merge remote-tracking branch 'remotes/marcel/tags/rdma-pull-request' into staging (2020-05-03 14:12:56 +0100)
6
10
7
are available in the Git repository at:
11
are available in the Git repository at:
8
12
9
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20191216-1
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200504
10
14
11
for you to fetch changes up to f80741d107673f162e3b097fc76a1590036cc9d1:
15
for you to fetch changes up to 9aefc6cf9b73f66062d2f914a0136756e7a28211:
12
16
13
target/arm: ensure we use current exception state after SCR update (2019-12-16 10:52:58 +0000)
17
target/arm: Move gen_ function typedefs to translate.h (2020-05-04 12:59:26 +0100)
14
18
15
----------------------------------------------------------------
19
----------------------------------------------------------------
16
target-arm queue:
20
target-arm queue:
17
* Add support for Cortex-M7 CPU
21
* Start of conversion of Neon insns to decodetree
18
* exynos4210_gic: Suppress gcc9 format-truncation warnings
22
* versal board: support SD and RTC
19
* aspeed: Various minor bug fixes and improvements
23
* Implement ARMv8.2-TTS2UXN
20
* aspeed: Add support for the tacoma-bmc board
24
* Make VQDMULL undefined when U=1
21
* Honour HCR_EL32.TID1 and .TID2 trapping requirements
25
* Some minor code cleanups
22
* Handle trapping to EL2 of AArch32 VMRS instructions
23
* Handle AArch32 CP15 trapping via HSTR_EL2
24
* Add support for missing Jazelle system registers
25
* arm/arm-powerctl: set NSACR.{CP11, CP10} bits in arm_set_cpu_on
26
* Add support for DC CVAP & DC CVADP instructions
27
* Fix assertion when SCR.NS is changed in Secure-SVC &c
28
* enable SHPC native hot plug in arm ACPI
29
26
30
----------------------------------------------------------------
27
----------------------------------------------------------------
31
Alex Bennée (1):
28
Edgar E. Iglesias (11):
32
target/arm: ensure we use current exception state after SCR update
29
hw/arm: versal: Remove inclusion of arm_gicv3_common.h
30
hw/arm: versal: Move misplaced comment
31
hw/arm: versal-virt: Fix typo xlnx-ve -> xlnx-versal
32
hw/arm: versal: Embed the UARTs into the SoC type
33
hw/arm: versal: Embed the GEMs into the SoC type
34
hw/arm: versal: Embed the ADMAs into the SoC type
35
hw/arm: versal: Embed the APUs into the SoC type
36
hw/arm: versal: Add support for SD
37
hw/arm: versal: Add support for the RTC
38
hw/arm: versal-virt: Add support for SD
39
hw/arm: versal-virt: Add support for the RTC
33
40
34
Beata Michalska (4):
41
Fredrik Strupe (1):
35
tcg: cputlb: Add probe_read
42
target/arm: Make VQDMULL undefined when U=1
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
39
43
40
Christophe Lyon (1):
44
Peter Maydell (25):
41
target/arm: Add support for cortex-m7 CPU
45
target/arm: Don't use a TLB for ARMMMUIdx_Stage2
42
46
target/arm: Use enum constant in get_phys_addr_lpae() call
43
Cédric Le Goater (12):
47
target/arm: Add new 's1_is_el0' argument to get_phys_addr_lpae()
44
aspeed/i2c: Add support for pool buffer transfers
48
target/arm: Implement ARMv8.2-TTS2UXN
45
aspeed/i2c: Check SRAM enablement on AST2500
49
target/arm: Use correct variable for setting 'max' cpu's ID_AA64DFR0
46
aspeed: Add a DRAM memory region at the SoC level
50
target/arm/translate-vfp.inc.c: Remove duplicate simd_r32 check
47
aspeed/i2c: Add support for DMA transfers
51
target/arm: Don't allow Thumb Neon insns without FEATURE_NEON
48
aspeed/i2c: Add trace events
52
target/arm: Add stubs for AArch32 Neon decodetree
49
aspeed/smc: Restore default AHB window mapping at reset
53
target/arm: Convert VCMLA (vector) to decodetree
50
aspeed/smc: Do not map disabled segment on the AST2600
54
target/arm: Convert VCADD (vector) to decodetree
51
aspeed/smc: Add AST2600 timings registers
55
target/arm: Convert V[US]DOT (vector) to decodetree
52
aspeed: Remove AspeedBoardConfig array and use AspeedMachineClass
56
target/arm: Convert VFM[AS]L (vector) to decodetree
53
aspeed: Add support for the tacoma-bmc board
57
target/arm: Convert VCMLA (scalar) to decodetree
54
aspeed: Change the "scu" property definition
58
target/arm: Convert V[US]DOT (scalar) to decodetree
55
aspeed: Change the "nic" property definition
59
target/arm: Convert VFM[AS]L (scalar) to decodetree
56
60
target/arm: Convert Neon load/store multiple structures to decodetree
57
David Gibson (1):
61
target/arm: Convert Neon 'load single structure to all lanes' to decodetree
58
exynos4210_gic: Suppress gcc9 format-truncation warnings
62
target/arm: Convert Neon 'load/store single structure' to decodetree
59
63
target/arm: Convert Neon 3-reg-same VADD/VSUB to decodetree
60
Heyi Guo (2):
64
target/arm: Convert Neon 3-reg-same logic ops to decodetree
61
hw/arm/acpi: simplify AML bit and/or statement
65
target/arm: Convert Neon 3-reg-same VMAX/VMIN to decodetree
62
hw/arm/acpi: enable SHPC native hot plug
66
target/arm: Convert Neon 3-reg-same comparisons to decodetree
63
67
target/arm: Convert Neon 3-reg-same VQADD/VQSUB to decodetree
64
Joel Stanley (4):
68
target/arm: Convert Neon 3-reg-same VMUL, VMLA, VMLS, VSHL to decodetree
65
aspeed/sdmc: Make ast2600 default 1G
69
target/arm: Move gen_ function typedefs to translate.h
66
aspeed/scu: Fix W1C behavior
67
watchdog/aspeed: Improve watchdog timeout message
68
watchdog/aspeed: Fix AST2600 frequency behaviour
69
70
Marc Zyngier (5):
71
target/arm: Honor HCR_EL2.TID2 trapping requirements
72
target/arm: Honor HCR_EL2.TID1 trapping requirements
73
target/arm: Handle trapping to EL2 of AArch32 VMRS instructions
74
target/arm: Handle AArch32 CP15 trapping via HSTR_EL2
75
target/arm: Add support for missing Jazelle system registers
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
70
83
Philippe Mathieu-Daudé (2):
71
Philippe Mathieu-Daudé (2):
84
hw/arm/sbsa-ref: Simplify by moving the gic in the machine state
72
hw/arm/mps2-tz: Use TYPE_IOTKIT instead of hardcoded string
85
hw/arm/virt: Simplify by moving the gic in the machine state
73
target/arm: Use uint64_t for midr field in CPU state struct
86
74
87
include/exec/exec-all.h | 6 +
75
include/hw/arm/xlnx-versal.h | 31 +-
88
include/exec/memory.h | 6 +
76
target/arm/cpu-param.h | 2 +-
89
include/exec/ram_addr.h | 8 +
77
target/arm/cpu.h | 38 ++-
90
include/hw/arm/aspeed.h | 24 +--
78
target/arm/translate-a64.h | 9 -
91
include/hw/arm/aspeed_soc.h | 1 +
79
target/arm/translate.h | 26 ++
92
include/hw/arm/virt.h | 1 +
80
target/arm/neon-dp.decode | 86 +++++
93
include/hw/i2c/aspeed_i2c.h | 16 ++
81
target/arm/neon-ls.decode | 52 +++
94
include/hw/ssi/aspeed_smc.h | 1 +
82
target/arm/neon-shared.decode | 66 ++++
95
include/hw/watchdog/wdt_aspeed.h | 1 +
83
hw/arm/mps2-tz.c | 2 +-
96
include/qemu/cutils.h | 1 +
84
hw/arm/xlnx-versal-virt.c | 74 ++++-
97
target/arm/cpu.h | 20 +-
85
hw/arm/xlnx-versal.c | 115 +++++--
98
target/arm/helper.h | 3 +
86
target/arm/cpu.c | 3 +-
99
target/arm/translate.h | 2 +
87
target/arm/cpu64.c | 8 +-
100
exec.c | 36 ++++
88
target/arm/helper.c | 183 ++++------
101
hw/arm/aspeed.c | 271 +++++++++++++----------
89
target/arm/translate-a64.c | 17 -
102
hw/arm/aspeed_ast2600.c | 25 ++-
90
target/arm/translate-neon.inc.c | 714 +++++++++++++++++++++++++++++++++++++++
103
hw/arm/aspeed_soc.c | 22 +-
91
target/arm/translate-vfp.inc.c | 6 -
104
hw/arm/sbsa-ref.c | 86 ++++----
92
target/arm/translate.c | 716 +++-------------------------------------
105
hw/arm/virt-acpi-build.c | 21 +-
93
target/arm/Makefile.objs | 18 +
106
hw/arm/virt.c | 109 +++++-----
94
19 files changed, 1302 insertions(+), 864 deletions(-)
107
hw/gpio/aspeed_gpio.c | 1 +
95
create mode 100644 target/arm/neon-dp.decode
108
hw/i2c/aspeed_i2c.c | 439 +++++++++++++++++++++++++++++++++++---
96
create mode 100644 target/arm/neon-ls.decode
109
hw/intc/exynos4210_gic.c | 9 +-
97
create mode 100644 target/arm/neon-shared.decode
110
hw/misc/aspeed_scu.c | 19 +-
98
create mode 100644 target/arm/translate-neon.inc.c
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
99
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Fredrik Strupe <fredrik@strupe.net>
2
2
3
This change ensures that the FPU can be accessed in Non-Secure mode
3
According to Arm ARM, VQDMULL is only valid when U=0, while having
4
when the CPU core is reset using the arm_set_cpu_on() function call.
4
U=1 is unallocated.
5
The NSACR.{CP11,CP10} bits define the exception level required to
6
access the FPU in Non-Secure mode. Without these bits set, the CPU
7
will give an undefined exception trap on the first FPU access for the
8
secondary cores under Linux.
9
5
10
This is necessary because in this power-control codepath QEMU
6
Signed-off-by: Fredrik Strupe <fredrik@strupe.net>
11
is effectively emulating a bit of EL3 firmware, and has to set
7
Fixes: 695272dcb976 ("target-arm: Handle UNDEF cases for Neon 3-regs-different-widths")
12
the CPU up as the EL3 firmware would.
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]
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
target/arm/arm-powerctl.c | 3 +++
11
target/arm/translate.c | 2 +-
22
1 file changed, 3 insertions(+)
12
1 file changed, 1 insertion(+), 1 deletion(-)
23
13
24
diff --git a/target/arm/arm-powerctl.c b/target/arm/arm-powerctl.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/arm-powerctl.c
16
--- a/target/arm/translate.c
27
+++ b/target/arm/arm-powerctl.c
17
+++ b/target/arm/translate.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_set_cpu_on_async_work(CPUState *target_cpu_state,
18
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
29
/* Processor is not in secure mode */
19
{0, 0, 0, 0}, /* VMLSL */
30
target_cpu->env.cp15.scr_el3 |= SCR_NS;
20
{0, 0, 0, 9}, /* VQDMLSL */
31
21
{0, 0, 0, 0}, /* Integer VMULL */
32
+ /* Set NSACR.{CP11,CP10} so NS can access the FPU */
22
- {0, 0, 0, 1}, /* VQDMULL */
33
+ target_cpu->env.cp15.nsacr |= 3 << 10;
23
+ {0, 0, 0, 9}, /* VQDMULL */
34
+
24
{0, 0, 0, 0xa}, /* Polynomial VMULL */
35
/*
25
{0, 0, 0, 7}, /* Reserved: always UNDEF */
36
* If QEMU is providing the equivalent of EL3 firmware, then we need
26
};
37
* to make sure a CPU targeting EL2 comes out of reset with a
38
--
27
--
39
2.20.1
28
2.20.1
40
29
41
30
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Switch to ram block writeback for pmem migration.
3
By using the TYPE_* definitions for devices, we can:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
4
6
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200428154650.21991-1-f4bug@amsat.org
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 20191121000843.24844-4-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
---
11
---
12
migration/ram.c | 5 +----
12
hw/arm/mps2-tz.c | 2 +-
13
1 file changed, 1 insertion(+), 4 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/migration/ram.c b/migration/ram.c
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/migration/ram.c
17
--- a/hw/arm/mps2-tz.c
18
+++ b/migration/ram.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
#include "qemu/bitops.h"
20
exit(EXIT_FAILURE);
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);
35
}
21
}
36
22
37
xbzrle_load_cleanup();
23
- sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
24
+ sysbus_init_child_obj(OBJECT(machine), TYPE_IOTKIT, &mms->iotkit,
25
sizeof(mms->iotkit), mmc->armsse_type);
26
iotkitdev = DEVICE(&mms->iotkit);
27
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
38
--
28
--
39
2.20.1
29
2.20.1
40
30
41
31
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
We define ARMMMUIdx_Stage2 as being an MMU index which uses a QEMU
2
2
TLB. However we never actually use the TLB -- all stage 2 lookups
3
A write to the SCR can change the effective EL by droppping the system
3
are done by direct calls to get_phys_addr_lpae() followed by a
4
from secure to non-secure mode. However if we use a cached current_el
4
physical address load via address_space_ld*().
5
from before the change we'll rebuild the flags incorrectly. To fix
5
6
this we introduce the ARM_CP_NEWEL CP flag to indicate the new EL
6
Remove Stage2 from the list of ARM MMU indexes which correspond to
7
should be used when recomputing the flags.
7
real core MMU indexes, and instead put it in the set of "NOTLB" ARM
8
8
MMU indexes.
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
10
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
This allows us to drop NB_MMU_MODES to 11. It also means we can
11
safely add support for the ARMv8.3-TTS2UXN extension, which adds
12
permission bits to the stage 2 descriptors which define execute
13
permission separatel for EL0 and EL1; supporting that while keeping
14
Stage2 in a QEMU TLB would require us to use separate TLBs for
15
"Stage2 for an EL0 access" and "Stage2 for an EL1 access", which is a
16
lot of extra complication given we aren't even using the QEMU TLB.
17
18
In the process of updating the comment on our MMU index use,
19
fix a couple of other minor errors:
20
* NS EL2 EL2&0 was missing from the list in the comment
21
* some text hadn't been updated from when we bumped NB_MMU_MODES
22
above 8
23
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20191212114734.6962-1-alex.bennee@linaro.org
27
Message-id: 20200330210400.11724-2-peter.maydell@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
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
28
---
18
target/arm/cpu.h | 8 ++++++--
29
target/arm/cpu-param.h | 2 +-
19
target/arm/helper.h | 1 +
30
target/arm/cpu.h | 21 +++++---
20
target/arm/helper.c | 14 +++++++++++++-
31
target/arm/helper.c | 112 ++++-------------------------------------
21
target/arm/translate.c | 6 +++++-
32
3 files changed, 27 insertions(+), 108 deletions(-)
22
4 files changed, 25 insertions(+), 4 deletions(-)
33
23
34
diff --git a/target/arm/cpu-param.h b/target/arm/cpu-param.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/cpu-param.h
37
+++ b/target/arm/cpu-param.h
38
@@ -XXX,XX +XXX,XX @@
39
# define TARGET_PAGE_BITS_MIN 10
40
#endif
41
42
-#define NB_MMU_MODES 12
43
+#define NB_MMU_MODES 11
44
45
#endif
24
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
46
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
25
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.h
48
--- a/target/arm/cpu.h
27
+++ b/target/arm/cpu.h
49
+++ b/target/arm/cpu.h
28
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
50
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
29
* RAISES_EXC is for when the read or write hook might raise an exception;
51
* handling via the TLB. The only way to do a stage 1 translation without
30
* the generated code will synchronize the CPU state before calling the hook
52
* the immediate stage 2 translation is via the ATS or AT system insns,
31
* so that it is safe for the hook to call raise_exception().
53
* which can be slow-pathed and always do a page table walk.
32
+ * NEWEL is for writes to registers that might change the exception
54
+ * The only use of stage 2 translations is either as part of an s1+2
33
+ * level - typically on older ARM chips. For those cases we need to
55
+ * lookup or when loading the descriptors during a stage 1 page table walk,
34
+ * re-read the new el when recomputing the translation flags.
56
+ * and in both those cases we don't use the TLB.
35
*/
57
* 4. we can also safely fold together the "32 bit EL3" and "64 bit EL3"
36
#define ARM_CP_SPECIAL 0x0001
58
* translation regimes, because they map reasonably well to each other
37
#define ARM_CP_CONST 0x0002
59
* and they can't both be active at the same time.
38
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
60
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
39
#define ARM_CP_SVE 0x2000
61
* NS EL1 EL1&0 stage 1+2 (aka NS PL1)
40
#define ARM_CP_NO_GDB 0x4000
62
* NS EL1 EL1&0 stage 1+2 +PAN
41
#define ARM_CP_RAISES_EXC 0x8000
63
* NS EL0 EL2&0
42
+#define ARM_CP_NEWEL 0x10000
64
+ * NS EL2 EL2&0
43
/* Used only as a terminator for ARMCPRegInfo lists */
65
* NS EL2 EL2&0 +PAN
44
-#define ARM_CP_SENTINEL 0xffff
66
* NS EL2 (aka NS PL2)
45
+#define ARM_CP_SENTINEL 0xfffff
67
* S EL0 EL1&0 (aka S PL0)
46
/* Mask of only the flag bits in a type field */
68
* S EL1 EL1&0 (not used if EL3 is 32 bit)
47
-#define ARM_CP_FLAG_MASK 0xf0ff
69
* S EL1 EL1&0 +PAN
48
+#define ARM_CP_FLAG_MASK 0x1f0ff
70
* S EL3 (aka S PL1)
49
71
- * NS EL1&0 stage 2
50
/* Valid values for ARMCPRegInfo state field, indicating which of
72
*
51
* the AArch32 and AArch64 execution states this register is visible in.
73
- * for a total of 12 different mmu_idx.
52
diff --git a/target/arm/helper.h b/target/arm/helper.h
74
+ * for a total of 11 different mmu_idx.
53
index XXXXXXX..XXXXXXX 100644
75
*
54
--- a/target/arm/helper.h
76
* R profile CPUs have an MPU, but can use the same set of MMU indexes
55
+++ b/target/arm/helper.h
77
* as A profile. They only need to distinguish NS EL0 and NS EL1 (and
56
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_user_reg, i32, env, i32)
78
@@ -XXX,XX +XXX,XX @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_sync);
57
DEF_HELPER_3(set_user_reg, void, env, i32, i32)
79
* are not quite the same -- different CPU types (most notably M profile
58
80
* vs A/R profile) would like to use MMU indexes with different semantics,
59
DEF_HELPER_FLAGS_2(rebuild_hflags_m32, TCG_CALL_NO_RWG, void, env, int)
81
* but since we don't ever need to use all of those in a single CPU we
60
+DEF_HELPER_FLAGS_1(rebuild_hflags_a32_newel, TCG_CALL_NO_RWG, void, env)
82
- * can avoid setting NB_MMU_MODES to more than 8. The lower bits of
61
DEF_HELPER_FLAGS_2(rebuild_hflags_a32, TCG_CALL_NO_RWG, void, env, int)
83
+ * can avoid having to set NB_MMU_MODES to "total number of A profile MMU
62
DEF_HELPER_FLAGS_2(rebuild_hflags_a64, TCG_CALL_NO_RWG, void, env, int)
84
+ * modes + total number of M profile MMU modes". The lower bits of
63
85
* ARMMMUIdx are the core TLB mmu index, and the higher bits are always
86
* the same for any particular CPU.
87
* Variables of type ARMMUIdx are always full values, and the core
88
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
89
ARMMMUIdx_SE10_1_PAN = 9 | ARM_MMU_IDX_A,
90
ARMMMUIdx_SE3 = 10 | ARM_MMU_IDX_A,
91
92
- ARMMMUIdx_Stage2 = 11 | ARM_MMU_IDX_A,
93
-
94
/*
95
* These are not allocated TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
98
ARMMMUIdx_Stage1_E0 = 0 | ARM_MMU_IDX_NOTLB,
99
ARMMMUIdx_Stage1_E1 = 1 | ARM_MMU_IDX_NOTLB,
100
ARMMMUIdx_Stage1_E1_PAN = 2 | ARM_MMU_IDX_NOTLB,
101
+ /*
102
+ * Not allocated a TLB: used only for second stage of an S12 page
103
+ * table walk, or for descriptor loads during first stage of an S1
104
+ * page table walk. Note that if we ever want to have a TLB for this
105
+ * then various TLB flush insns which currently are no-ops or flush
106
+ * only stage 1 MMU indexes will need to change to flush stage 2.
107
+ */
108
+ ARMMMUIdx_Stage2 = 3 | ARM_MMU_IDX_NOTLB,
109
110
/*
111
* M-profile.
112
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
113
TO_CORE_BIT(SE10_1),
114
TO_CORE_BIT(SE10_1_PAN),
115
TO_CORE_BIT(SE3),
116
- TO_CORE_BIT(Stage2),
117
118
TO_CORE_BIT(MUser),
119
TO_CORE_BIT(MPriv),
64
diff --git a/target/arm/helper.c b/target/arm/helper.c
120
diff --git a/target/arm/helper.c b/target/arm/helper.c
65
index XXXXXXX..XXXXXXX 100644
121
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/helper.c
122
--- a/target/arm/helper.c
67
+++ b/target/arm/helper.c
123
+++ b/target/arm/helper.c
68
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_cp_reginfo[] = {
124
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_write(CPUARMState *env, const ARMCPRegInfo *ri,
69
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 1, .opc2 = 0,
125
tlb_flush_by_mmuidx(cs,
70
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.scr_el3),
126
ARMMMUIdxBit_E10_1 |
71
.resetvalue = 0, .writefn = scr_write },
127
ARMMMUIdxBit_E10_1_PAN |
72
- { .name = "SCR", .type = ARM_CP_ALIAS,
128
- ARMMMUIdxBit_E10_0 |
73
+ { .name = "SCR", .type = ARM_CP_ALIAS | ARM_CP_NEWEL,
129
- ARMMMUIdxBit_Stage2);
74
.cp = 15, .opc1 = 0, .crn = 1, .crm = 1, .opc2 = 0,
130
+ ARMMMUIdxBit_E10_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
}
131
}
80
132
81
+/*
133
static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
82
+ * If we have triggered a EL state change we can't rely on the
134
@@ -XXX,XX +XXX,XX @@ static void tlbiall_nsnh_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
83
+ * translator having passed it too us, we need to recompute.
135
tlb_flush_by_mmuidx_all_cpus_synced(cs,
84
+ */
136
ARMMMUIdxBit_E10_1 |
85
+void HELPER(rebuild_hflags_a32_newel)(CPUARMState *env)
137
ARMMMUIdxBit_E10_1_PAN |
86
+{
138
- ARMMMUIdxBit_E10_0 |
87
+ int el = arm_current_el(env);
139
- ARMMMUIdxBit_Stage2);
88
+ int fp_el = fp_exception_el(env, el);
140
+ ARMMMUIdxBit_E10_0);
89
+ ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
141
}
90
+ env->hflags = rebuild_hflags_a32(env, fp_el, mmu_idx);
142
91
+}
143
-static void tlbiipas2_write(CPUARMState *env, const ARMCPRegInfo *ri,
92
+
144
- uint64_t value)
93
void HELPER(rebuild_hflags_a32)(CPUARMState *env, int el)
145
-{
146
- /* Invalidate by IPA. This has to invalidate any structures that
147
- * contain only stage 2 translation information, but does not need
148
- * to apply to structures that contain combined stage 1 and stage 2
149
- * translation information.
150
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
151
- */
152
- CPUState *cs = env_cpu(env);
153
- uint64_t pageaddr;
154
-
155
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
156
- return;
157
- }
158
-
159
- pageaddr = sextract64(value << 12, 0, 40);
160
-
161
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
162
-}
163
-
164
-static void tlbiipas2_is_write(CPUARMState *env, const ARMCPRegInfo *ri,
165
- uint64_t value)
166
-{
167
- CPUState *cs = env_cpu(env);
168
- uint64_t pageaddr;
169
-
170
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
171
- return;
172
- }
173
-
174
- pageaddr = sextract64(value << 12, 0, 40);
175
-
176
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
177
- ARMMMUIdxBit_Stage2);
178
-}
179
180
static void tlbiall_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
uint64_t value)
182
@@ -XXX,XX +XXX,XX @@ static void vttbr_write(CPUARMState *env, const ARMCPRegInfo *ri,
183
tlb_flush_by_mmuidx(cs,
184
ARMMMUIdxBit_E10_1 |
185
ARMMMUIdxBit_E10_1_PAN |
186
- ARMMMUIdxBit_E10_0 |
187
- ARMMMUIdxBit_Stage2);
188
+ ARMMMUIdxBit_E10_0);
189
raw_write(env, ri, value);
190
}
191
}
192
@@ -XXX,XX +XXX,XX @@ static int alle1_tlbmask(CPUARMState *env)
193
return ARMMMUIdxBit_SE10_1 |
194
ARMMMUIdxBit_SE10_1_PAN |
195
ARMMMUIdxBit_SE10_0;
196
- } else if (arm_feature(env, ARM_FEATURE_EL2)) {
197
- return ARMMMUIdxBit_E10_1 |
198
- ARMMMUIdxBit_E10_1_PAN |
199
- ARMMMUIdxBit_E10_0 |
200
- ARMMMUIdxBit_Stage2;
201
} else {
202
return ARMMMUIdxBit_E10_1 |
203
ARMMMUIdxBit_E10_1_PAN |
204
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
205
ARMMMUIdxBit_SE3);
206
}
207
208
-static void tlbi_aa64_ipas2e1_write(CPUARMState *env, const ARMCPRegInfo *ri,
209
- uint64_t value)
210
-{
211
- /* Invalidate by IPA. This has to invalidate any structures that
212
- * contain only stage 2 translation information, but does not need
213
- * to apply to structures that contain combined stage 1 and stage 2
214
- * translation information.
215
- * This must NOP if EL2 isn't implemented or SCR_EL3.NS is zero.
216
- */
217
- ARMCPU *cpu = env_archcpu(env);
218
- CPUState *cs = CPU(cpu);
219
- uint64_t pageaddr;
220
-
221
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
222
- return;
223
- }
224
-
225
- pageaddr = sextract64(value << 12, 0, 48);
226
-
227
- tlb_flush_page_by_mmuidx(cs, pageaddr, ARMMMUIdxBit_Stage2);
228
-}
229
-
230
-static void tlbi_aa64_ipas2e1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
231
- uint64_t value)
232
-{
233
- CPUState *cs = env_cpu(env);
234
- uint64_t pageaddr;
235
-
236
- if (!arm_feature(env, ARM_FEATURE_EL2) || !(env->cp15.scr_el3 & SCR_NS)) {
237
- return;
238
- }
239
-
240
- pageaddr = sextract64(value << 12, 0, 48);
241
-
242
- tlb_flush_page_by_mmuidx_all_cpus_synced(cs, pageaddr,
243
- ARMMMUIdxBit_Stage2);
244
-}
245
-
246
static CPAccessResult aa64_zva_access(CPUARMState *env, const ARMCPRegInfo *ri,
247
bool isread)
94
{
248
{
95
int fp_el = fp_exception_el(env, el);
249
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
250
.writefn = tlbi_aa64_vae1_write },
97
index XXXXXXX..XXXXXXX 100644
251
{ .name = "TLBI_IPAS2E1IS", .state = ARM_CP_STATE_AA64,
98
--- a/target/arm/translate.c
252
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
99
+++ b/target/arm/translate.c
253
- .access = PL2_W, .type = ARM_CP_NO_RAW,
100
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
254
- .writefn = tlbi_aa64_ipas2e1is_write },
101
if (arm_dc_feature(s, ARM_FEATURE_M)) {
255
+ .access = PL2_W, .type = ARM_CP_NOP },
102
gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
256
{ .name = "TLBI_IPAS2LE1IS", .state = ARM_CP_STATE_AA64,
103
} else {
257
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
104
- gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
258
- .access = PL2_W, .type = ARM_CP_NO_RAW,
105
+ if (ri->type & ARM_CP_NEWEL) {
259
- .writefn = tlbi_aa64_ipas2e1is_write },
106
+ gen_helper_rebuild_hflags_a32_newel(cpu_env);
260
+ .access = PL2_W, .type = ARM_CP_NOP },
107
+ } else {
261
{ .name = "TLBI_ALLE1IS", .state = ARM_CP_STATE_AA64,
108
+ gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
262
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 3, .opc2 = 4,
109
+ }
263
.access = PL2_W, .type = ARM_CP_NO_RAW,
110
}
264
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
111
tcg_temp_free_i32(tcg_el);
265
.writefn = tlbi_aa64_alle1is_write },
112
/*
266
{ .name = "TLBI_IPAS2E1", .state = ARM_CP_STATE_AA64,
267
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
268
- .access = PL2_W, .type = ARM_CP_NO_RAW,
269
- .writefn = tlbi_aa64_ipas2e1_write },
270
+ .access = PL2_W, .type = ARM_CP_NOP },
271
{ .name = "TLBI_IPAS2LE1", .state = ARM_CP_STATE_AA64,
272
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
273
- .access = PL2_W, .type = ARM_CP_NO_RAW,
274
- .writefn = tlbi_aa64_ipas2e1_write },
275
+ .access = PL2_W, .type = ARM_CP_NOP },
276
{ .name = "TLBI_ALLE1", .state = ARM_CP_STATE_AA64,
277
.opc0 = 1, .opc1 = 4, .crn = 8, .crm = 7, .opc2 = 4,
278
.access = PL2_W, .type = ARM_CP_NO_RAW,
279
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
280
.writefn = tlbimva_hyp_is_write },
281
{ .name = "TLBIIPAS2",
282
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 1,
283
- .type = ARM_CP_NO_RAW, .access = PL2_W,
284
- .writefn = tlbiipas2_write },
285
+ .type = ARM_CP_NOP, .access = PL2_W },
286
{ .name = "TLBIIPAS2IS",
287
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 1,
288
- .type = ARM_CP_NO_RAW, .access = PL2_W,
289
- .writefn = tlbiipas2_is_write },
290
+ .type = ARM_CP_NOP, .access = PL2_W },
291
{ .name = "TLBIIPAS2L",
292
.cp = 15, .opc1 = 4, .crn = 8, .crm = 4, .opc2 = 5,
293
- .type = ARM_CP_NO_RAW, .access = PL2_W,
294
- .writefn = tlbiipas2_write },
295
+ .type = ARM_CP_NOP, .access = PL2_W },
296
{ .name = "TLBIIPAS2LIS",
297
.cp = 15, .opc1 = 4, .crn = 8, .crm = 0, .opc2 = 5,
298
- .type = ARM_CP_NO_RAW, .access = PL2_W,
299
- .writefn = tlbiipas2_is_write },
300
+ .type = ARM_CP_NOP, .access = PL2_W },
301
/* 32 bit cache operations */
302
{ .name = "ICIALLUIS", .cp = 15, .opc1 = 0, .crn = 7, .crm = 1, .opc2 = 0,
303
.type = ARM_CP_NOP, .access = PL1_W, .accessfn = aa64_cacheop_pou_access },
113
--
304
--
114
2.20.1
305
2.20.1
115
306
116
307
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
The access_type argument to get_phys_addr_lpae() is an MMUAccessType;
2
use the enum constant MMU_DATA_LOAD rather than a literal 0 when we
3
call it in S1_ptw_translate().
2
4
3
QEMU lacks the minimum Jazelle implementation that is required
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
by the architecture (everything is RAZ or RAZ/WI). Add it
5
together with the HCR_EL2.TID0 trapping that goes with it.
6
7
Signed-off-by: Marc Zyngier <maz@kernel.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20191201122018.25808-6-maz@kernel.org
8
Message-id: 20200330210400.11724-3-peter.maydell@linaro.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]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
9
---
17
target/arm/helper.c | 27 +++++++++++++++++++++++++++
10
target/arm/helper.c | 5 +++--
18
1 file changed, 27 insertions(+)
11
1 file changed, 3 insertions(+), 2 deletions(-)
19
12
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
15
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
16
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_aa32_tid3(CPUARMState *env, const ARMCPRegInfo *ri,
17
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
25
return CP_ACCESS_OK;
18
pcacheattrs = &cacheattrs;
26
}
19
}
27
20
28
+static CPAccessResult access_jazelle(CPUARMState *env, const ARMCPRegInfo *ri,
21
- ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_Stage2, &s2pa,
29
+ bool isread)
22
- &txattrs, &s2prot, &s2size, fi, pcacheattrs);
30
+{
23
+ ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID0)) {
24
+ &s2pa, &txattrs, &s2prot, &s2size, fi,
32
+ return CP_ACCESS_TRAP_EL2;
25
+ pcacheattrs);
33
+ }
26
if (ret) {
34
+
27
assert(fi->type != ARMFault_None);
35
+ return CP_ACCESS_OK;
28
fi->s2addr = addr;
36
+}
37
+
38
+static const ARMCPRegInfo jazelle_regs[] = {
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)
53
{
54
/* Register all the coprocessor registers based on feature bits */
55
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
if (arm_feature(env, ARM_FEATURE_LPAE)) {
57
define_arm_cp_regs(cpu, lpae_cp_reginfo);
58
}
59
+ if (cpu_isar_feature(jazelle, cpu)) {
60
+ define_arm_cp_regs(cpu, jazelle_regs);
61
+ }
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).
65
--
29
--
66
2.20.1
30
2.20.1
67
31
68
32
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
For ARMv8.2-TTS2UXN, the stage 2 page table walk wants to know
2
whether the stage 1 access is for EL0 or not, because whether
3
exec permission is given can depend on whether this is an EL0
4
or EL1 access. Add a new argument to get_phys_addr_lpae() so
5
the call sites can pass this information in.
2
6
3
HCR_EL2.TID2 mandates that access from EL1 to CTR_EL0, CCSIDR_EL1,
7
Since get_phys_addr_lpae() doesn't already have a doc comment,
4
CCSIDR2_EL1, CLIDR_EL1, CSSELR_EL1 are trapped to EL2, and QEMU
8
add one so we have a place to put the documentation of the
5
completely ignores it, making it impossible for hypervisors to
9
semantics of the new s1_is_el0 argument.
6
virtualize the cache hierarchy.
7
10
8
Do the right thing by trapping to EL2 if HCR_EL2.TID2 is set.
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
10
Signed-off-by: Marc Zyngier <maz@kernel.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20191201122018.25808-2-maz@kernel.org
14
Message-id: 20200330210400.11724-4-peter.maydell@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
15
---
16
target/arm/helper.c | 31 +++++++++++++++++++++++++++----
16
target/arm/helper.c | 29 ++++++++++++++++++++++++++++-
17
1 file changed, 27 insertions(+), 4 deletions(-)
17
1 file changed, 28 insertions(+), 1 deletion(-)
18
18
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
23
@@ -XXX,XX +XXX,XX @@
24
raw_write(env, ri, value);
24
25
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
27
+ bool s1_is_el0,
28
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
29
target_ulong *page_size_ptr,
30
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
31
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
32
}
33
34
ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, ARMMMUIdx_Stage2,
35
+ false,
36
&s2pa, &txattrs, &s2prot, &s2size, fi,
37
pcacheattrs);
38
if (ret) {
39
@@ -XXX,XX +XXX,XX @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
40
};
25
}
41
}
26
42
27
+static CPAccessResult access_aa64_tid2(CPUARMState *env,
43
+/**
28
+ const ARMCPRegInfo *ri,
44
+ * get_phys_addr_lpae: perform one stage of page table walk, LPAE format
29
+ bool isread)
45
+ *
30
+{
46
+ * Returns false if the translation was successful. Otherwise, phys_ptr, attrs,
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID2)) {
47
+ * prot and page_size may not be filled in, and the populated fsr value provides
32
+ return CP_ACCESS_TRAP_EL2;
48
+ * information on why the translation aborted, in the format of a long-format
33
+ }
49
+ * DFSR/IFSR fault register, with the following caveats:
34
+
50
+ * * the WnR bit is never set (the caller must do this).
35
+ return CP_ACCESS_OK;
51
+ *
36
+}
52
+ * @env: CPUARMState
37
+
53
+ * @address: virtual address to get physical address for
38
static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
54
+ * @access_type: MMU_DATA_LOAD, MMU_DATA_STORE or MMU_INST_FETCH
39
{
55
+ * @mmu_idx: MMU index indicating required translation regime
40
ARMCPU *cpu = env_archcpu(env);
56
+ * @s1_is_el0: if @mmu_idx is ARMMMUIdx_Stage2 (so this is a stage 2 page table
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
57
+ * walk), must be true if this is stage 2 of a stage 1+2 walk for an
42
.writefn = pmintenclr_write },
58
+ * EL0 access). If @mmu_idx is anything else, @s1_is_el0 is ignored.
43
{ .name = "CCSIDR", .state = ARM_CP_STATE_BOTH,
59
+ * @phys_ptr: set to the physical address corresponding to the virtual address
44
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 0,
60
+ * @attrs: set to the memory transaction attributes to use
45
- .access = PL1_R, .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
61
+ * @prot: set to the permissions for the page containing phys_ptr
46
+ .access = PL1_R,
62
+ * @page_size_ptr: set to the size of the page containing phys_ptr
47
+ .accessfn = access_aa64_tid2,
63
+ * @fi: set to fault info if the translation fails
48
+ .readfn = ccsidr_read, .type = ARM_CP_NO_RAW },
64
+ * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
49
{ .name = "CSSELR", .state = ARM_CP_STATE_BOTH,
65
+ */
50
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 2, .opc2 = 0,
66
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
51
- .access = PL1_RW, .writefn = csselr_write, .resetvalue = 0,
67
MMUAccessType access_type, ARMMMUIdx mmu_idx,
52
+ .access = PL1_RW,
68
+ bool s1_is_el0,
53
+ .accessfn = access_aa64_tid2,
69
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
54
+ .writefn = csselr_write, .resetvalue = 0,
70
target_ulong *page_size_ptr,
55
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
71
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
56
offsetof(CPUARMState, cp15.csselr_ns) } },
72
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
57
/* Auxiliary ID register: this actually has an IMPDEF value but for now
73
58
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ctr_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
74
/* S1 is done. Now do S2 translation. */
59
if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UCT)) {
75
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_Stage2,
60
return CP_ACCESS_TRAP;
76
+ mmu_idx == ARMMMUIdx_E10_0,
77
phys_ptr, attrs, &s2_prot,
78
page_size, fi,
79
cacheattrs != NULL ? &cacheattrs2 : NULL);
80
@@ -XXX,XX +XXX,XX @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
61
}
81
}
62
+
82
63
+ if (arm_current_el(env) < 2 && arm_hcr_el2_eff(env) & HCR_TID2) {
83
if (regime_using_lpae_format(env, mmu_idx)) {
64
+ return CP_ACCESS_TRAP_EL2;
84
- return get_phys_addr_lpae(env, address, access_type, mmu_idx,
65
+ }
85
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
66
+
86
phys_ptr, attrs, prot, page_size,
67
return CP_ACCESS_OK;
87
fi, cacheattrs);
68
}
88
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
69
70
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
71
ARMCPRegInfo clidr = {
72
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
73
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
74
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->clidr
75
+ .access = PL1_R, .type = ARM_CP_CONST,
76
+ .accessfn = access_aa64_tid2,
77
+ .resetvalue = cpu->clidr
78
};
79
define_one_arm_cp_reg(cpu, &clidr);
80
define_arm_cp_regs(cpu, v7_cp_reginfo);
81
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
82
/* These are common to v8 and pre-v8 */
83
{ .name = "CTR",
84
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 1,
85
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
86
+ .access = PL1_R, .accessfn = ctr_el0_access,
87
+ .type = ARM_CP_CONST, .resetvalue = cpu->ctr },
88
{ .name = "CTR_EL0", .state = ARM_CP_STATE_AA64,
89
.opc0 = 3, .opc1 = 3, .opc2 = 1, .crn = 0, .crm = 0,
90
.access = PL0_R, .accessfn = ctr_el0_access,
91
--
89
--
92
2.20.1
90
2.20.1
93
91
94
92
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
The ARMv8.2-TTS2UXN feature extends the XN field in stage 2
2
translation table descriptors from just bit [54] to bits [54:53],
3
allowing stage 2 to control execution permissions separately for EL0
4
and EL1. Implement the new semantics of the XN field and enable
5
the feature for our 'max' CPU.
2
6
3
ARMv8.2 introduced support for Data Cache Clean instructions
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to PoP (point-of-persistence) - DC CVAP and PoDP (point-of-deep-persistence)
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191121000843.24844-5-beata.michalska@linaro.org
10
Message-id: 20200330210400.11724-5-peter.maydell@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
target/arm/cpu.h | 10 ++++++++
12
target/arm/cpu.h | 15 +++++++++++++++
18
linux-user/elfload.c | 2 ++
13
target/arm/cpu.c | 1 +
19
target/arm/cpu64.c | 1 +
14
target/arm/cpu64.c | 2 ++
20
target/arm/helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++------
21
4 files changed, 69 insertions(+)
16
4 files changed, 49 insertions(+), 6 deletions(-)
22
17
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
20
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
22
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
28
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
23
return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
29
}
24
}
30
25
31
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
26
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
32
+{
27
+{
33
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
28
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
34
+}
29
+}
35
+
30
+
36
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
31
/*
32
* 64-bit feature tests via id registers.
33
*/
34
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
35
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
36
}
37
38
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
37
+{
39
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
40
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
39
+}
41
+}
40
+
42
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
43
/*
42
{
44
* Feature tests for "does this exist in either 32-bit or 64-bit?"
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
45
*/
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
46
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
47
return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
48
}
49
50
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
51
+{
52
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
53
+}
54
+
55
/*
56
* Forward to the above feature tests given an ARMCPU pointer.
57
*/
58
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
60
--- a/target/arm/cpu.c
47
+++ b/linux-user/elfload.c
61
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
62
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
49
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
63
t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */
50
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
64
t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
51
GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
65
t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* TTCNP */
52
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
66
+ t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* TTS2UXN */
53
67
cpu->isar.id_mmfr4 = t;
54
return hwcaps;
68
}
55
}
69
#endif
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
70
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
72
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
73
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
74
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
cpu->isar.id_aa64isar0 = t;
75
t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
70
76
t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2); /* ATS1E1 */
71
t = cpu->isar.id_aa64isar1;
77
t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2); /* VMID16 */
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
78
+ t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1); /* TTS2UXN */
73
t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
79
cpu->isar.id_aa64mmfr1 = t;
74
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
80
75
t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
81
t = cpu->isar.id_aa64mmfr2;
82
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
83
u = FIELD_DP32(u, ID_MMFR4, HPDS, 1); /* AA32HPD */
84
u = FIELD_DP32(u, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
85
u = FIELD_DP32(u, ID_MMFR4, CNP, 1); /* TTCNP */
86
+ u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
87
cpu->isar.id_mmfr4 = u;
88
89
u = cpu->isar.id_aa64dfr0;
76
diff --git a/target/arm/helper.c b/target/arm/helper.c
90
diff --git a/target/arm/helper.c b/target/arm/helper.c
77
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/helper.c
92
--- a/target/arm/helper.c
79
+++ b/target/arm/helper.c
93
+++ b/target/arm/helper.c
80
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo rndr_reginfo[] = {
94
@@ -XXX,XX +XXX,XX @@ simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
81
.access = PL0_R, .readfn = rndr_readfn },
95
*
82
REGINFO_SENTINEL
96
* @env: CPUARMState
83
};
97
* @s2ap: The 2-bit stage2 access permissions (S2AP)
98
- * @xn: XN (execute-never) bit
99
+ * @xn: XN (execute-never) bits
100
+ * @s1_is_el0: true if this is S2 of an S1+2 walk for EL0
101
*/
102
-static int get_S2prot(CPUARMState *env, int s2ap, int xn)
103
+static int get_S2prot(CPUARMState *env, int s2ap, int xn, bool s1_is_el0)
104
{
105
int prot = 0;
106
107
@@ -XXX,XX +XXX,XX @@ static int get_S2prot(CPUARMState *env, int s2ap, int xn)
108
if (s2ap & 2) {
109
prot |= PAGE_WRITE;
110
}
111
- if (!xn) {
112
- if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
84
+
113
+
85
+#ifndef CONFIG_USER_ONLY
114
+ if (cpu_isar_feature(any_tts2uxn, env_archcpu(env))) {
86
+static void dccvap_writefn(CPUARMState *env, const ARMCPRegInfo *opaque,
115
+ switch (xn) {
87
+ uint64_t value)
116
+ case 0:
88
+{
117
prot |= PAGE_EXEC;
89
+ ARMCPU *cpu = env_archcpu(env);
118
+ break;
90
+ /* CTR_EL0 System register -> DminLine, bits [19:16] */
119
+ case 1:
91
+ uint64_t dline_size = 4 << ((cpu->ctr >> 16) & 0xF);
120
+ if (s1_is_el0) {
92
+ uint64_t vaddr_in = (uint64_t) value;
121
+ prot |= PAGE_EXEC;
93
+ uint64_t vaddr = vaddr_in & ~(dline_size - 1);
122
+ }
94
+ void *haddr;
123
+ break;
95
+ int mem_idx = cpu_mmu_index(env, false);
124
+ case 2:
96
+
125
+ break;
97
+ /* This won't be crossing page boundaries */
126
+ case 3:
98
+ haddr = probe_read(env, vaddr, dline_size, mem_idx, GETPC());
127
+ if (!s1_is_el0) {
99
+ if (haddr) {
128
+ prot |= PAGE_EXEC;
100
+
129
+ }
101
+ ram_addr_t offset;
130
+ break;
102
+ MemoryRegion *mr;
131
+ default:
103
+
132
+ g_assert_not_reached();
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
+ }
133
+ }
110
+ }
134
+ } else {
111
+}
135
+ if (!extract32(xn, 1, 1)) {
112
+
136
+ if (arm_el_is_aa64(env, 2) || prot & PAGE_READ) {
113
+static const ARMCPRegInfo dcpop_reg[] = {
137
+ prot |= PAGE_EXEC;
114
+ { .name = "DC_CVAP", .state = ARM_CP_STATE_AA64,
138
+ }
115
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 12, .opc2 = 1,
139
}
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
}
140
}
137
+#ifndef CONFIG_USER_ONLY
141
return prot;
138
+ /* Data Cache clean instructions up to PoP */
142
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
139
+ if (cpu_isar_feature(aa64_dcpop, cpu)) {
143
}
140
+ define_one_arm_cp_reg(cpu, dcpop_reg);
144
141
+
145
ap = extract32(attrs, 4, 2);
142
+ if (cpu_isar_feature(aa64_dcpodp, cpu)) {
146
- xn = extract32(attrs, 12, 1);
143
+ define_one_arm_cp_reg(cpu, dcpodp_reg);
147
144
+ }
148
if (mmu_idx == ARMMMUIdx_Stage2) {
145
+ }
149
ns = true;
146
+#endif /*CONFIG_USER_ONLY*/
150
- *prot = get_S2prot(env, ap, xn);
147
#endif
151
+ xn = extract32(attrs, 11, 2);
148
152
+ *prot = get_S2prot(env, ap, xn, s1_is_el0);
149
/*
153
} else {
154
ns = extract32(attrs, 3, 1);
155
+ xn = extract32(attrs, 12, 1);
156
pxn = extract32(attrs, 11, 1);
157
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
158
}
150
--
159
--
151
2.20.1
160
2.20.1
152
161
153
162
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
In aarch64_max_initfn() we update both 32-bit and 64-bit ID
2
registers. The intended pattern is that for 64-bit ID registers we
3
use FIELD_DP64 and the uint64_t 't' register, while 32-bit ID
4
registers use FIELD_DP32 and the uint32_t 'u' register. For
5
ID_AA64DFR0 we accidentally used 'u', meaning that the top 32 bits of
6
this 64-bit ID register would end up always zero. Luckily at the
7
moment that's what they should be anyway, so this bug has no visible
8
effects.
2
9
3
Most boards have this much.
10
Use the right-sized variable.
4
11
5
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Fixes: 3bec78447a958d481991
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>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20200423110915.10527-1-peter.maydell@linaro.org
11
---
17
---
12
hw/misc/aspeed_sdmc.c | 6 +++---
18
target/arm/cpu64.c | 6 +++---
13
1 file changed, 3 insertions(+), 3 deletions(-)
19
1 file changed, 3 insertions(+), 3 deletions(-)
14
20
15
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
21
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/misc/aspeed_sdmc.c
23
--- a/target/arm/cpu64.c
18
+++ b/hw/misc/aspeed_sdmc.c
24
+++ b/target/arm/cpu64.c
19
@@ -XXX,XX +XXX,XX @@ static int ast2600_rambits(AspeedSDMCState *s)
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
}
26
u = FIELD_DP32(u, ID_MMFR4, XNX, 1); /* TTS2UXN */
21
27
cpu->isar.id_mmfr4 = u;
22
/* use a common default */
28
23
- warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M",
29
- u = cpu->isar.id_aa64dfr0;
24
+ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 1024M",
30
- u = FIELD_DP64(u, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
25
s->ram_size);
31
- cpu->isar.id_aa64dfr0 = u;
26
- s->ram_size = 512 << 20;
32
+ t = cpu->isar.id_aa64dfr0;
27
- return ASPEED_SDMC_AST2600_512MB;
33
+ t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5); /* v8.4-PMU */
28
+ s->ram_size = 1024 << 20;
34
+ cpu->isar.id_aa64dfr0 = t;
29
+ return ASPEED_SDMC_AST2600_1024MB;
35
30
}
36
u = cpu->isar.id_dfr0;
31
37
u = FIELD_DP32(u, ID_DFR0, PERFMON, 5); /* v8.4-PMU */
32
static void aspeed_sdmc_reset(DeviceState *dev)
33
--
38
--
34
2.20.1
39
2.20.1
35
40
36
41
diff view generated by jsdifflib
1
From: Christophe Lyon <christophe.lyon@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This is derived from cortex-m4 description, adding DP support and FPv5
3
MIDR_EL1 is a 64-bit system register with the top 32-bit being RES0.
4
instructions with the corresponding flags in isar and mvfr2.
4
Represent it in QEMU's ARMCPU struct with a uint64_t, not a
5
uint32_t.
5
6
6
Checked that it could successfully execute
7
This fixes an error when compiling with -Werror=conversion
7
vrinta.f32 s15, s15
8
because we were manipulating the register value using a
8
while cortex-m4 emulation rejects it with "illegal instruction".
9
local uint64_t variable:
9
10
10
Signed-off-by: Christophe Lyon <christophe.lyon@linaro.org>
11
target/arm/cpu64.c: In function ‘aarch64_max_initfn’:
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
target/arm/cpu64.c:628:21: error: conversion from ‘uint64_t’ {aka ‘long unsigned int’} to ‘uint32_t’ {aka ‘unsigned int’} may change value [-Werror=conversion]
13
628 | cpu->midr = t;
14
| ^
15
16
and future-proofs us against a possible future architecture
17
change using some of the top 32 bits.
18
19
Suggested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
20
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
23
Message-id: 20200428172634.29707-1-f4bug@amsat.org
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
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>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
26
---
16
target/arm/cpu.c | 33 +++++++++++++++++++++++++++++++++
27
target/arm/cpu.h | 2 +-
17
1 file changed, 33 insertions(+)
28
target/arm/cpu.c | 2 +-
29
2 files changed, 2 insertions(+), 2 deletions(-)
18
30
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
36
uint64_t id_aa64dfr0;
37
uint64_t id_aa64dfr1;
38
} isar;
39
- uint32_t midr;
40
+ uint64_t midr;
41
uint32_t revidr;
42
uint32_t reset_fpsid;
43
uint32_t ctr;
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
46
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
47
+++ 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[] = {
48
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
62
.class_init = arm_v7m_class_init },
49
static Property arm_cpu_properties[] = {
63
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
50
DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
64
.class_init = arm_v7m_class_init },
51
DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
65
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
52
- DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
66
+ .class_init = arm_v7m_class_init },
53
+ DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
67
{ .name = "cortex-m33", .initfn = cortex_m33_initfn,
54
DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
68
.class_init = arm_v7m_class_init },
55
mp_affinity, ARM64_AFFINITY_INVALID),
69
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
56
DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
70
--
57
--
71
2.20.1
58
2.20.1
72
59
73
60
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
After the introduction of generic PCIe root port and PCIe-PCI bridge,
3
Remove inclusion of arm_gicv3_common.h, this already gets
4
we will also have SHPC controller on ARM, so just enable SHPC native
4
included via xlnx-versal.h.
5
hot plug.
6
5
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20200427181649.26851-2-edgar.iglesias@gmail.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
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
hw/arm/virt-acpi-build.c | 7 ++++++-
12
hw/arm/xlnx-versal.c | 1 -
20
tests/data/acpi/virt/DSDT | Bin 18462 -> 18462 bytes
13
1 file changed, 1 deletion(-)
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(-)
24
14
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
17
--- a/hw/arm/xlnx-versal.c
28
+++ b/hw/arm/virt-acpi-build.c
18
+++ b/hw/arm/xlnx-versal.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
19
@@ -XXX,XX +XXX,XX @@
30
aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
20
#include "hw/arm/boot.h"
31
aml_append(ifctx, aml_store(aml_name("CDW2"), aml_name("SUPP")));
21
#include "kvm_arm.h"
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
22
#include "hw/misc/unimp.h"
33
- aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
23
-#include "hw/intc/arm_gicv3_common.h"
34
+
24
#include "hw/arm/xlnx-versal.h"
35
+ /*
25
#include "hw/char/pl011.h"
36
+ * Allow OS control for all 5 features:
26
37
+ * PCIeHotplug SHPCHotplug PME AER PCIeCapability.
38
+ */
39
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1F),
40
aml_name("CTRL")));
41
42
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
43
diff --git a/tests/data/acpi/virt/DSDT b/tests/data/acpi/virt/DSDT
44
index XXXXXXX..XXXXXXX 100644
45
GIT binary patch
46
delta 28
47
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
48
49
delta 28
50
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
51
52
diff --git a/tests/data/acpi/virt/DSDT.memhp b/tests/data/acpi/virt/DSDT.memhp
53
index XXXXXXX..XXXXXXX 100644
54
GIT binary patch
55
delta 28
56
kcmcaUi}Cs_MlP3NmymE@1_mbija=*8809zbbeqQp0Eq|*2mk;8
57
58
delta 28
59
kcmcaUi}Cs_MlP3NmymE@1_ma@ja=*87-cu_beqQp0ErX{2mk;8
60
61
diff --git a/tests/data/acpi/virt/DSDT.numamem b/tests/data/acpi/virt/DSDT.numamem
62
index XXXXXXX..XXXXXXX 100644
63
GIT binary patch
64
delta 28
65
kcmbO?fpOjhMlP3Nmk>D*1_q{tja=*8809zbbW3Ff0C~9xM*si-
66
67
delta 28
68
kcmbO?fpOjhMlP3Nmk>D*1_q|2ja=*87-cu_bW3Ff0C~j-M*si-
69
70
--
27
--
71
2.20.1
28
2.20.1
72
29
73
30
diff view generated by jsdifflib
1
From: Heyi Guo <guoheyi@huawei.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The last argument of AML bit and/or statement is the target variable,
3
Move misplaced comment.
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.
6
4
7
Also update tests/data/acpi/virt/DSDT* to pass "make check".
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: Shannon Zhao <shannon.zhaosl@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Cc: "Michael S. Tsirkin" <mst@redhat.com>
9
Message-id: 20200427181649.26851-3-edgar.iglesias@gmail.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
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
11
---
19
hw/arm/virt-acpi-build.c | 16 ++++++++--------
12
hw/arm/xlnx-versal.c | 2 +-
20
tests/data/acpi/virt/DSDT | Bin 18470 -> 18462 bytes
13
1 file changed, 1 insertion(+), 1 deletion(-)
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(-)
24
14
25
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
15
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/virt-acpi-build.c
17
--- a/hw/arm/xlnx-versal.c
28
+++ b/hw/arm/virt-acpi-build.c
18
+++ b/hw/arm/xlnx-versal.c
29
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
19
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *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
obj = object_new(XLNX_VERSAL_ACPU_TYPE);
32
aml_append(ifctx, aml_store(aml_name("CDW3"), aml_name("CTRL")));
22
if (!obj) {
33
- aml_append(ifctx, aml_store(aml_and(aml_name("CTRL"), aml_int(0x1D), NULL),
23
- /* Secondary CPUs start in PSCI powered-down state */
34
- aml_name("CTRL")));
24
error_report("Unable to create apu.cpu[%d] of type %s",
35
+ aml_append(ifctx, aml_and(aml_name("CTRL"), aml_int(0x1D),
25
i, XLNX_VERSAL_ACPU_TYPE);
36
+ aml_name("CTRL")));
26
exit(EXIT_FAILURE);
37
27
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
38
ifctx1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1))));
28
object_property_set_int(obj, s->cfg.psci_conduit,
39
- aml_append(ifctx1, aml_store(aml_or(aml_name("CDW1"), aml_int(0x08), NULL),
29
"psci-conduit", &error_abort);
40
- aml_name("CDW1")));
30
if (i) {
41
+ aml_append(ifctx1, aml_or(aml_name("CDW1"), aml_int(0x08),
31
+ /* Secondary CPUs start in PSCI powered-down state */
42
+ aml_name("CDW1")));
32
object_property_set_bool(obj, true,
43
aml_append(ifctx, ifctx1);
33
"start-powered-off", &error_abort);
44
34
}
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
103
--
35
--
104
2.20.1
36
2.20.1
105
37
106
38
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The Aspeed Watchdog and Timer models have a link pointing to the SCU
3
Fix typo xlnx-ve -> xlnx-versal.
4
controller model of the machine.
5
4
6
Change the "scu" property definition so that it explicitly sets the
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
pointer. The property isn't optional : not being able to set the link
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
is a bug and QEMU should rather abort than exit in this case.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20200427181649.26851-4-edgar.iglesias@gmail.com
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
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
hw/arm/aspeed_ast2600.c | 8 ++++----
12
hw/arm/xlnx-versal-virt.c | 2 +-
18
hw/arm/aspeed_soc.c | 8 ++++----
13
1 file changed, 1 insertion(+), 1 deletion(-)
19
hw/timer/aspeed_timer.c | 17 +++++++++--------
20
hw/watchdog/wdt_aspeed.c | 17 ++++++++---------
21
4 files changed, 25 insertions(+), 25 deletions(-)
22
14
23
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
15
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/aspeed_ast2600.c
17
--- a/hw/arm/xlnx-versal-virt.c
26
+++ b/hw/arm/aspeed_ast2600.c
18
+++ b/hw/arm/xlnx-versal-virt.c
27
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
28
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
20
psci_conduit = QEMU_PSCI_CONDUIT_SMC;
29
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
30
sizeof(s->timerctrl), typename);
31
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
32
- OBJECT(&s->scu), &error_abort);
33
34
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
35
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
37
snprintf(typename, sizeof(typename), "aspeed.wdt-%s", socname);
38
sysbus_init_child_obj(obj, "wdt[*]", OBJECT(&s->wdt[i]),
39
sizeof(s->wdt[i]), typename);
40
- object_property_add_const_link(OBJECT(&s->wdt[i]), "scu",
41
- OBJECT(&s->scu), &error_abort);
42
}
21
}
43
22
44
for (i = 0; i < sc->macs_num; i++) {
23
- sysbus_init_child_obj(OBJECT(machine), "xlnx-ve", &s->soc,
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
24
+ sysbus_init_child_obj(OBJECT(machine), "xlnx-versal", &s->soc,
46
aspeed_soc_get_irq(s, ASPEED_RTC));
25
sizeof(s->soc), TYPE_XLNX_VERSAL);
47
26
object_property_set_link(OBJECT(&s->soc), OBJECT(machine->ram),
48
/* Timer */
27
"ddr", &error_abort);
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
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/arm/aspeed_soc.c
66
+++ b/hw/arm/aspeed_soc.c
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
68
snprintf(typename, sizeof(typename), "aspeed.timer-%s", socname);
69
sysbus_init_child_obj(obj, "timerctrl", OBJECT(&s->timerctrl),
70
sizeof(s->timerctrl), typename);
71
- object_property_add_const_link(OBJECT(&s->timerctrl), "scu",
72
- OBJECT(&s->scu), &error_abort);
73
74
snprintf(typename, sizeof(typename), "aspeed.i2c-%s", socname);
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;
150
}
151
152
static const TypeInfo aspeed_timer_info = {
153
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/watchdog/wdt_aspeed.c
156
+++ b/hw/watchdog/wdt_aspeed.c
157
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
158
{
159
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
160
AspeedWDTState *s = ASPEED_WDT(dev);
161
- Error *err = NULL;
162
- Object *obj;
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)
186
{
187
DeviceClass *dc = DEVICE_CLASS(klass);
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
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;
193
}
194
195
static const TypeInfo aspeed_wdt_info = {
196
--
28
--
197
2.20.1
29
2.20.1
198
30
199
31
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Make the gic a field in the machine state, and instead of filling
3
Embed the UARTs into the SoC type.
4
an array of qemu_irq and passing it around, directly call
5
qdev_get_gpio_in() on the gic field.
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20191206162303.30338-1-philmd@redhat.com
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-5-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/arm/sbsa-ref.c | 86 +++++++++++++++++++++++------------------------
13
include/hw/arm/xlnx-versal.h | 3 ++-
13
1 file changed, 42 insertions(+), 44 deletions(-)
14
hw/arm/xlnx-versal.c | 12 ++++++------
15
2 files changed, 8 insertions(+), 7 deletions(-)
14
16
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
19
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/hw/arm/sbsa-ref.c
20
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct {
21
@@ -XXX,XX +XXX,XX @@
20
void *fdt;
22
#include "hw/sysbus.h"
21
int fdt_size;
23
#include "hw/arm/boot.h"
22
int psci_conduit;
24
#include "hw/intc/arm_gicv3.h"
23
+ DeviceState *gic;
25
+#include "hw/char/pl011.h"
24
PFlashCFI01 *flash[2];
26
25
} SBSAMachineState;
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
26
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
27
@@ -XXX,XX +XXX,XX @@ static void create_secure_ram(SBSAMachineState *sms,
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
28
memory_region_add_subregion(secure_sysmem, base, secram);
30
MemoryRegion mr_ocm;
29
}
31
30
32
struct {
31
-static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
33
- SysBusDevice *uart[XLNX_VERSAL_NR_UARTS];
32
+static void create_gic(SBSAMachineState *sms)
34
+ PL011State uart[XLNX_VERSAL_NR_UARTS];
33
{
35
SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
unsigned int smp_cpus = MACHINE(sms)->smp.cpus;
36
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
35
- DeviceState *gicdev;
37
} iou;
36
SysBusDevice *gicbusdev;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
37
const char *gictype;
39
index XXXXXXX..XXXXXXX 100644
38
uint32_t redist0_capacity, redist0_count;
40
--- a/hw/arm/xlnx-versal.c
39
@@ -XXX,XX +XXX,XX @@ static void create_gic(SBSAMachineState *sms, qemu_irq *pic)
41
+++ b/hw/arm/xlnx-versal.c
40
42
@@ -XXX,XX +XXX,XX @@
41
gictype = gicv3_class_name();
43
#include "kvm_arm.h"
42
44
#include "hw/misc/unimp.h"
43
- gicdev = qdev_create(NULL, gictype);
45
#include "hw/arm/xlnx-versal.h"
44
- qdev_prop_set_uint32(gicdev, "revision", 3);
46
-#include "hw/char/pl011.h"
45
- qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);
47
46
+ sms->gic = qdev_create(NULL, gictype);
48
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
47
+ qdev_prop_set_uint32(sms->gic, "revision", 3);
49
#define GEM_REVISION 0x40070106
48
+ qdev_prop_set_uint32(sms->gic, "num-cpu", smp_cpus);
50
@@ -XXX,XX +XXX,XX @@ static void versal_create_uarts(Versal *s, qemu_irq *pic)
49
/*
51
DeviceState *dev;
50
* Note that the num-irq property counts both internal and external
52
MemoryRegion *mr;
51
* interrupts; there are always 32 of the former (mandated by GIC spec).
53
52
*/
54
- dev = qdev_create(NULL, TYPE_PL011);
53
- qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);
55
- s->lpd.iou.uart[i] = SYS_BUS_DEVICE(dev);
54
- qdev_prop_set_bit(gicdev, "has-security-extensions", true);
56
+ sysbus_init_child_obj(OBJECT(s), name,
55
+ qdev_prop_set_uint32(sms->gic, "num-irq", NUM_IRQS + 32);
57
+ &s->lpd.iou.uart[i], sizeof(s->lpd.iou.uart[i]),
56
+ qdev_prop_set_bit(sms->gic, "has-security-extensions", true);
58
+ TYPE_PL011);
57
59
+ dev = DEVICE(&s->lpd.iou.uart[i]);
58
redist0_capacity =
60
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
59
sbsa_ref_memmap[SBSA_GIC_REDIST].size / GICV3_REDIST_SIZE;
61
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
60
redist0_count = MIN(smp_cpus, redist0_capacity);
62
qdev_init_nofail(dev);
61
63
62
- qdev_prop_set_uint32(gicdev, "len-redist-region-count", 1);
64
- mr = sysbus_mmio_get_region(s->lpd.iou.uart[i], 0);
63
- qdev_prop_set_uint32(gicdev, "redist-region-count[0]", redist0_count);
65
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
64
+ qdev_prop_set_uint32(sms->gic, "len-redist-region-count", 1);
66
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
65
+ qdev_prop_set_uint32(sms->gic, "redist-region-count[0]", redist0_count);
67
66
68
- sysbus_connect_irq(s->lpd.iou.uart[i], 0, pic[irqs[i]]);
67
- qdev_init_nofail(gicdev);
69
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
68
- gicbusdev = SYS_BUS_DEVICE(gicdev);
70
g_free(name);
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
}
71
}
164
}
72
}
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
--
73
--
258
2.20.1
74
2.20.1
259
75
260
76
diff view generated by jsdifflib
1
From: PanNengyuan <pannengyuan@huawei.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Address Sanitizer shows memory leak in hw/gpio/aspeed_gpio.c:875
3
Embed the GEMs into the SoC type.
4
4
5
Reported-by: Euler Robot <euler.robot@huawei.com>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: PanNengyuan <pannengyuan@huawei.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20191119141211.25716-16-clg@kaod.org
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-6-edgar.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
---
12
hw/gpio/aspeed_gpio.c | 1 +
13
include/hw/arm/xlnx-versal.h | 3 ++-
13
1 file changed, 1 insertion(+)
14
hw/arm/xlnx-versal.c | 15 ++++++++-------
15
2 files changed, 10 insertions(+), 8 deletions(-)
14
16
15
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/gpio/aspeed_gpio.c
19
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/hw/gpio/aspeed_gpio.c
20
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_gpio_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@
20
pin_idx % GPIOS_PER_GROUP);
22
#include "hw/arm/boot.h"
21
object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
23
#include "hw/intc/arm_gicv3.h"
22
aspeed_gpio_set_pin, NULL, NULL, NULL);
24
#include "hw/char/pl011.h"
23
+ g_free(name);
25
+#include "hw/net/cadence_gem.h"
26
27
#define TYPE_XLNX_VERSAL "xlnx-versal"
28
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
31
struct {
32
PL011State uart[XLNX_VERSAL_NR_UARTS];
33
- SysBusDevice *gem[XLNX_VERSAL_NR_GEMS];
34
+ CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
35
SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
36
} iou;
37
} lpd;
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_gems(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "cadence_gem");
47
- s->lpd.iou.gem[i] = SYS_BUS_DEVICE(dev);
48
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
49
+ sysbus_init_child_obj(OBJECT(s), name,
50
+ &s->lpd.iou.gem[i], sizeof(s->lpd.iou.gem[i]),
51
+ TYPE_CADENCE_GEM);
52
+ dev = DEVICE(&s->lpd.iou.gem[i]);
53
if (nd->used) {
54
qemu_check_nic_model(nd, "cadence_gem");
55
qdev_set_nic_properties(dev, nd);
56
}
57
- object_property_set_int(OBJECT(s->lpd.iou.gem[i]),
58
+ object_property_set_int(OBJECT(dev),
59
2, "num-priority-queues",
60
&error_abort);
61
- object_property_set_link(OBJECT(s->lpd.iou.gem[i]),
62
+ object_property_set_link(OBJECT(dev),
63
OBJECT(&s->mr_ps), "dma",
64
&error_abort);
65
qdev_init_nofail(dev);
66
67
- mr = sysbus_mmio_get_region(s->lpd.iou.gem[i], 0);
68
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
69
memory_region_add_subregion(&s->mr_ps, addrs[i], mr);
70
71
- sysbus_connect_irq(s->lpd.iou.gem[i], 0, pic[irqs[i]]);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irqs[i]]);
73
g_free(name);
24
}
74
}
25
}
75
}
26
27
--
76
--
28
2.20.1
77
2.20.1
29
78
30
79
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Users benefit from knowing which watchdog timer has expired. The address
3
Embed the ADMAs into the SoC type.
4
of the watchdog's registers unambiguously indicates which has expired,
5
so log that.
6
4
7
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20191119141211.25716-9-clg@kaod.org
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20200427181649.26851-7-edgar.iglesias@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
hw/watchdog/wdt_aspeed.c | 3 ++-
13
include/hw/arm/xlnx-versal.h | 3 ++-
15
1 file changed, 2 insertions(+), 1 deletion(-)
14
hw/arm/xlnx-versal.c | 14 +++++++-------
15
2 files changed, 9 insertions(+), 8 deletions(-)
16
16
17
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
17
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/watchdog/wdt_aspeed.c
19
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/hw/watchdog/wdt_aspeed.c
20
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_timer_expired(void *dev)
21
@@ -XXX,XX +XXX,XX @@
22
return;
22
#include "hw/arm/boot.h"
23
#include "hw/intc/arm_gicv3.h"
24
#include "hw/char/pl011.h"
25
+#include "hw/dma/xlnx-zdma.h"
26
#include "hw/net/cadence_gem.h"
27
28
#define TYPE_XLNX_VERSAL "xlnx-versal"
29
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
30
struct {
31
PL011State uart[XLNX_VERSAL_NR_UARTS];
32
CadenceGEMState gem[XLNX_VERSAL_NR_GEMS];
33
- SysBusDevice *adma[XLNX_VERSAL_NR_ADMAS];
34
+ XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
35
} iou;
36
} lpd;
37
38
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/arm/xlnx-versal.c
41
+++ b/hw/arm/xlnx-versal.c
42
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
43
DeviceState *dev;
44
MemoryRegion *mr;
45
46
- dev = qdev_create(NULL, "xlnx.zdma");
47
- s->lpd.iou.adma[i] = SYS_BUS_DEVICE(dev);
48
- object_property_set_int(OBJECT(s->lpd.iou.adma[i]), 128, "bus-width",
49
- &error_abort);
50
- object_property_add_child(OBJECT(s), name, OBJECT(dev), &error_fatal);
51
+ sysbus_init_child_obj(OBJECT(s), name,
52
+ &s->lpd.iou.adma[i], sizeof(s->lpd.iou.adma[i]),
53
+ TYPE_XLNX_ZDMA);
54
+ dev = DEVICE(&s->lpd.iou.adma[i]);
55
+ object_property_set_int(OBJECT(dev), 128, "bus-width", &error_abort);
56
qdev_init_nofail(dev);
57
58
- mr = sysbus_mmio_get_region(s->lpd.iou.adma[i], 0);
59
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
60
memory_region_add_subregion(&s->mr_ps,
61
MM_ADMA_CH0 + i * MM_ADMA_CH0_SIZE, mr);
62
63
- sysbus_connect_irq(s->lpd.iou.adma[i], 0, pic[VERSAL_ADMA_IRQ_0 + i]);
64
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[VERSAL_ADMA_IRQ_0 + i]);
65
g_free(name);
23
}
66
}
24
25
- qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n");
26
+ qemu_log_mask(CPU_LOG_RESET, "Watchdog timer %" HWADDR_PRIx " expired.\n",
27
+ s->iomem.addr);
28
watchdog_perform_action();
29
timer_del(s->timer);
30
}
67
}
31
--
68
--
32
2.20.1
69
2.20.1
33
70
34
71
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The segments can be disabled on the AST2600 (zero register value).
3
Embed the APUs into the SoC type.
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
4
7
In the model, check the segment size and disable the associated region
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
when the value is zero.
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Fixes: bcaa8ddd081c ("aspeed/smc: Add AST2600 support")
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Message-id: 20200427181649.26851-8-edgar.iglesias@gmail.com
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Message-id: 20191119141211.25716-12-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
hw/ssi/aspeed_smc.c | 16 +++++++++++-----
13
include/hw/arm/xlnx-versal.h | 2 +-
18
1 file changed, 11 insertions(+), 5 deletions(-)
14
hw/arm/xlnx-versal-virt.c | 4 ++--
15
hw/arm/xlnx-versal.c | 19 +++++--------------
16
3 files changed, 8 insertions(+), 17 deletions(-)
19
17
20
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
18
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/ssi/aspeed_smc.c
20
--- a/include/hw/arm/xlnx-versal.h
23
+++ b/hw/ssi/aspeed_smc.c
21
+++ b/include/hw/arm/xlnx-versal.h
24
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_smc_reg_to_segment(const AspeedSMCState *s,
22
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
25
uint32_t start_offset = (reg << 16) & AST2600_SEG_ADDR_MASK;
23
struct {
26
uint32_t end_offset = reg & AST2600_SEG_ADDR_MASK;
24
struct {
27
25
MemoryRegion mr;
28
- seg->addr = s->ctrl->flash_window_base + start_offset;
26
- ARMCPU *cpu[XLNX_VERSAL_NR_ACPUS];
29
- seg->size = end_offset + MiB - start_offset;
27
+ ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
30
+ if (reg) {
28
GICv3State gic;
31
+ seg->addr = s->ctrl->flash_window_base + start_offset;
29
} apu;
32
+ seg->size = end_offset + MiB - start_offset;
30
} fpd;
33
+ } else {
31
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
34
+ seg->addr = s->ctrl->flash_window_base;
32
index XXXXXXX..XXXXXXX 100644
35
+ seg->size = 0;
33
--- a/hw/arm/xlnx-versal-virt.c
36
+ }
34
+++ b/hw/arm/xlnx-versal-virt.c
35
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
36
s->binfo.get_dtb = versal_virt_get_dtb;
37
s->binfo.modify_dtb = versal_virt_modify_dtb;
38
if (machine->kernel_filename) {
39
- arm_load_kernel(s->soc.fpd.apu.cpu[0], machine, &s->binfo);
40
+ arm_load_kernel(&s->soc.fpd.apu.cpu[0], machine, &s->binfo);
41
} else {
42
- AddressSpace *as = arm_boot_address_space(s->soc.fpd.apu.cpu[0],
43
+ AddressSpace *as = arm_boot_address_space(&s->soc.fpd.apu.cpu[0],
44
&s->binfo);
45
/* Some boot-loaders (e.g u-boot) don't like blobs at address 0 (NULL).
46
* Offset things by 4K. */
47
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/xlnx-versal.c
50
+++ b/hw/arm/xlnx-versal.c
51
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
52
53
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
54
Object *obj;
55
- char *name;
56
-
57
- obj = object_new(XLNX_VERSAL_ACPU_TYPE);
58
- if (!obj) {
59
- error_report("Unable to create apu.cpu[%d] of type %s",
60
- i, XLNX_VERSAL_ACPU_TYPE);
61
- exit(EXIT_FAILURE);
62
- }
63
-
64
- name = g_strdup_printf("apu-cpu[%d]", i);
65
- object_property_add_child(OBJECT(s), name, obj, &error_fatal);
66
- g_free(name);
67
68
+ object_initialize_child(OBJECT(s), "apu-cpu[*]",
69
+ &s->fpd.apu.cpu[i], sizeof(s->fpd.apu.cpu[i]),
70
+ XLNX_VERSAL_ACPU_TYPE, &error_abort, NULL);
71
+ obj = OBJECT(&s->fpd.apu.cpu[i]);
72
object_property_set_int(obj, s->cfg.psci_conduit,
73
"psci-conduit", &error_abort);
74
if (i) {
75
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
76
object_property_set_link(obj, OBJECT(&s->fpd.apu.mr), "memory",
77
&error_abort);
78
object_property_set_bool(obj, true, "realized", &error_fatal);
79
- s->fpd.apu.cpu[i] = ARM_CPU(obj);
80
}
37
}
81
}
38
82
39
static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
83
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
40
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
41
memory_region_transaction_begin();
42
memory_region_set_size(&fl->mmio, seg.size);
43
memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
44
- memory_region_set_enabled(&fl->mmio, true);
45
+ memory_region_set_enabled(&fl->mmio, !!seg.size);
46
memory_region_transaction_commit();
47
48
s->regs[R_SEG_ADDR0 + cs] = regval;
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
50
}
84
}
51
85
52
/* Keep the segment in the overall flash window */
86
for (i = 0; i < nr_apu_cpus; i++) {
53
- if (seg.addr + seg.size <= s->ctrl->flash_window_base ||
87
- DeviceState *cpudev = DEVICE(s->fpd.apu.cpu[i]);
54
- seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size) {
88
+ DeviceState *cpudev = DEVICE(&s->fpd.apu.cpu[i]);
55
+ if (seg.size &&
89
int ppibase = XLNX_VERSAL_NR_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
56
+ (seg.addr + seg.size <= s->ctrl->flash_window_base ||
90
qemu_irq maint_irq;
57
+ seg.addr > s->ctrl->flash_window_base + s->ctrl->flash_window_size)) {
91
int ti;
58
qemu_log_mask(LOG_GUEST_ERROR, "%s: new segment for CS%d is invalid : "
59
"[ 0x%"HWADDR_PRIx" - 0x%"HWADDR_PRIx" ]\n",
60
s->ctrl->name, cs, seg.addr, seg.addr + seg.size);
61
--
92
--
62
2.20.1
93
2.20.1
63
94
64
95
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The AST2600 control register sneakily changed the meaning of bit 4
3
Add support for SD.
4
without anyone noticing. It no longer controls the 1MHz vs APB clock
5
select, and instead always runs at 1MHz.
6
4
7
The AST2500 was always 1MHz too, but it retained bit 4, making it read
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
only. We can model both using the same fixed 1MHz calculation.
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Fixes: 6b2b2a703cad ("hw: wdt_aspeed: Add AST2600 support")
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
Message-id: 20200427181649.26851-9-edgar.iglesias@gmail.com
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Signed-off-by: Joel Stanley <joel@jms.id.au>
14
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
Message-id: 20191119141211.25716-10-clg@kaod.org
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
include/hw/watchdog/wdt_aspeed.h | 1 +
12
include/hw/arm/xlnx-versal.h | 12 ++++++++++++
19
hw/watchdog/wdt_aspeed.c | 21 +++++++++++++++++----
13
hw/arm/xlnx-versal.c | 31 +++++++++++++++++++++++++++++++
20
2 files changed, 18 insertions(+), 4 deletions(-)
14
2 files changed, 43 insertions(+)
21
15
22
diff --git a/include/hw/watchdog/wdt_aspeed.h b/include/hw/watchdog/wdt_aspeed.h
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/watchdog/wdt_aspeed.h
18
--- a/include/hw/arm/xlnx-versal.h
25
+++ b/include/hw/watchdog/wdt_aspeed.h
19
+++ b/include/hw/arm/xlnx-versal.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedWDTClass {
20
@@ -XXX,XX +XXX,XX @@
27
uint32_t ext_pulse_width_mask;
21
28
uint32_t reset_ctrl_reg;
22
#include "hw/sysbus.h"
29
void (*reset_pulse)(AspeedWDTState *s, uint32_t property);
23
#include "hw/arm/boot.h"
30
+ void (*wdt_reload)(AspeedWDTState *s);
24
+#include "hw/sd/sdhci.h"
31
} AspeedWDTClass;
25
#include "hw/intc/arm_gicv3.h"
32
26
#include "hw/char/pl011.h"
33
#endif /* WDT_ASPEED_H */
27
#include "hw/dma/xlnx-zdma.h"
34
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
28
@@ -XXX,XX +XXX,XX @@
29
#define XLNX_VERSAL_NR_UARTS 2
30
#define XLNX_VERSAL_NR_GEMS 2
31
#define XLNX_VERSAL_NR_ADMAS 8
32
+#define XLNX_VERSAL_NR_SDS 2
33
#define XLNX_VERSAL_NR_IRQS 192
34
35
typedef struct Versal {
36
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
37
} iou;
38
} lpd;
39
40
+ /* The Platform Management Controller subsystem. */
41
+ struct {
42
+ struct {
43
+ SDHCIState sd[XLNX_VERSAL_NR_SDS];
44
+ } iou;
45
+ } pmc;
46
+
47
struct {
48
MemoryRegion *mr_ddr;
49
uint32_t psci_conduit;
50
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
51
#define VERSAL_GEM1_IRQ_0 58
52
#define VERSAL_GEM1_WAKE_IRQ_0 59
53
#define VERSAL_ADMA_IRQ_0 60
54
+#define VERSAL_SD0_IRQ_0 126
55
56
/* Architecturally reserved IRQs suitable for virtualization. */
57
#define VERSAL_RSVD_IRQ_FIRST 111
58
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
59
#define MM_FPD_CRF 0xfd1a0000U
60
#define MM_FPD_CRF_SIZE 0x140000
61
62
+#define MM_PMC_SD0 0xf1040000U
63
+#define MM_PMC_SD0_SIZE 0x10000
64
#define MM_PMC_CRP 0xf1260000U
65
#define MM_PMC_CRP_SIZE 0x10000
66
#endif
67
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/watchdog/wdt_aspeed.c
69
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/watchdog/wdt_aspeed.c
70
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
71
@@ -XXX,XX +XXX,XX @@ static void versal_create_admas(Versal *s, qemu_irq *pic)
39
40
}
41
42
-static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
43
+static void aspeed_wdt_reload(AspeedWDTState *s)
44
{
45
uint64_t reload;
46
47
- if (pclk) {
48
+ if (!(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK)) {
49
reload = muldiv64(s->regs[WDT_RELOAD_VALUE], NANOSECONDS_PER_SECOND,
50
s->pclk_freq);
51
} else {
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_reload(AspeedWDTState *s, bool pclk)
53
}
72
}
54
}
73
}
55
74
56
+static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
75
+#define SDHCI_CAPABILITIES 0x280737ec6481 /* Same as on ZynqMP. */
76
+static void versal_create_sds(Versal *s, qemu_irq *pic)
57
+{
77
+{
58
+ uint64_t reload = s->regs[WDT_RELOAD_VALUE] * 1000ULL;
78
+ int i;
59
+
79
+
60
+ if (aspeed_wdt_is_enabled(s)) {
80
+ for (i = 0; i < ARRAY_SIZE(s->pmc.iou.sd); i++) {
61
+ timer_mod(s->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + reload);
81
+ DeviceState *dev;
82
+ MemoryRegion *mr;
83
+
84
+ sysbus_init_child_obj(OBJECT(s), "sd[*]",
85
+ &s->pmc.iou.sd[i], sizeof(s->pmc.iou.sd[i]),
86
+ TYPE_SYSBUS_SDHCI);
87
+ dev = DEVICE(&s->pmc.iou.sd[i]);
88
+
89
+ object_property_set_uint(OBJECT(dev),
90
+ 3, "sd-spec-version", &error_fatal);
91
+ object_property_set_uint(OBJECT(dev), SDHCI_CAPABILITIES, "capareg",
92
+ &error_fatal);
93
+ object_property_set_uint(OBJECT(dev), UHS_I, "uhs", &error_fatal);
94
+ qdev_init_nofail(dev);
95
+
96
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
97
+ memory_region_add_subregion(&s->mr_ps,
98
+ MM_PMC_SD0 + i * MM_PMC_SD0_SIZE, mr);
99
+
100
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
101
+ pic[VERSAL_SD0_IRQ_0 + i * 2]);
62
+ }
102
+ }
63
+}
103
+}
64
+
104
+
65
+
105
/* This takes the board allocated linear DDR memory and creates aliases
66
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
106
* for each split DDR range/aperture on the Versal address map.
67
unsigned size)
107
*/
68
{
108
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
69
@@ -XXX,XX +XXX,XX @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
109
versal_create_uarts(s, pic);
70
case WDT_RESTART:
110
versal_create_gems(s, pic);
71
if ((data & 0xFFFF) == WDT_RESTART_MAGIC) {
111
versal_create_admas(s, pic);
72
s->regs[WDT_STATUS] = s->regs[WDT_RELOAD_VALUE];
112
+ versal_create_sds(s, pic);
73
- aspeed_wdt_reload(s, !(s->regs[WDT_CTRL] & WDT_CTRL_1MHZ_CLK));
113
versal_map_ddr(s);
74
+ awc->wdt_reload(s);
114
versal_unimp(s);
75
}
115
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;
90
}
91
92
static const TypeInfo aspeed_2400_wdt_info = {
93
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
94
awc->ext_pulse_width_mask = 0xfffff;
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;
98
}
99
100
static const TypeInfo aspeed_2500_wdt_info = {
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
102
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
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;
106
}
107
108
static const TypeInfo aspeed_2600_wdt_info = {
109
--
116
--
110
2.20.1
117
2.20.1
111
118
112
119
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The Tacoma BMC board is replacement board for the BMC of the OpenPOWER
3
hw/arm: versal: Add support for the RTC.
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
4
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20191119141211.25716-15-clg@kaod.org
8
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20200427181649.26851-10-edgar.iglesias@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/arm/aspeed.c | 28 ++++++++++++++++++++++++++++
12
include/hw/arm/xlnx-versal.h | 8 ++++++++
15
1 file changed, 28 insertions(+)
13
hw/arm/xlnx-versal.c | 21 +++++++++++++++++++++
14
2 files changed, 29 insertions(+)
16
15
17
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
18
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/aspeed.c
18
--- a/include/hw/arm/xlnx-versal.h
20
+++ b/hw/arm/aspeed.c
19
+++ b/include/hw/arm/xlnx-versal.h
21
@@ -XXX,XX +XXX,XX @@ struct AspeedBoardState {
20
@@ -XXX,XX +XXX,XX @@
22
#define AST2600_EVB_HW_STRAP1 0x000000C0
21
#include "hw/char/pl011.h"
23
#define AST2600_EVB_HW_STRAP2 0x00000003
22
#include "hw/dma/xlnx-zdma.h"
24
23
#include "hw/net/cadence_gem.h"
25
+/* Tacoma hardware value */
24
+#include "hw/rtc/xlnx-zynqmp-rtc.h"
26
+#define TACOMA_BMC_HW_STRAP1 0x00000000
25
27
+#define TACOMA_BMC_HW_STRAP2 0x00000000
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
#define XLNX_VERSAL(obj) OBJECT_CHECK(Versal, (obj), TYPE_XLNX_VERSAL)
28
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
29
struct {
30
SDHCIState sd[XLNX_VERSAL_NR_SDS];
31
} iou;
28
+
32
+
29
/*
33
+ XlnxZynqMPRTC rtc;
30
* The max ram region is for firmwares that scan the address space
34
} pmc;
31
* with load/store to guess how much RAM the SoC has.
35
32
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
36
struct {
33
AspeedSoCState *soc = &bmc->soc;
37
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
34
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
38
#define VERSAL_GEM1_IRQ_0 58
35
39
#define VERSAL_GEM1_WAKE_IRQ_0 59
36
+ /* Bus 3: TODO bmp280@77 */
40
#define VERSAL_ADMA_IRQ_0 60
37
+ /* Bus 3: TODO max31785@52 */
41
+#define VERSAL_RTC_APB_ERR_IRQ 121
38
+ /* Bus 3: TODO dps310@76 */
42
#define VERSAL_SD0_IRQ_0 126
39
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
43
+#define VERSAL_RTC_ALARM_IRQ 142
40
0x60);
44
+#define VERSAL_RTC_SECONDS_IRQ 143
41
45
42
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
46
/* Architecturally reserved IRQs suitable for virtualization. */
43
eeprom_buf);
47
#define VERSAL_RSVD_IRQ_FIRST 111
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
48
@@ -XXX,XX +XXX,XX @@ typedef struct Versal {
45
0x60);
49
#define MM_PMC_SD0_SIZE 0x10000
46
+ /* Bus 11: TODO ucd90160@64 */
50
#define MM_PMC_CRP 0xf1260000U
51
#define MM_PMC_CRP_SIZE 0x10000
52
+#define MM_PMC_RTC 0xf12a0000
53
+#define MM_PMC_RTC_SIZE 0x10000
54
#endif
55
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/xlnx-versal.c
58
+++ b/hw/arm/xlnx-versal.c
59
@@ -XXX,XX +XXX,XX @@ static void versal_create_sds(Versal *s, qemu_irq *pic)
60
}
47
}
61
}
48
62
49
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
63
+static void versal_create_rtc(Versal *s, qemu_irq *pic)
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
+{
64
+{
56
+ MachineClass *mc = MACHINE_CLASS(oc);
65
+ SysBusDevice *sbd;
57
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
66
+ MemoryRegion *mr;
58
+
67
+
59
+ mc->desc = "Aspeed AST2600 EVB (Cortex A7)";
68
+ sysbus_init_child_obj(OBJECT(s), "rtc", &s->pmc.rtc, sizeof(s->pmc.rtc),
60
+ amc->soc_name = "ast2600-a0";
69
+ TYPE_XLNX_ZYNQMP_RTC);
61
+ amc->hw_strap1 = TACOMA_BMC_HW_STRAP1;
70
+ sbd = SYS_BUS_DEVICE(&s->pmc.rtc);
62
+ amc->hw_strap2 = TACOMA_BMC_HW_STRAP2;
71
+ qdev_init_nofail(DEVICE(sbd));
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
+
72
+
70
static const TypeInfo aspeed_machine_types[] = {
73
+ mr = sysbus_mmio_get_region(sbd, 0);
71
{
74
+ memory_region_add_subregion(&s->mr_ps, MM_PMC_RTC, mr);
72
.name = MACHINE_TYPE_NAME("palmetto-bmc"),
75
+
73
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_machine_types[] = {
76
+ /*
74
.name = MACHINE_TYPE_NAME("ast2600-evb"),
77
+ * TODO: Connect the ALARM and SECONDS interrupts once our RTC model
75
.parent = TYPE_ASPEED_MACHINE,
78
+ * supports them.
76
.class_init = aspeed_machine_ast2600_evb_class_init,
79
+ */
77
+ }, {
80
+ sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
78
+ .name = MACHINE_TYPE_NAME("tacoma-bmc"),
81
+}
79
+ .parent = TYPE_ASPEED_MACHINE,
82
+
80
+ .class_init = aspeed_machine_tacoma_class_init,
83
/* This takes the board allocated linear DDR memory and creates aliases
81
}, {
84
* for each split DDR range/aperture on the Versal address map.
82
.name = TYPE_ASPEED_MACHINE,
85
*/
83
.parent = TYPE_MACHINE,
86
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
87
versal_create_gems(s, pic);
88
versal_create_admas(s, pic);
89
versal_create_sds(s, pic);
90
+ versal_create_rtc(s, pic);
91
versal_map_ddr(s);
92
versal_unimp(s);
93
84
--
94
--
85
2.20.1
95
2.20.1
86
96
87
97
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
The Aspeed I2C controller can operate in different transfer modes :
3
Add support for SD.
4
4
5
- Byte Buffer mode, using a dedicated register to transfer a
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
byte. This is what the model supports today.
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
- Pool Buffer mode, using an internal SRAM to transfer multiple
8
Message-id: 20200427181649.26851-11-edgar.iglesias@gmail.com
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
10
---
30
include/hw/i2c/aspeed_i2c.h | 8 ++
11
hw/arm/xlnx-versal-virt.c | 46 +++++++++++++++++++++++++++++++++++++++
31
hw/i2c/aspeed_i2c.c | 197 ++++++++++++++++++++++++++++++++----
12
1 file changed, 46 insertions(+)
32
2 files changed, 186 insertions(+), 19 deletions(-)
33
13
34
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
35
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/i2c/aspeed_i2c.h
16
--- a/hw/arm/xlnx-versal-virt.c
37
+++ b/include/hw/i2c/aspeed_i2c.h
17
+++ b/hw/arm/xlnx-versal-virt.c
38
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
39
OBJECT_CHECK(AspeedI2CState, (obj), TYPE_ASPEED_I2C)
19
#include "hw/arm/sysbus-fdt.h"
40
20
#include "hw/arm/fdt.h"
41
#define ASPEED_I2C_NR_BUSSES 16
21
#include "cpu.h"
42
+#define ASPEED_I2C_MAX_POOL_SIZE 0x800
22
+#include "hw/qdev-properties.h"
43
23
#include "hw/arm/xlnx-versal.h"
44
struct AspeedI2CState;
24
45
25
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
46
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
26
@@ -XXX,XX +XXX,XX @@ static void fdt_add_zdma_nodes(VersalVirt *s)
47
uint32_t intr_status;
27
}
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
}
28
}
128
29
129
+static int aspeed_i2c_bus_send(AspeedI2CBus *bus, uint8_t pool_start)
30
+static void fdt_add_sd_nodes(VersalVirt *s)
130
+{
31
+{
131
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
32
+ const char clocknames[] = "clk_xin\0clk_ahb";
132
+ int ret = -1;
33
+ const char compat[] = "arasan,sdhci-8.9a";
133
+ int i;
34
+ int i;
134
+
35
+
135
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
36
+ for (i = ARRAY_SIZE(s->soc.pmc.iou.sd) - 1; i >= 0; i--) {
136
+ for (i = pool_start; i < I2CD_POOL_TX_COUNT(bus->pool_ctrl); i++) {
37
+ uint64_t addr = MM_PMC_SD0 + MM_PMC_SD0_SIZE * i;
137
+ uint8_t *pool_base = aic->bus_pool_base(bus);
38
+ char *name = g_strdup_printf("/sdhci@%" PRIx64, addr);
138
+
39
+
139
+ ret = i2c_send(bus->bus, pool_base[i]);
40
+ qemu_fdt_add_subnode(s->fdt, name);
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
+
41
+
149
+ return ret;
42
+ qemu_fdt_setprop_cells(s->fdt, name, "clocks",
150
+}
43
+ s->phandle.clk_25Mhz, s->phandle.clk_25Mhz);
151
+
44
+ qemu_fdt_setprop(s->fdt, name, "clock-names",
152
+static void aspeed_i2c_bus_recv(AspeedI2CBus *bus)
45
+ clocknames, sizeof(clocknames));
153
+{
46
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
154
+ AspeedI2CState *s = bus->controller;
47
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_SD0_IRQ_0 + i * 2,
155
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
48
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
156
+ uint8_t data;
49
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
157
+ int i;
50
+ 2, addr, 2, MM_PMC_SD0_SIZE);
158
+
51
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
159
+ if (bus->cmd & I2CD_RX_BUFF_ENABLE) {
52
+ g_free(name);
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
+ }
53
+ }
174
+}
54
+}
175
+
55
+
176
static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
56
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
177
{
57
{
178
- uint8_t ret;
58
Error *err = NULL;
179
-
59
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
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
}
60
}
188
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_handle_rx_cmd(AspeedI2CBus *bus)
189
aspeed_i2c_set_state(bus, I2CD_MACTIVE);
190
}
61
}
191
62
192
+static uint8_t aspeed_i2c_get_addr(AspeedI2CBus *bus)
63
+static void sd_plugin_card(SDHCIState *sd, DriveInfo *di)
193
+{
64
+{
194
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
65
+ BlockBackend *blk = di ? blk_by_legacy_dinfo(di) : NULL;
66
+ DeviceState *card;
195
+
67
+
196
+ if (bus->cmd & I2CD_TX_BUFF_ENABLE) {
68
+ card = qdev_create(qdev_get_child_bus(DEVICE(sd), "sd-bus"), TYPE_SD_CARD);
197
+ uint8_t *pool_base = aic->bus_pool_base(bus);
69
+ object_property_add_child(OBJECT(sd), "card[*]", OBJECT(card),
198
+
70
+ &error_fatal);
199
+ return pool_base[0];
71
+ qdev_prop_set_drive(card, "drive", blk, &error_fatal);
200
+ } else {
72
+ object_property_set_bool(OBJECT(card), true, "realized", &error_fatal);
201
+ return bus->buf;
202
+ }
203
+}
73
+}
204
+
74
+
205
/*
75
static void versal_virt_init(MachineState *machine)
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
{
76
{
211
+ uint8_t pool_start = 0;
77
VersalVirt *s = XLNX_VERSAL_VIRT_MACHINE(machine);
212
+
78
int psci_conduit = QEMU_PSCI_CONDUIT_DISABLED;
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;
79
+ int i;
291
+
80
292
+ for (i = 0; i < size; i++) {
81
/*
293
+ ret |= (uint64_t) s->pool[offset + i] << (8 * i);
82
* If the user provides an Operating System to be loaded, we expect them
83
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
84
fdt_add_gic_nodes(s);
85
fdt_add_timer_nodes(s);
86
fdt_add_zdma_nodes(s);
87
+ fdt_add_sd_nodes(s);
88
fdt_add_cpu_nodes(s, psci_conduit);
89
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
90
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
91
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
92
memory_region_add_subregion_overlap(get_system_memory(),
93
0, &s->soc.fpd.apu.mr, 0);
94
95
+ /* Plugin SD cards. */
96
+ for (i = 0; i < ARRAY_SIZE(s->soc.pmc.iou.sd); i++) {
97
+ sd_plugin_card(&s->soc.pmc.iou.sd[i], drive_get_next(IF_SD));
294
+ }
98
+ }
295
+
99
+
296
+ return ret;
100
s->binfo.ram_size = machine->ram_size;
297
+}
101
s->binfo.loader_start = 0x0;
298
+
102
s->binfo.get_dtb = versal_virt_get_dtb;
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
--
103
--
434
2.20.1
104
2.20.1
435
105
436
106
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
2
3
Add probe_read alongside the write probing equivalent.
3
Add support for the RTC.
4
4
5
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20191121000843.24844-2-beata.michalska@linaro.org
8
Message-id: 20200427181649.26851-12-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/exec/exec-all.h | 6 ++++++
11
hw/arm/xlnx-versal-virt.c | 22 ++++++++++++++++++++++
12
1 file changed, 6 insertions(+)
12
1 file changed, 22 insertions(+)
13
13
14
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
14
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/exec-all.h
16
--- a/hw/arm/xlnx-versal-virt.c
17
+++ b/include/exec/exec-all.h
17
+++ b/hw/arm/xlnx-versal-virt.c
18
@@ -XXX,XX +XXX,XX @@ static inline void *probe_write(CPUArchState *env, target_ulong addr, int size,
18
@@ -XXX,XX +XXX,XX @@ static void fdt_add_sd_nodes(VersalVirt *s)
19
return probe_access(env, addr, size, MMU_DATA_STORE, mmu_idx, retaddr);
19
}
20
}
20
}
21
21
22
+static inline void *probe_read(CPUArchState *env, target_ulong addr, int size,
22
+static void fdt_add_rtc_node(VersalVirt *s)
23
+ int mmu_idx, uintptr_t retaddr)
24
+{
23
+{
25
+ return probe_access(env, addr, size, MMU_DATA_LOAD, mmu_idx, retaddr);
24
+ const char compat[] = "xlnx,zynqmp-rtc";
25
+ const char interrupt_names[] = "alarm\0sec";
26
+ char *name = g_strdup_printf("/rtc@%x", MM_PMC_RTC);
27
+
28
+ qemu_fdt_add_subnode(s->fdt, name);
29
+
30
+ qemu_fdt_setprop_cells(s->fdt, name, "interrupts",
31
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_ALARM_IRQ,
32
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI,
33
+ GIC_FDT_IRQ_TYPE_SPI, VERSAL_RTC_SECONDS_IRQ,
34
+ GIC_FDT_IRQ_FLAGS_LEVEL_HI);
35
+ qemu_fdt_setprop(s->fdt, name, "interrupt-names",
36
+ interrupt_names, sizeof(interrupt_names));
37
+ qemu_fdt_setprop_sized_cells(s->fdt, name, "reg",
38
+ 2, MM_PMC_RTC, 2, MM_PMC_RTC_SIZE);
39
+ qemu_fdt_setprop(s->fdt, name, "compatible", compat, sizeof(compat));
40
+ g_free(name);
26
+}
41
+}
27
+
42
+
28
#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
43
static void fdt_nop_memory_nodes(void *fdt, Error **errp)
29
44
{
30
/* Estimated block size for TB allocation. */
45
Error *err = NULL;
46
@@ -XXX,XX +XXX,XX @@ static void versal_virt_init(MachineState *machine)
47
fdt_add_timer_nodes(s);
48
fdt_add_zdma_nodes(s);
49
fdt_add_sd_nodes(s);
50
+ fdt_add_rtc_node(s);
51
fdt_add_cpu_nodes(s, psci_conduit);
52
fdt_add_clk_node(s, "/clk125", 125000000, s->phandle.clk_125Mhz);
53
fdt_add_clk_node(s, "/clk25", 25000000, s->phandle.clk_25Mhz);
31
--
54
--
32
2.20.1
55
2.20.1
33
56
34
57
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Somewhere along theline we accidentally added a duplicate
2
"using D16-D31 when they don't exist" check to do_vfm_dp()
3
(probably an artifact of a patchseries rebase). Remove it.
2
4
3
The Aspeed MII model has a link pointing to its associated FTGMAC100
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
NIC in the machine.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200430181003.21682-2-peter.maydell@linaro.org
9
---
10
target/arm/translate-vfp.inc.c | 6 ------
11
1 file changed, 6 deletions(-)
5
12
6
Change the "nic" property definition so that it explicitly sets the
13
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
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-18-clg@kaod.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/aspeed_ast2600.c | 5 ++---
18
hw/net/ftgmac100.c | 19 +++++++++----------
19
2 files changed, 11 insertions(+), 13 deletions(-)
20
21
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/aspeed_ast2600.c
15
--- a/target/arm/translate-vfp.inc.c
24
+++ b/hw/arm/aspeed_ast2600.c
16
+++ b/target/arm/translate-vfp.inc.c
25
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static bool do_vfm_dp(DisasContext *s, arg_VFMA_dp *a, bool neg_n, bool neg_d)
26
18
return false;
27
sysbus_init_child_obj(obj, "mii[*]", &s->mii[i], sizeof(s->mii[i]),
28
TYPE_ASPEED_MII);
29
- object_property_add_const_link(OBJECT(&s->mii[i]), "nic",
30
- OBJECT(&s->ftgmac100[i]),
31
- &error_abort);
32
}
19
}
33
20
34
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
21
- /* UNDEF accesses to D16-D31 if they don't exist. */
35
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
22
- if (!dc_isar_feature(aa32_simd_r32, s) &&
36
sysbus_connect_irq(SYS_BUS_DEVICE(&s->ftgmac100[i]), 0,
23
- ((a->vd | a->vn | a->vm) & 0x10)) {
37
aspeed_soc_get_irq(s, ASPEED_ETH1 + i));
24
- return false;
38
39
+ object_property_set_link(OBJECT(&s->mii[i]), OBJECT(&s->ftgmac100[i]),
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;
60
- }
25
- }
61
-
26
-
62
- s->nic = FTGMAC100(obj);
27
if (!vfp_access_check(s)) {
63
+ assert(s->nic);
28
return true;
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
}
29
}
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 = {
89
--
30
--
90
2.20.1
31
2.20.1
91
32
92
33
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
We were accidentally permitting decode of Thumb Neon insns even if
2
the CPU didn't have the FEATURE_NEON bit set, because the feature
3
check was being done before the call to disas_neon_data_insn() and
4
disas_neon_ls_insn() in the Arm decoder but was omitted from the
5
Thumb decoder. Push the feature bit check down into the called
6
functions so it is done for both Arm and Thumb encodings.
2
7
3
HCR_EL2.TID1 mandates that access from EL1 to REVIDR_EL1, AIDR_EL1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
(and their 32bit equivalents) as well as TCMTR, TLBTR are trapped
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
to EL2. QEMU ignores it, making it harder for a hypervisor to
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
virtualize the HW (though to be fair, no known hypervisor actually
11
Message-id: 20200430181003.21682-3-peter.maydell@linaro.org
7
cares).
12
---
13
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 8 deletions(-)
8
15
9
Do the right thing by trapping to EL2 if HCR_EL2.TID1 is set.
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 36 ++++++++++++++++++++++++++++++++----
18
1 file changed, 32 insertions(+), 4 deletions(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
18
--- a/target/arm/translate.c
23
+++ b/target/arm/helper.c
19
+++ b/target/arm/translate.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri)
20
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
25
return ret;
21
TCGv_i32 tmp2;
26
}
22
TCGv_i64 tmp64;
27
23
28
+static CPAccessResult access_aa64_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
24
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
29
+ bool isread)
25
+ return 1;
30
+{
31
+ if (arm_current_el(env) == 1 && (arm_hcr_el2_eff(env) & HCR_TID1)) {
32
+ return CP_ACCESS_TRAP_EL2;
33
+ }
26
+ }
34
+
27
+
35
+ return CP_ACCESS_OK;
28
/* FIXME: this access check should not take precedence over UNDEF
36
+}
29
* for invalid encodings; we will generate incorrect syndrome information
37
+
30
* for attempts to execute invalid vfp/neon encodings with FP disabled.
38
+static CPAccessResult access_aa32_tid1(CPUARMState *env, const ARMCPRegInfo *ri,
31
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
39
+ bool isread)
32
TCGv_ptr ptr1, ptr2, ptr3;
40
+{
33
TCGv_i64 tmp64;
41
+ if (arm_feature(env, ARM_FEATURE_V8)) {
34
42
+ return access_aa64_tid1(env, ri, isread);
35
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
36
+ return 1;
43
+ }
37
+ }
44
+
38
+
45
+ return CP_ACCESS_OK;
39
/* FIXME: this access check should not take precedence over UNDEF
46
+}
40
* for invalid encodings; we will generate incorrect syndrome information
47
+
41
* for attempts to execute invalid vfp/neon encodings with FP disabled.
48
static const ARMCPRegInfo v7_cp_reginfo[] = {
42
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
49
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
43
50
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
44
if (((insn >> 25) & 7) == 1) {
51
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
45
/* NEON Data processing. */
52
*/
46
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
53
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
47
- goto illegal_op;
54
.opc0 = 3, .opc1 = 1, .crn = 0, .crm = 0, .opc2 = 7,
48
- }
55
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
49
-
56
+ .access = PL1_R, .type = ARM_CP_CONST,
50
if (disas_neon_data_insn(s, insn)) {
57
+ .accessfn = access_aa64_tid1,
51
goto illegal_op;
58
+ .resetvalue = 0 },
52
}
59
/* Auxiliary fault status registers: these also are IMPDEF, and we
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
60
* choose to RAZ/WI for all cores.
54
}
61
*/
55
if ((insn & 0x0f100000) == 0x04000000) {
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
56
/* NEON load/store. */
63
.access = PL1_R, .resetvalue = cpu->midr },
57
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
64
{ .name = "REVIDR_EL1", .state = ARM_CP_STATE_BOTH,
58
- goto illegal_op;
65
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 0, .opc2 = 6,
59
- }
66
- .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
60
-
67
+ .access = PL1_R,
61
if (disas_neon_ls_insn(s, insn)) {
68
+ .accessfn = access_aa64_tid1,
62
goto illegal_op;
69
+ .type = ARM_CP_CONST, .resetvalue = cpu->revidr },
63
}
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 = {
94
--
64
--
95
2.20.1
65
2.20.1
96
66
97
67
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Add the infrastructure for building and invoking a decodetree decoder
2
2
for the AArch32 Neon encodings. At the moment the new decoder covers
3
The I2C controller of the Aspeed AST2500 and AST2600 SoCs supports DMA
3
nothing, so we always fall back to the existing hand-written decode.
4
transfers to and from DRAM.
4
5
5
We follow the same pattern we did for the VFP decodetree conversion
6
A pair of registers defines the buffer address and the length of the
6
(commit 78e138bc1f672c145ef6ace74617d and following): code that deals
7
DMA transfer. The address should be aligned on 4 bytes and the maximum
7
with Neon will be moving gradually out to translate-neon.vfp.inc,
8
length should not exceed 4K. The receive or transmit DMA transfer can
8
which we #include into translate.c.
9
then be initiated with specific bits in the Command/Status register of
9
10
the controller.
10
In order to share the decode files between A32 and T32, we
11
11
split Neon into 3 parts:
12
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
* data-processing
13
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
* load-store
14
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
14
* 'shared' encodings
15
Signed-off-by: Cédric Le Goater <clg@kaod.org>
15
16
Message-id: 20191119141211.25716-5-clg@kaod.org
16
The first two groups of instructions have similar but not identical
17
A32 and T32 encodings, so we need to manually transform the T32
18
encoding into the A32 one before calling the decoder; the third group
19
covers the Neon instructions which are identical in A32 and T32.
20
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20200430181003.21682-4-peter.maydell@linaro.org
18
---
24
---
19
include/hw/i2c/aspeed_i2c.h | 5 ++
25
target/arm/neon-dp.decode | 29 ++++++++++++++++++++++++++
20
hw/arm/aspeed_ast2600.c | 5 ++
26
target/arm/neon-ls.decode | 29 ++++++++++++++++++++++++++
21
hw/arm/aspeed_soc.c | 5 ++
27
target/arm/neon-shared.decode | 27 +++++++++++++++++++++++++
22
hw/i2c/aspeed_i2c.c | 126 +++++++++++++++++++++++++++++++++++-
28
target/arm/translate-neon.inc.c | 32 +++++++++++++++++++++++++++++
23
4 files changed, 138 insertions(+), 3 deletions(-)
29
target/arm/translate.c | 36 +++++++++++++++++++++++++++++++--
24
30
target/arm/Makefile.objs | 18 +++++++++++++++++
25
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
31
6 files changed, 169 insertions(+), 2 deletions(-)
32
create mode 100644 target/arm/neon-dp.decode
33
create mode 100644 target/arm/neon-ls.decode
34
create mode 100644 target/arm/neon-shared.decode
35
create mode 100644 target/arm/translate-neon.inc.c
36
37
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/target/arm/neon-dp.decode
42
@@ -XXX,XX +XXX,XX @@
43
+# AArch32 Neon data-processing instruction descriptions
44
+#
45
+# Copyright (c) 2020 Linaro, Ltd
46
+#
47
+# This library is free software; you can redistribute it and/or
48
+# modify it under the terms of the GNU Lesser General Public
49
+# License as published by the Free Software Foundation; either
50
+# version 2 of the License, or (at your option) any later version.
51
+#
52
+# This library is distributed in the hope that it will be useful,
53
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
55
+# Lesser General Public License for more details.
56
+#
57
+# You should have received a copy of the GNU Lesser General Public
58
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
59
+
60
+#
61
+# This file is processed by scripts/decodetree.py
62
+#
63
+
64
+# Encodings for Neon data processing instructions where the T32 encoding
65
+# is a simple transformation of the A32 encoding.
66
+# More specifically, this file covers instructions where the A32 encoding is
67
+# 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
68
+# and the T32 encoding is
69
+# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
70
+# This file works on the A32 encoding only; calling code for T32 has to
71
+# transform the insn into the A32 version first.
72
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
73
new file mode 100644
74
index XXXXXXX..XXXXXXX
75
--- /dev/null
76
+++ b/target/arm/neon-ls.decode
77
@@ -XXX,XX +XXX,XX @@
78
+# AArch32 Neon load/store instruction descriptions
79
+#
80
+# Copyright (c) 2020 Linaro, Ltd
81
+#
82
+# This library is free software; you can redistribute it and/or
83
+# modify it under the terms of the GNU Lesser General Public
84
+# License as published by the Free Software Foundation; either
85
+# version 2 of the License, or (at your option) any later version.
86
+#
87
+# This library is distributed in the hope that it will be useful,
88
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
89
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
90
+# Lesser General Public License for more details.
91
+#
92
+# You should have received a copy of the GNU Lesser General Public
93
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
94
+
95
+#
96
+# This file is processed by scripts/decodetree.py
97
+#
98
+
99
+# Encodings for Neon load/store instructions where the T32 encoding
100
+# is a simple transformation of the A32 encoding.
101
+# More specifically, this file covers instructions where the A32 encoding is
102
+# 0b1111_0100_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
103
+# and the T32 encoding is
104
+# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
105
+# This file works on the A32 encoding only; calling code for T32 has to
106
+# transform the insn into the A32 version first.
107
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/target/arm/neon-shared.decode
112
@@ -XXX,XX +XXX,XX @@
113
+# AArch32 Neon instruction descriptions
114
+#
115
+# Copyright (c) 2020 Linaro, Ltd
116
+#
117
+# This library is free software; you can redistribute it and/or
118
+# modify it under the terms of the GNU Lesser General Public
119
+# License as published by the Free Software Foundation; either
120
+# version 2 of the License, or (at your option) any later version.
121
+#
122
+# This library is distributed in the hope that it will be useful,
123
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
124
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
125
+# Lesser General Public License for more details.
126
+#
127
+# You should have received a copy of the GNU Lesser General Public
128
+# License along with this library; if not, see <http://www.gnu.org/licenses/>.
129
+
130
+#
131
+# This file is processed by scripts/decodetree.py
132
+#
133
+
134
+# Encodings for Neon instructions whose encoding is the same for
135
+# both A32 and T32.
136
+
137
+# More specifically, this covers:
138
+# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
139
+# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
140
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
141
new file mode 100644
142
index XXXXXXX..XXXXXXX
143
--- /dev/null
144
+++ b/target/arm/translate-neon.inc.c
145
@@ -XXX,XX +XXX,XX @@
146
+/*
147
+ * ARM translation: AArch32 Neon instructions
148
+ *
149
+ * Copyright (c) 2003 Fabrice Bellard
150
+ * Copyright (c) 2005-2007 CodeSourcery
151
+ * Copyright (c) 2007 OpenedHand, Ltd.
152
+ * Copyright (c) 2020 Linaro, Ltd.
153
+ *
154
+ * This library is free software; you can redistribute it and/or
155
+ * modify it under the terms of the GNU Lesser General Public
156
+ * License as published by the Free Software Foundation; either
157
+ * version 2 of the License, or (at your option) any later version.
158
+ *
159
+ * This library is distributed in the hope that it will be useful,
160
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
161
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
162
+ * Lesser General Public License for more details.
163
+ *
164
+ * You should have received a copy of the GNU Lesser General Public
165
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
166
+ */
167
+
168
+/*
169
+ * This file is intended to be included from translate.c; it uses
170
+ * some macros and definitions provided by that file.
171
+ * It might be possible to convert it to a standalone .c file eventually.
172
+ */
173
+
174
+/* Include the generated Neon decoder */
175
+#include "decode-neon-dp.inc.c"
176
+#include "decode-neon-ls.inc.c"
177
+#include "decode-neon-shared.inc.c"
178
diff --git a/target/arm/translate.c b/target/arm/translate.c
26
index XXXXXXX..XXXXXXX 100644
179
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/i2c/aspeed_i2c.h
180
--- a/target/arm/translate.c
28
+++ b/include/hw/i2c/aspeed_i2c.h
181
+++ b/target/arm/translate.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CBus {
182
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
30
uint32_t cmd;
183
31
uint32_t buf;
184
#define ARM_CP_RW_BIT (1 << 20)
32
uint32_t pool_ctrl;
185
33
+ uint32_t dma_addr;
186
-/* Include the VFP decoder */
34
+ uint32_t dma_len;
187
+/* Include the VFP and Neon decoders */
35
} AspeedI2CBus;
188
#include "translate-vfp.inc.c"
36
189
+#include "translate-neon.inc.c"
37
typedef struct AspeedI2CState {
190
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
191
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
39
uint8_t pool[ASPEED_I2C_MAX_POOL_SIZE];
192
{
40
193
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
41
AspeedI2CBus busses[ASPEED_I2C_NR_BUSSES];
194
/* Unconditional instructions. */
42
+ MemoryRegion *dram_mr;
195
/* TODO: Perhaps merge these into one decodetree output file. */
43
+ AddressSpace dram_as;
196
if (disas_a32_uncond(s, insn) ||
44
} AspeedI2CState;
197
- disas_vfp_uncond(s, insn)) {
45
198
+ disas_vfp_uncond(s, insn) ||
46
#define ASPEED_I2C_CLASS(klass) \
199
+ disas_neon_dp(s, insn) ||
47
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CClass {
200
+ disas_neon_ls(s, insn) ||
48
hwaddr pool_base;
201
+ disas_neon_shared(s, insn)) {
49
uint8_t *(*bus_pool_base)(AspeedI2CBus *);
202
return;
50
bool check_sram;
203
}
51
+ bool has_dma;
204
/* fall back to legacy decoder */
52
205
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
53
} AspeedI2CClass;
206
ARCH(6T2);
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
}
207
}
61
208
62
/* I2C */
209
+ if ((insn & 0xef000000) == 0xef000000) {
63
+ object_property_set_link(OBJECT(&s->i2c), OBJECT(s->dram_mr), "dram", &err);
210
+ /*
64
+ if (err) {
211
+ * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
65
+ error_propagate(errp, err);
212
+ * transform into
66
+ return;
213
+ * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
67
+ }
214
+ */
68
object_property_set_bool(OBJECT(&s->i2c), true, "realized", &err);
215
+ uint32_t a32_insn = (insn & 0xe2ffffff) |
69
if (err) {
216
+ ((insn & (1 << 28)) >> 4) | (1 << 28);
70
error_propagate(errp, err);
217
+
71
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
218
+ if (disas_neon_dp(s, a32_insn)) {
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;
219
+ return;
304
+ }
220
+ }
305
+
306
+ address_space_init(&s->dram_as, s->dram_mr, "dma-dram");
307
+ }
221
+ }
308
}
222
+
309
223
+ if ((insn & 0xff100000) == 0xf9000000) {
310
+static Property aspeed_i2c_properties[] = {
224
+ /*
311
+ DEFINE_PROP_LINK("dram", AspeedI2CState, dram_mr,
225
+ * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
312
+ TYPE_MEMORY_REGION, MemoryRegion *),
226
+ * transform into
313
+ DEFINE_PROP_END_OF_LIST(),
227
+ * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
314
+};
228
+ */
315
+
229
+ uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
316
static void aspeed_i2c_class_init(ObjectClass *klass, void *data)
230
+
317
{
231
+ if (disas_neon_ls(s, a32_insn)) {
318
DeviceClass *dc = DEVICE_CLASS(klass);
232
+ return;
319
233
+ }
320
dc->vmsd = &aspeed_i2c_vmstate;
234
+ }
321
dc->reset = aspeed_i2c_reset;
235
+
322
+ dc->props = aspeed_i2c_properties;
236
/*
323
dc->realize = aspeed_i2c_realize;
237
* TODO: Perhaps merge these into one decodetree output file.
324
dc->desc = "Aspeed I2C Controller";
238
* Note disas_vfp is written for a32 with cond field in the
325
}
239
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
326
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
240
*/
327
aic->pool_base = 0x200;
241
if (disas_t32(s, insn) ||
328
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
242
disas_vfp_uncond(s, insn) ||
329
aic->check_sram = true;
243
+ disas_neon_shared(s, insn) ||
330
+ aic->has_dma = true;
244
((insn >> 28) == 0xe && disas_vfp(s, insn))) {
331
}
245
return;
332
246
}
333
static const TypeInfo aspeed_2500_i2c_info = {
247
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
334
@@ -XXX,XX +XXX,XX @@ static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data)
248
index XXXXXXX..XXXXXXX 100644
335
aic->pool_size = 0x200;
249
--- a/target/arm/Makefile.objs
336
aic->pool_base = 0xC00;
250
+++ b/target/arm/Makefile.objs
337
aic->bus_pool_base = aspeed_2600_i2c_bus_pool_base;
251
@@ -XXX,XX +XXX,XX @@ target/arm/decode-sve.inc.c: $(SRC_PATH)/target/arm/sve.decode $(DECODETREE)
338
+ aic->has_dma = true;
252
     $(PYTHON) $(DECODETREE) --decode disas_sve -o $@ $<,\
339
}
253
     "GEN", $(TARGET_DIR)$@)
340
254
341
static const TypeInfo aspeed_2600_i2c_info = {
255
+target/arm/decode-neon-shared.inc.c: $(SRC_PATH)/target/arm/neon-shared.decode $(DECODETREE)
256
+    $(call quiet-command,\
257
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_shared -o $@ $<,\
258
+     "GEN", $(TARGET_DIR)$@)
259
+
260
+target/arm/decode-neon-dp.inc.c: $(SRC_PATH)/target/arm/neon-dp.decode $(DECODETREE)
261
+    $(call quiet-command,\
262
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_dp -o $@ $<,\
263
+     "GEN", $(TARGET_DIR)$@)
264
+
265
+target/arm/decode-neon-ls.inc.c: $(SRC_PATH)/target/arm/neon-ls.decode $(DECODETREE)
266
+    $(call quiet-command,\
267
+     $(PYTHON) $(DECODETREE) --static-decode disas_neon_ls -o $@ $<,\
268
+     "GEN", $(TARGET_DIR)$@)
269
+
270
target/arm/decode-vfp.inc.c: $(SRC_PATH)/target/arm/vfp.decode $(DECODETREE)
271
    $(call quiet-command,\
272
     $(PYTHON) $(DECODETREE) --static-decode disas_vfp -o $@ $<,\
273
@@ -XXX,XX +XXX,XX @@ target/arm/decode-t16.inc.c: $(SRC_PATH)/target/arm/t16.decode $(DECODETREE)
274
     "GEN", $(TARGET_DIR)$@)
275
276
target/arm/translate-sve.o: target/arm/decode-sve.inc.c
277
+target/arm/translate.o: target/arm/decode-neon-shared.inc.c
278
+target/arm/translate.o: target/arm/decode-neon-dp.inc.c
279
+target/arm/translate.o: target/arm/decode-neon-ls.inc.c
280
target/arm/translate.o: target/arm/decode-vfp.inc.c
281
target/arm/translate.o: target/arm/decode-vfp-uncond.inc.c
282
target/arm/translate.o: target/arm/decode-a32.inc.c
342
--
283
--
343
2.20.1
284
2.20.1
344
285
345
286
diff view generated by jsdifflib
New patch
1
Convert the VCMLA (vector) insns in the 3same extension group to
2
decodetree.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-5-peter.maydell@linaro.org
7
---
8
target/arm/neon-shared.decode | 11 ++++++++++
9
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 11 +---------
11
3 files changed, 49 insertions(+), 10 deletions(-)
12
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-shared.decode
16
+++ b/target/arm/neon-shared.decode
17
@@ -XXX,XX +XXX,XX @@
18
# More specifically, this covers:
19
# 2reg scalar ext: 0b1111_1110_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
20
# 3same ext: 0b1111_110x_xxxx_xxxx_xxxx_1x0x_xxxx_xxxx
21
+
22
+# VFP/Neon register fields; same as vfp.decode
23
+%vm_dp 5:1 0:4
24
+%vm_sp 0:4 5:1
25
+%vn_dp 7:1 16:4
26
+%vn_sp 16:4 7:1
27
+%vd_dp 22:1 12:4
28
+%vd_sp 12:4 22:1
29
+
30
+VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
31
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
32
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-neon.inc.c
35
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@
37
#include "decode-neon-dp.inc.c"
38
#include "decode-neon-ls.inc.c"
39
#include "decode-neon-shared.inc.c"
40
+
41
+static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
42
+{
43
+ int opr_sz;
44
+ TCGv_ptr fpst;
45
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
46
+
47
+ if (!dc_isar_feature(aa32_vcma, s)
48
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
49
+ return false;
50
+ }
51
+
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
54
+ ((a->vd | a->vn | a->vm) & 0x10)) {
55
+ return false;
56
+ }
57
+
58
+ if ((a->vn | a->vm | a->vd) & a->q) {
59
+ return false;
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ opr_sz = (1 + a->q) * 8;
67
+ fpst = get_fpstatus_ptr(1);
68
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
69
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
70
+ vfp_reg_offset(1, a->vn),
71
+ vfp_reg_offset(1, a->vm),
72
+ fpst, opr_sz, opr_sz, a->rot,
73
+ fn_gvec_ptr);
74
+ tcg_temp_free_ptr(fpst);
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
82
bool is_long = false, q = extract32(insn, 6, 1);
83
bool ptr_is_env = false;
84
85
- if ((insn & 0xfe200f10) == 0xfc200800) {
86
- /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
87
- int size = extract32(insn, 20, 1);
88
- data = extract32(insn, 23, 2); /* rot */
89
- if (!dc_isar_feature(aa32_vcma, s)
90
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
91
- return 1;
92
- }
93
- fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
94
- } else if ((insn & 0xfea00f10) == 0xfc800800) {
95
+ if ((insn & 0xfea00f10) == 0xfc800800) {
96
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
97
int size = extract32(insn, 20, 1);
98
data = extract32(insn, 24, 1); /* rot */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
New patch
1
Convert the VCADD (vector) insns to decodetree.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-6-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 3 +++
8
target/arm/translate-neon.inc.c | 37 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 11 +---------
10
3 files changed, 41 insertions(+), 10 deletions(-)
11
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-shared.decode
15
+++ b/target/arm/neon-shared.decode
16
@@ -XXX,XX +XXX,XX @@
17
18
VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
+
21
+VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-neon.inc.c
26
+++ b/target/arm/translate-neon.inc.c
27
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
28
tcg_temp_free_ptr(fpst);
29
return true;
30
}
31
+
32
+static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
33
+{
34
+ int opr_sz;
35
+ TCGv_ptr fpst;
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
37
+
38
+ if (!dc_isar_feature(aa32_vcma, s)
39
+ || (!a->size && !dc_isar_feature(aa32_fp16_arith, s))) {
40
+ return false;
41
+ }
42
+
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
45
+ ((a->vd | a->vn | a->vm) & 0x10)) {
46
+ return false;
47
+ }
48
+
49
+ if ((a->vn | a->vm | a->vd) & a->q) {
50
+ return false;
51
+ }
52
+
53
+ if (!vfp_access_check(s)) {
54
+ return true;
55
+ }
56
+
57
+ opr_sz = (1 + a->q) * 8;
58
+ fpst = get_fpstatus_ptr(1);
59
+ fn_gvec_ptr = a->size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
60
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->vm),
63
+ fpst, opr_sz, opr_sz, a->rot,
64
+ fn_gvec_ptr);
65
+ tcg_temp_free_ptr(fpst);
66
+ return true;
67
+}
68
diff --git a/target/arm/translate.c b/target/arm/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate.c
71
+++ b/target/arm/translate.c
72
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
73
bool is_long = false, q = extract32(insn, 6, 1);
74
bool ptr_is_env = false;
75
76
- if ((insn & 0xfea00f10) == 0xfc800800) {
77
- /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
78
- int size = extract32(insn, 20, 1);
79
- data = extract32(insn, 24, 1); /* rot */
80
- if (!dc_isar_feature(aa32_vcma, s)
81
- || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
82
- return 1;
83
- }
84
- fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
85
- } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
86
+ if ((insn & 0xfeb00f00) == 0xfc200d00) {
87
/* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
88
bool u = extract32(insn, 4, 1);
89
if (!dc_isar_feature(aa32_dp, s)) {
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert the V[US]DOT (vector) insns to decodetree.
2
2
3
Each CS has its own Read Timing Compensation Register on newer SoCs.
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-7-peter.maydell@linaro.org
6
---
7
target/arm/neon-shared.decode | 4 ++++
8
target/arm/translate-neon.inc.c | 32 ++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 9 +--------
10
3 files changed, 37 insertions(+), 8 deletions(-)
4
11
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
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
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/ssi/aspeed_smc.h | 1 +
12
hw/ssi/aspeed_smc.c | 17 ++++++++++++++---
13
2 files changed, 15 insertions(+), 3 deletions(-)
14
15
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/aspeed_smc.h
14
--- a/target/arm/neon-shared.decode
18
+++ b/include/hw/ssi/aspeed_smc.h
15
+++ b/target/arm/neon-shared.decode
19
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
16
@@ -XXX,XX +XXX,XX @@ VCMLA 1111 110 rot:2 . 1 size:1 .... .... 1000 . q:1 . 0 .... \
20
uint8_t r_ce_ctrl;
17
21
uint8_t r_ctrl0;
18
VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
uint8_t r_timings;
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp
23
+ uint8_t nregs_timings;
20
+
24
uint8_t conf_enable_w0;
21
+# VUDOT and VSDOT
25
uint8_t max_slaves;
22
+VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
26
const AspeedSegments *segments;
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
28
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/ssi/aspeed_smc.c
26
--- a/target/arm/translate-neon.inc.c
30
+++ b/hw/ssi/aspeed_smc.c
27
+++ b/target/arm/translate-neon.inc.c
31
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCADD(DisasContext *s, arg_VCADD *a)
32
/* Checksum Calculation Result */
29
tcg_temp_free_ptr(fpst);
33
#define R_DMA_CHECKSUM (0x90 / 4)
30
return true;
34
31
}
35
-/* Misc Control Register #2 */
32
+
36
+/* Read Timing Compensation Register */
33
+static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
37
#define R_TIMINGS (0x94 / 4)
34
+{
38
35
+ int opr_sz;
39
/* SPI controller registers and bits (AST2400) */
36
+ gen_helper_gvec_3 *fn_gvec;
40
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
37
+
41
.r_ce_ctrl = R_CE_CTRL,
38
+ if (!dc_isar_feature(aa32_dp, s)) {
42
.r_ctrl0 = R_CTRL0,
39
+ return false;
43
.r_timings = R_TIMINGS,
40
+ }
44
+ .nregs_timings = 1,
41
+
45
.conf_enable_w0 = CONF_ENABLE_W0,
42
+ /* UNDEF accesses to D16-D31 if they don't exist. */
46
.max_slaves = 5,
43
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
47
.segments = aspeed_segments_legacy,
44
+ ((a->vd | a->vn | a->vm) & 0x10)) {
48
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
45
+ return false;
49
.r_ce_ctrl = R_CE_CTRL,
46
+ }
50
.r_ctrl0 = R_CTRL0,
47
+
51
.r_timings = R_TIMINGS,
48
+ if ((a->vn | a->vm | a->vd) & a->q) {
52
+ .nregs_timings = 1,
49
+ return false;
53
.conf_enable_w0 = CONF_ENABLE_W0,
50
+ }
54
.max_slaves = 5,
51
+
55
.segments = aspeed_segments_fmc,
52
+ if (!vfp_access_check(s)) {
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
53
+ return true;
57
.r_ce_ctrl = 0xff,
54
+ }
58
.r_ctrl0 = R_SPI_CTRL0,
55
+
59
.r_timings = R_SPI_TIMINGS,
56
+ opr_sz = (1 + a->q) * 8;
60
+ .nregs_timings = 1,
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
61
.conf_enable_w0 = SPI_CONF_ENABLE_W0,
58
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
62
.max_slaves = 1,
59
+ vfp_reg_offset(1, a->vn),
63
.segments = aspeed_segments_spi,
60
+ vfp_reg_offset(1, a->vm),
64
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
61
+ opr_sz, opr_sz, 0, fn_gvec);
65
.r_ce_ctrl = R_CE_CTRL,
62
+ return true;
66
.r_ctrl0 = R_CTRL0,
63
+}
67
.r_timings = R_TIMINGS,
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
68
+ .nregs_timings = 1,
65
index XXXXXXX..XXXXXXX 100644
69
.conf_enable_w0 = CONF_ENABLE_W0,
66
--- a/target/arm/translate.c
70
.max_slaves = 3,
67
+++ b/target/arm/translate.c
71
.segments = aspeed_segments_ast2500_fmc,
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
72
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
69
bool is_long = false, q = extract32(insn, 6, 1);
73
.r_ce_ctrl = R_CE_CTRL,
70
bool ptr_is_env = false;
74
.r_ctrl0 = R_CTRL0,
71
75
.r_timings = R_TIMINGS,
72
- if ((insn & 0xfeb00f00) == 0xfc200d00) {
76
+ .nregs_timings = 1,
73
- /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
77
.conf_enable_w0 = CONF_ENABLE_W0,
74
- bool u = extract32(insn, 4, 1);
78
.max_slaves = 2,
75
- if (!dc_isar_feature(aa32_dp, s)) {
79
.segments = aspeed_segments_ast2500_spi1,
76
- return 1;
80
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
77
- }
81
.r_ce_ctrl = R_CE_CTRL,
78
- fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
82
.r_ctrl0 = R_CTRL0,
79
- } else if ((insn & 0xff300f10) == 0xfc200810) {
83
.r_timings = R_TIMINGS,
80
+ if ((insn & 0xff300f10) == 0xfc200810) {
84
+ .nregs_timings = 1,
81
/* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
85
.conf_enable_w0 = CONF_ENABLE_W0,
82
int is_s = extract32(insn, 23, 1);
86
.max_slaves = 2,
83
if (!dc_isar_feature(aa32_fhm, s)) {
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) {
132
--
84
--
133
2.20.1
85
2.20.1
134
86
135
87
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
Convert the VFM[AS]L (vector) insns to decodetree. This is the last
2
insn in the legacy decoder for the 3same_ext group, so we can
3
delete the legacy decoder function for the group entirely.
2
4
3
Make the gic a field in the machine state, and instead of filling
5
Note that in disas_thumb2_insn() the parts of this encoding space
4
an array of qemu_irq and passing it around, directly call
6
where the decodetree decoder returns false will correctly be directed
5
qdev_get_gpio_in() on the gic field.
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
6
9
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200430181003.21682-8-peter.maydell@linaro.org
12
---
13
---
13
include/hw/arm/virt.h | 1 +
14
target/arm/neon-shared.decode | 6 +++
14
hw/arm/virt.c | 109 +++++++++++++++++++++---------------------
15
target/arm/translate-neon.inc.c | 31 +++++++++++
15
2 files changed, 55 insertions(+), 55 deletions(-)
16
target/arm/translate.c | 92 +--------------------------------
17
3 files changed, 38 insertions(+), 91 deletions(-)
16
18
17
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/arm/virt.h
21
--- a/target/arm/neon-shared.decode
20
+++ b/include/hw/arm/virt.h
22
+++ b/target/arm/neon-shared.decode
21
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
@@ -XXX,XX +XXX,XX @@ VCADD 1111 110 rot:1 1 . 0 size:1 .... .... 1000 . q:1 . 0 .... \
22
uint32_t iommu_phandle;
24
# VUDOT and VSDOT
23
int psci_conduit;
25
VDOT 1111 110 00 . 10 .... .... 1101 . q:1 . u:1 .... \
24
hwaddr highest_gpa;
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
25
+ DeviceState *gic;
27
+
26
DeviceState *acpi_dev;
28
+# VFM[AS]L
27
Notifier powerdown_notifier;
29
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
28
} VirtMachineState;
30
+ vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
29
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
31
+VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
32
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/virt.c
35
--- a/target/arm/translate-neon.inc.c
32
+++ b/hw/arm/virt.c
36
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ static void fdt_add_pmu_nodes(const VirtMachineState *vms)
37
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT(DisasContext *s, arg_VDOT *a)
34
}
38
opr_sz, opr_sz, 0, fn_gvec);
39
return true;
35
}
40
}
36
41
+
37
-static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
42
+static bool trans_VFML(DisasContext *s, arg_VFML *a)
38
+static inline DeviceState *create_acpi_ged(VirtMachineState *vms)
43
+{
39
{
44
+ int opr_sz;
40
DeviceState *dev;
45
+
41
MachineState *ms = MACHINE(vms);
46
+ if (!dc_isar_feature(aa32_fhm, s)) {
42
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
47
+ return false;
43
48
+ }
44
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_ACPI_GED].base);
49
+
45
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, vms->memmap[VIRT_PCDIMM_ACPI].base);
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
46
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[irq]);
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, qdev_get_gpio_in(vms->gic, irq));
52
+ (a->vd & 0x10)) {
48
53
+ return false;
49
qdev_init_nofail(dev);
54
+ }
50
55
+
51
return dev;
56
+ if (a->vd & a->q) {
57
+ return false;
58
+ }
59
+
60
+ if (!vfp_access_check(s)) {
61
+ return true;
62
+ }
63
+
64
+ opr_sz = (1 + a->q) * 8;
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(a->q, a->vn),
67
+ vfp_reg_offset(a->q, a->vm),
68
+ cpu_env, opr_sz, opr_sz, a->s, /* is_2 == 0 */
69
+ gen_helper_gvec_fmlal_a32);
70
+ return true;
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
return 0;
52
}
78
}
53
79
54
-static void create_its(VirtMachineState *vms, DeviceState *gicdev)
80
-/* Advanced SIMD three registers of the same length extension.
55
+static void create_its(VirtMachineState *vms)
81
- * 31 25 23 22 20 16 12 11 10 9 8 3 0
56
{
82
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
57
const char *itsclass = its_class_name();
83
- * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
58
DeviceState *dev;
84
- * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
59
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
85
- */
60
86
-static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
61
dev = qdev_create(NULL, itsclass);
87
-{
62
88
- gen_helper_gvec_3 *fn_gvec = NULL;
63
- object_property_set_link(OBJECT(dev), OBJECT(gicdev), "parent-gicv3",
89
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
64
+ object_property_set_link(OBJECT(dev), OBJECT(vms->gic), "parent-gicv3",
90
- int rd, rn, rm, opr_sz;
65
&error_abort);
91
- int data = 0;
66
qdev_init_nofail(dev);
92
- int off_rn, off_rm;
67
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_GIC_ITS].base);
93
- bool is_long = false, q = extract32(insn, 6, 1);
68
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms, DeviceState *gicdev)
94
- bool ptr_is_env = false;
69
fdt_add_its_gic_node(vms);
95
-
70
}
96
- if ((insn & 0xff300f10) == 0xfc200810) {
71
97
- /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
72
-static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
98
- int is_s = extract32(insn, 23, 1);
73
+static void create_v2m(VirtMachineState *vms)
99
- if (!dc_isar_feature(aa32_fhm, s)) {
74
{
100
- return 1;
75
int i;
101
- }
76
int irq = vms->irqmap[VIRT_GIC_V2M];
102
- is_long = true;
77
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms, qemu_irq *pic)
103
- data = is_s; /* is_2 == 0 */
78
qdev_init_nofail(dev);
104
- fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
79
105
- ptr_is_env = true;
80
for (i = 0; i < NUM_GICV2M_SPIS; i++) {
106
- } else {
81
- sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, pic[irq + i]);
107
- return 1;
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
- }
108
- }
186
-
109
-
187
fdt_add_gic_node(vms);
110
- VFP_DREG_D(rd, insn);
188
111
- if (rd & q) {
189
if (type == 3 && vms->its) {
112
- return 1;
190
- create_its(vms, gicdev);
113
- }
191
+ create_its(vms);
114
- if (q || !is_long) {
192
} else if (type == 2) {
115
- VFP_DREG_N(rn, insn);
193
- create_v2m(vms, pic);
116
- VFP_DREG_M(rm, insn);
194
+ create_v2m(vms);
117
- if ((rn | rm) & q & !is_long) {
195
}
118
- return 1;
196
}
119
- }
197
120
- off_rn = vfp_reg_offset(1, rn);
198
-static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
121
- off_rm = vfp_reg_offset(1, rm);
199
+static void create_uart(const VirtMachineState *vms, int uart,
122
- } else {
200
MemoryRegion *mem, Chardev *chr)
123
- rn = VFP_SREG_N(insn);
201
{
124
- rm = VFP_SREG_M(insn);
202
char *nodename;
125
- off_rn = vfp_reg_offset(0, rn);
203
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
126
- off_rm = vfp_reg_offset(0, rm);
204
qdev_init_nofail(dev);
127
- }
205
memory_region_add_subregion(mem, base,
128
-
206
sysbus_mmio_get_region(s, 0));
129
- if (s->fp_excp_el) {
207
- sysbus_connect_irq(s, 0, pic[irq]);
130
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
208
+ sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq));
131
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
209
132
- return 0;
210
nodename = g_strdup_printf("/pl011@%" PRIx64, base);
133
- }
211
qemu_fdt_add_subnode(vms->fdt, nodename);
134
- if (!s->vfp_enabled) {
212
@@ -XXX,XX +XXX,XX @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart,
135
- return 1;
213
g_free(nodename);
136
- }
214
}
137
-
215
138
- opr_sz = (1 + q) * 8;
216
-static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
139
- if (fn_gvec_ptr) {
217
+static void create_rtc(const VirtMachineState *vms)
140
- TCGv_ptr ptr;
218
{
141
- if (ptr_is_env) {
219
char *nodename;
142
- ptr = cpu_env;
220
hwaddr base = vms->memmap[VIRT_RTC].base;
143
- } else {
221
@@ -XXX,XX +XXX,XX @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
144
- ptr = get_fpstatus_ptr(1);
222
int irq = vms->irqmap[VIRT_RTC];
145
- }
223
const char compat[] = "arm,pl031\0arm,primecell";
146
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
224
147
- opr_sz, opr_sz, data, fn_gvec_ptr);
225
- sysbus_create_simple("pl031", base, pic[irq]);
148
- if (!ptr_is_env) {
226
+ sysbus_create_simple("pl031", base, qdev_get_gpio_in(vms->gic, irq));
149
- tcg_temp_free_ptr(ptr);
227
150
- }
228
nodename = g_strdup_printf("/pl031@%" PRIx64, base);
151
- } else {
229
qemu_fdt_add_subnode(vms->fdt, nodename);
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
230
@@ -XXX,XX +XXX,XX @@ static void virt_powerdown_req(Notifier *n, void *opaque)
153
- opr_sz, opr_sz, data, fn_gvec);
231
}
154
- }
232
}
155
- return 0;
233
156
-}
234
-static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
157
-
235
+static void create_gpio(const VirtMachineState *vms)
158
/* Advanced SIMD two registers and a scalar extension.
236
{
159
* 31 24 23 22 20 16 12 11 10 9 8 3 0
237
char *nodename;
160
* +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
238
DeviceState *pl061_dev;
161
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
239
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
162
}
240
int irq = vms->irqmap[VIRT_GPIO];
163
}
241
const char compat[] = "arm,pl061\0arm,primecell";
164
}
242
165
- } else if ((insn & 0x0e000a00) == 0x0c000800
243
- pl061_dev = sysbus_create_simple("pl061", base, pic[irq]);
166
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
244
+ pl061_dev = sysbus_create_simple("pl061", base,
167
- if (disas_neon_insn_3same_ext(s, insn)) {
245
+ qdev_get_gpio_in(vms->gic, irq));
168
- goto illegal_op;
246
169
- }
247
uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt);
170
- return;
248
nodename = g_strdup_printf("/pl061@%" PRIx64, base);
171
} else if ((insn & 0x0f000a00) == 0x0e000800
249
@@ -XXX,XX +XXX,XX @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
172
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
250
g_free(nodename);
173
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
251
}
174
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
252
175
}
253
-static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
176
break;
254
+static void create_virtio_devices(const VirtMachineState *vms)
177
}
255
{
178
- if ((insn & 0xfe000a00) == 0xfc000800
256
int i;
179
+ if ((insn & 0xff000a00) == 0xfe000800
257
hwaddr size = vms->memmap[VIRT_MMIO].size;
180
&& arm_dc_feature(s, ARM_FEATURE_V8)) {
258
@@ -XXX,XX +XXX,XX @@ static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic)
181
/* The Thumb2 and ARM encodings are identical. */
259
int irq = vms->irqmap[VIRT_MMIO] + i;
182
- if (disas_neon_insn_3same_ext(s, insn)) {
260
hwaddr base = vms->memmap[VIRT_MMIO].base + i * size;
183
- goto illegal_op;
261
184
- }
262
- sysbus_create_simple("virtio-mmio", base, pic[irq]);
185
- } else if ((insn & 0xff000a00) == 0xfe000800
263
+ sysbus_create_simple("virtio-mmio", base,
186
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
264
+ qdev_get_gpio_in(vms->gic, irq));
187
- /* The Thumb2 and ARM encodings are identical. */
265
}
188
if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
266
189
goto illegal_op;
267
/* We add dtb nodes in reverse order so that they appear in the finished
190
}
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
--
191
--
394
2.20.1
192
2.20.1
395
193
396
194
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert VCMLA (scalar) in the 2reg-scalar-ext group to decodetree.
2
2
3
Currently, we link the DRAM memory region to the FMC model (for DMAs)
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
through a property alias at the SoC level. The I2C model will need a
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
similar region for DMA support, add a DRAM region property at the SoC
5
Message-id: 20200430181003.21682-9-peter.maydell@linaro.org
6
level for both model to use.
6
---
7
target/arm/neon-shared.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 40 +++++++++++++++++++++++++++++++++
9
target/arm/translate.c | 26 +--------------------
10
3 files changed, 46 insertions(+), 25 deletions(-)
7
11
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Tested-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>
11
Signed-off-by: Cédric Le Goater <clg@kaod.org>
12
Message-id: 20191119141211.25716-4-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/arm/aspeed_soc.h | 1 +
16
hw/arm/aspeed_ast2600.c | 7 +++++--
17
hw/arm/aspeed_soc.c | 9 +++++++--
18
3 files changed, 13 insertions(+), 4 deletions(-)
19
20
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
21
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/aspeed_soc.h
14
--- a/target/arm/neon-shared.decode
23
+++ b/include/hw/arm/aspeed_soc.h
15
+++ b/target/arm/neon-shared.decode
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
16
@@ -XXX,XX +XXX,XX @@ VFML 1111 110 0 s:1 . 10 .... .... 1000 . 0 . 1 .... \
25
ARMCPU cpu[ASPEED_CPUS_NUM];
17
vm=%vm_sp vn=%vn_sp vd=%vd_dp q=0
26
uint32_t num_cpus;
18
VFML 1111 110 0 s:1 . 10 .... .... 1000 . 1 . 1 .... \
27
A15MPPrivState a7mpcore;
19
vm=%vm_dp vn=%vn_dp vd=%vd_dp q=1
28
+ MemoryRegion *dram_mr;
20
+
29
MemoryRegion sram;
21
+VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
30
AspeedVICState vic;
22
+ vn=%vn_dp vd=%vd_dp size=0
31
AspeedRtcState rtc;
23
+VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
32
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
24
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
33
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/aspeed_ast2600.c
27
--- a/target/arm/translate-neon.inc.c
35
+++ b/hw/arm/aspeed_ast2600.c
28
+++ b/target/arm/translate-neon.inc.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_init(Object *obj)
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML(DisasContext *s, arg_VFML *a)
37
typename);
30
gen_helper_gvec_fmlal_a32);
38
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
31
return true;
39
&error_abort);
32
}
40
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
33
+
41
- &error_abort);
34
+static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
42
35
+{
43
for (i = 0; i < sc->spis_num; i++) {
36
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
44
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
37
+ int opr_sz;
45
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
38
+ TCGv_ptr fpst;
46
}
39
+
47
40
+ if (!dc_isar_feature(aa32_vcma, s)) {
48
/* FMC, The number of CS is set at the board level */
41
+ return false;
49
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
50
+ if (err) {
51
+ error_propagate(errp, err);
52
+ return;
53
+ }
42
+ }
54
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
43
+ if (a->size == 0 && !dc_isar_feature(aa32_fp16_arith, s)) {
55
"sdram-base", &err);
44
+ return false;
56
if (err) {
45
+ }
57
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
46
+
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
49
+ ((a->vd | a->vn | a->vm) & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if ((a->vd | a->vn) & a->q) {
54
+ return false;
55
+ }
56
+
57
+ if (!vfp_access_check(s)) {
58
+ return true;
59
+ }
60
+
61
+ fn_gvec_ptr = (a->size ? gen_helper_gvec_fcmlas_idx
62
+ : gen_helper_gvec_fcmlah_idx);
63
+ opr_sz = (1 + a->q) * 8;
64
+ fpst = get_fpstatus_ptr(1);
65
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
66
+ vfp_reg_offset(1, a->vn),
67
+ vfp_reg_offset(1, a->vm),
68
+ fpst, opr_sz, opr_sz,
69
+ (a->index << 2) | a->rot, fn_gvec_ptr);
70
+ tcg_temp_free_ptr(fpst);
71
+ return true;
72
+}
73
diff --git a/target/arm/translate.c b/target/arm/translate.c
58
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/aspeed_soc.c
75
--- a/target/arm/translate.c
60
+++ b/hw/arm/aspeed_soc.c
76
+++ b/target/arm/translate.c
61
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
77
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
62
typename);
78
bool is_long = false, q = extract32(insn, 6, 1);
63
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
79
bool ptr_is_env = false;
64
&error_abort);
80
65
- object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
81
- if ((insn & 0xff000f10) == 0xfe000800) {
66
- &error_abort);
82
- /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
67
83
- int rot = extract32(insn, 20, 2);
68
for (i = 0; i < sc->spis_num; i++) {
84
- int size = extract32(insn, 23, 1);
69
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
85
- int index;
70
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
86
-
71
aspeed_soc_get_irq(s, ASPEED_I2C));
87
- if (!dc_isar_feature(aa32_vcma, s)) {
72
88
- return 1;
73
/* FMC, The number of CS is set at the board level */
89
- }
74
+ object_property_set_link(OBJECT(&s->fmc), OBJECT(s->dram_mr), "dram", &err);
90
- if (size == 0) {
75
+ if (err) {
91
- if (!dc_isar_feature(aa32_fp16_arith, s)) {
76
+ error_propagate(errp, err);
92
- return 1;
77
+ return;
93
- }
78
+ }
94
- /* For fp16, rm is just Vm, and index is M. */
79
object_property_set_int(OBJECT(&s->fmc), sc->memmap[ASPEED_SDRAM],
95
- rm = extract32(insn, 0, 4);
80
"sdram-base", &err);
96
- index = extract32(insn, 5, 1);
81
if (err) {
97
- } else {
82
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
98
- /* For fp32, rm is the usual M:Vm, and index is 0. */
83
}
99
- VFP_DREG_M(rm, insn);
84
static Property aspeed_soc_properties[] = {
100
- index = 0;
85
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
101
- }
86
+ DEFINE_PROP_LINK("dram", AspeedSoCState, dram_mr, TYPE_MEMORY_REGION,
102
- data = (index << 2) | rot;
87
+ MemoryRegion *),
103
- fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
88
DEFINE_PROP_END_OF_LIST(),
104
- : gen_helper_gvec_fcmlah_idx);
89
};
105
- } else if ((insn & 0xffb00f00) == 0xfe200d00) {
106
+ if ((insn & 0xffb00f00) == 0xfe200d00) {
107
/* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
108
int u = extract32(insn, 4, 1);
90
109
91
--
110
--
92
2.20.1
111
2.20.1
93
112
94
113
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert the V[US]DOT (scalar) insns in the 2reg-scalar-ext group
2
to decodetree.
2
3
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>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-10-peter.maydell@linaro.org
10
---
7
---
11
hw/i2c/aspeed_i2c.c | 93 ++++++++++++++++++++++++++++++++++++++-------
8
target/arm/neon-shared.decode | 3 +++
12
hw/i2c/trace-events | 9 +++++
9
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
13
2 files changed, 89 insertions(+), 13 deletions(-)
10
target/arm/translate.c | 13 +-----------
11
3 files changed, 39 insertions(+), 12 deletions(-)
14
12
15
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
13
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/aspeed_i2c.c
15
--- a/target/arm/neon-shared.decode
18
+++ b/hw/i2c/aspeed_i2c.c
16
+++ b/target/arm/neon-shared.decode
19
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 0 . rot:2 .... .... 1000 . q:1 index:1 0 vm:4 \
20
#include "hw/i2c/aspeed_i2c.h"
18
vn=%vn_dp vd=%vd_dp size=0
21
#include "hw/irq.h"
19
VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
22
#include "hw/qdev-properties.h"
20
vm=%vm_dp vn=%vn_dp vd=%vd_dp size=1 index=0
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
+
21
+
38
bus->intr_status &= bus->intr_ctrl;
22
+VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
39
if (bus->intr_status) {
23
+ vm=%vm_dp vn=%vn_dp vd=%vd_dp
40
bus->controller->intr_status |= 1 << bus->id;
24
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_bus_read(void *opaque, hwaddr offset,
25
index XXXXXXX..XXXXXXX 100644
42
{
26
--- a/target/arm/translate-neon.inc.c
43
AspeedI2CBus *bus = opaque;
27
+++ b/target/arm/translate-neon.inc.c
44
AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(bus->controller);
28
@@ -XXX,XX +XXX,XX @@ static bool trans_VCMLA_scalar(DisasContext *s, arg_VCMLA_scalar *a)
45
+ uint64_t value = -1;
29
tcg_temp_free_ptr(fpst);
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;
30
return true;
166
}
31
}
167
32
+
168
+static void aspeed_i2c_bus_cmd_dump(AspeedI2CBus *bus)
33
+static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
169
+{
34
+{
170
+ g_autofree char *cmd_flags;
35
+ gen_helper_gvec_3 *fn_gvec;
171
+ uint32_t count;
36
+ int opr_sz;
37
+ TCGv_ptr fpst;
172
+
38
+
173
+ if (bus->cmd & (I2CD_RX_BUFF_ENABLE | I2CD_RX_BUFF_ENABLE)) {
39
+ if (!dc_isar_feature(aa32_dp, s)) {
174
+ count = I2CD_POOL_TX_COUNT(bus->pool_ctrl);
40
+ return false;
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
+ }
41
+ }
180
+
42
+
181
+ cmd_flags = g_strdup_printf("%s%s%s%s%s%s%s%s%s",
43
+ /* UNDEF accesses to D16-D31 if they don't exist. */
182
+ bus->cmd & I2CD_M_START_CMD ? "start|" : "",
44
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
183
+ bus->cmd & I2CD_RX_DMA_ENABLE ? "rxdma|" : "",
45
+ ((a->vd | a->vn) & 0x10)) {
184
+ bus->cmd & I2CD_TX_DMA_ENABLE ? "txdma|" : "",
46
+ return false;
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
+ }
47
+ }
205
+
48
+
206
if (bus->cmd & I2CD_M_START_CMD) {
49
+ if ((a->vd | a->vn) & a->q) {
207
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
50
+ return false;
208
I2CD_MSTARTR : I2CD_MSTART;
51
+ }
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
+
52
+
215
switch (offset) {
53
+ if (!vfp_access_check(s)) {
216
case I2CD_FUN_CTRL_REG:
54
+ return true;
217
if (value & I2CD_SLAVE_EN) {
55
+ }
218
diff --git a/hw/i2c/trace-events b/hw/i2c/trace-events
56
+
57
+ fn_gvec = a->u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
58
+ opr_sz = (1 + a->q) * 8;
59
+ fpst = get_fpstatus_ptr(1);
60
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, a->vd),
61
+ vfp_reg_offset(1, a->vn),
62
+ vfp_reg_offset(1, a->rm),
63
+ opr_sz, opr_sz, a->index, fn_gvec);
64
+ tcg_temp_free_ptr(fpst);
65
+ return true;
66
+}
67
diff --git a/target/arm/translate.c b/target/arm/translate.c
219
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/i2c/trace-events
69
--- a/target/arm/translate.c
221
+++ b/hw/i2c/trace-events
70
+++ b/target/arm/translate.c
222
@@ -XXX,XX +XXX,XX @@
71
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
223
i2c_event(const char *event, uint8_t address) "%s(addr:0x%02x)"
72
bool is_long = false, q = extract32(insn, 6, 1);
224
i2c_send(uint8_t address, uint8_t data) "send(addr:0x%02x) data:0x%02x"
73
bool ptr_is_env = false;
225
i2c_recv(uint8_t address, uint8_t data) "recv(addr:0x%02x) data:0x%02x"
74
226
+
75
- if ((insn & 0xffb00f00) == 0xfe200d00) {
227
+# aspeed_i2c.c
76
- /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
228
+
77
- int u = extract32(insn, 4, 1);
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"
78
-
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"
79
- if (!dc_isar_feature(aa32_dp, 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
80
- return 1;
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
81
- }
233
+aspeed_i2c_bus_send(const char *mode, int i, int count, uint8_t byte) "%s send %d/%d 0x%02x"
82
- fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
234
+aspeed_i2c_bus_recv(const char *mode, int i, int count, uint8_t byte) "%s recv %d/%d 0x%02x"
83
- /* rm is just Vm, and index is M. */
84
- data = extract32(insn, 5, 1); /* index */
85
- rm = extract32(insn, 0, 4);
86
- } else if ((insn & 0xffa00f10) == 0xfe000810) {
87
+ if ((insn & 0xffa00f10) == 0xfe000810) {
88
/* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
89
int is_s = extract32(insn, 20, 1);
90
int vm20 = extract32(insn, 0, 3);
235
--
91
--
236
2.20.1
92
2.20.1
237
93
238
94
diff view generated by jsdifflib
1
From: Beata Michalska <beata.michalska@linaro.org>
1
Convert the VFM[AS]L (scalar) insns in the 2reg-scalar-ext group
2
2
to decodetree. These are the last ones in the group so we can remove
3
Add an option to trigger memory writeback to sync given memory region
3
all the legacy decode for the group.
4
with the corresponding backing store, case one is available.
4
5
This extends the support for persistent memory, allowing syncing on-demand.
5
Note that in disas_thumb2_insn() the parts of this encoding space
6
6
where the decodetree decoder returns false will correctly be directed
7
Signed-off-by: Beata Michalska <beata.michalska@linaro.org>
7
to illegal_op by the "(insn & (1 << 28))" check so they won't fall
8
into disas_coproc_insn() by mistake.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20191121000843.24844-3-beata.michalska@linaro.org
12
Message-id: 20200430181003.21682-11-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
13
---
12
include/exec/memory.h | 6 ++++++
14
target/arm/neon-shared.decode | 7 +++
13
include/exec/ram_addr.h | 8 ++++++++
15
target/arm/translate-neon.inc.c | 32 ++++++++++
14
include/qemu/cutils.h | 1 +
16
target/arm/translate.c | 107 +-------------------------------
15
exec.c | 36 ++++++++++++++++++++++++++++++++++++
17
3 files changed, 40 insertions(+), 106 deletions(-)
16
memory.c | 12 ++++++++++++
18
17
util/cutils.c | 38 ++++++++++++++++++++++++++++++++++++++
19
diff --git a/target/arm/neon-shared.decode b/target/arm/neon-shared.decode
18
6 files changed, 101 insertions(+)
19
20
diff --git a/include/exec/memory.h b/include/exec/memory.h
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/include/exec/memory.h
21
--- a/target/arm/neon-shared.decode
23
+++ b/include/exec/memory.h
22
+++ b/target/arm/neon-shared.decode
24
@@ -XXX,XX +XXX,XX @@ void *memory_region_get_ram_ptr(MemoryRegion *mr);
23
@@ -XXX,XX +XXX,XX @@ VCMLA_scalar 1111 1110 1 . rot:2 .... .... 1000 . q:1 . 0 .... \
25
*/
24
26
void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize,
25
VDOT_scalar 1111 1110 0 . 10 .... .... 1101 . q:1 index:1 u:1 rm:4 \
27
Error **errp);
26
vm=%vm_dp vn=%vn_dp vd=%vd_dp
28
+/**
27
+
29
+ * memory_region_do_writeback: Trigger writeback for selected address range
28
+%vfml_scalar_q0_rm 0:3 5:1
30
+ * [addr, addr + size]
29
+%vfml_scalar_q1_index 5:1 3:1
31
+ *
30
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 0 . 1 index:1 ... \
32
+ */
31
+ rm=%vfml_scalar_q0_rm vn=%vn_sp vd=%vd_dp q=0
33
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size);
32
+VFML_scalar 1111 1110 0 . 0 s:1 .... .... 1000 . 1 . 1 . rm:3 \
34
33
+ index=%vfml_scalar_q1_index vn=%vn_dp vd=%vd_dp q=1
35
/**
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
35
index XXXXXXX..XXXXXXX 100644
39
--- a/include/exec/ram_addr.h
36
--- a/target/arm/translate-neon.inc.c
40
+++ b/include/exec/ram_addr.h
37
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ void qemu_ram_free(RAMBlock *block);
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VDOT_scalar(DisasContext *s, arg_VDOT_scalar *a)
42
39
tcg_temp_free_ptr(fpst);
43
int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp);
40
return true;
44
41
}
45
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length);
42
+
46
+
43
+static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
47
+/* Clear whole block of mem */
48
+static inline void qemu_ram_block_writeback(RAMBlock *block)
49
+{
44
+{
50
+ qemu_ram_writeback(block, 0, block->used_length);
45
+ int opr_sz;
46
+
47
+ if (!dc_isar_feature(aa32_fhm, s)) {
48
+ return false;
49
+ }
50
+
51
+ /* UNDEF accesses to D16-D31 if they don't exist. */
52
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
53
+ ((a->vd & 0x10) || (a->q && (a->vn & 0x10)))) {
54
+ return false;
55
+ }
56
+
57
+ if (a->vd & a->q) {
58
+ return false;
59
+ }
60
+
61
+ if (!vfp_access_check(s)) {
62
+ return true;
63
+ }
64
+
65
+ opr_sz = (1 + a->q) * 8;
66
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, a->vd),
67
+ vfp_reg_offset(a->q, a->vn),
68
+ vfp_reg_offset(a->q, a->rm),
69
+ cpu_env, opr_sz, opr_sz,
70
+ (a->index << 2) | a->s, /* is_2 == 0 */
71
+ gen_helper_gvec_fmlal_idx_a32);
72
+ return true;
51
+}
73
+}
52
+
74
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
75
index XXXXXXX..XXXXXXX 100644
58
--- a/include/qemu/cutils.h
76
--- a/target/arm/translate.c
59
+++ b/include/qemu/cutils.h
77
+++ b/target/arm/translate.c
60
@@ -XXX,XX +XXX,XX @@ const char *qemu_strchrnul(const char *s, int c);
78
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
61
#endif
79
}
62
time_t mktimegm(struct tm *tm);
80
63
int qemu_fdatasync(int fd);
81
#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
64
+int qemu_msync(void *addr, size_t length, int fd);
82
-#define VFP_SREG(insn, bigbit, smallbit) \
65
int fcntl_setfl(int fd, int flag);
83
- ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
66
int qemu_parse_fd(const char *param);
84
#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
67
int qemu_strtoi(const char *nptr, const char **endptr, int base,
85
if (dc_isar_feature(aa32_simd_r32, s)) { \
68
diff --git a/exec.c b/exec.c
86
reg = (((insn) >> (bigbit)) & 0x0f) \
69
index XXXXXXX..XXXXXXX 100644
87
@@ -XXX,XX +XXX,XX @@ static int disas_dsp_insn(DisasContext *s, uint32_t insn)
70
--- a/exec.c
88
reg = ((insn) >> (bigbit)) & 0x0f; \
71
+++ b/exec.c
89
}} while (0)
72
@@ -XXX,XX +XXX,XX @@
90
73
#include "exec/ram_addr.h"
91
-#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
74
#include "exec/log.h"
92
#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
75
93
-#define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
76
+#include "qemu/pmem.h"
94
#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
77
+
95
-#define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
78
#include "migration/vmstate.h"
96
#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
79
97
80
#include "qemu/range.h"
98
static void gen_neon_dup_low16(TCGv_i32 var)
81
@@ -XXX,XX +XXX,XX @@ int qemu_ram_resize(RAMBlock *block, ram_addr_t newsize, Error **errp)
99
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
82
return 0;
100
return 0;
83
}
101
}
84
102
85
+/*
103
-/* Advanced SIMD two registers and a scalar extension.
86
+ * Trigger sync on the given ram block for range [start, start + length]
104
- * 31 24 23 22 20 16 12 11 10 9 8 3 0
87
+ * with the backing store if one is available.
105
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
88
+ * Otherwise no-op.
106
- * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
89
+ * @Note: this is supposed to be a synchronous op.
107
- * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
90
+ */
108
- *
91
+void qemu_ram_writeback(RAMBlock *block, ram_addr_t start, ram_addr_t length)
109
- */
92
+{
110
-
93
+ void *addr = ramblock_ptr(block, start);
111
-static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
94
+
112
-{
95
+ /* The requested range should fit in within the block range */
113
- gen_helper_gvec_3 *fn_gvec = NULL;
96
+ g_assert((start + length) <= block->used_length);
114
- gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
97
+
115
- int rd, rn, rm, opr_sz, data;
98
+#ifdef CONFIG_LIBPMEM
116
- int off_rn, off_rm;
99
+ /* The lack of support for pmem should not block the sync */
117
- bool is_long = false, q = extract32(insn, 6, 1);
100
+ if (ramblock_is_pmem(block)) {
118
- bool ptr_is_env = false;
101
+ pmem_persist(addr, length);
119
-
102
+ return;
120
- if ((insn & 0xffa00f10) == 0xfe000810) {
103
+ }
121
- /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
104
+#endif
122
- int is_s = extract32(insn, 20, 1);
105
+ if (block->fd >= 0) {
123
- int vm20 = extract32(insn, 0, 3);
106
+ /**
124
- int vm3 = extract32(insn, 3, 1);
107
+ * Case there is no support for PMEM or the memory has not been
125
- int m = extract32(insn, 5, 1);
108
+ * specified as persistent (or is not one) - use the msync.
126
- int index;
109
+ * Less optimal but still achieves the same goal
127
-
110
+ */
128
- if (!dc_isar_feature(aa32_fhm, s)) {
111
+ if (qemu_msync(addr, length, block->fd)) {
129
- return 1;
112
+ warn_report("%s: failed to sync memory range: start: "
130
- }
113
+ RAM_ADDR_FMT " length: " RAM_ADDR_FMT,
131
- if (q) {
114
+ __func__, start, length);
132
- rm = vm20;
115
+ }
133
- index = m * 2 + vm3;
116
+ }
134
- } else {
117
+}
135
- rm = vm20 * 2 + m;
118
+
136
- index = vm3;
119
/* Called with ram_list.mutex held */
137
- }
120
static void dirty_memory_extend(ram_addr_t old_ram_size,
138
- is_long = true;
121
ram_addr_t new_ram_size)
139
- data = (index << 2) | is_s; /* is_2 == 0 */
122
diff --git a/memory.c b/memory.c
140
- fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
123
index XXXXXXX..XXXXXXX 100644
141
- ptr_is_env = true;
124
--- a/memory.c
142
- } else {
125
+++ b/memory.c
143
- return 1;
126
@@ -XXX,XX +XXX,XX @@ void memory_region_ram_resize(MemoryRegion *mr, ram_addr_t newsize, Error **errp
144
- }
127
qemu_ram_resize(mr->ram_block, newsize, errp);
145
-
128
}
146
- VFP_DREG_D(rd, insn);
129
147
- if (rd & q) {
130
+
148
- return 1;
131
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
149
- }
132
+{
150
- if (q || !is_long) {
133
+ /*
151
- VFP_DREG_N(rn, insn);
134
+ * Might be extended case needed to cover
152
- if (rn & q & !is_long) {
135
+ * different types of memory regions
153
- return 1;
136
+ */
154
- }
137
+ if (mr->ram_block && mr->dirty_log_mask) {
155
- off_rn = vfp_reg_offset(1, rn);
138
+ qemu_ram_writeback(mr->ram_block, addr, size);
156
- off_rm = vfp_reg_offset(1, rm);
139
+ }
157
- } else {
140
+}
158
- rn = VFP_SREG_N(insn);
141
+
159
- off_rn = vfp_reg_offset(0, rn);
142
/*
160
- off_rm = vfp_reg_offset(0, rm);
143
* Call proper memory listeners about the change on the newly
161
- }
144
* added/removed CoalescedMemoryRange.
162
- if (s->fp_excp_el) {
145
diff --git a/util/cutils.c b/util/cutils.c
163
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
146
index XXXXXXX..XXXXXXX 100644
164
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
147
--- a/util/cutils.c
165
- return 0;
148
+++ b/util/cutils.c
166
- }
149
@@ -XXX,XX +XXX,XX @@ int qemu_fdatasync(int fd)
167
- if (!s->vfp_enabled) {
150
#endif
168
- return 1;
151
}
169
- }
152
170
-
153
+/**
171
- opr_sz = (1 + q) * 8;
154
+ * Sync changes made to the memory mapped file back to the backing
172
- if (fn_gvec_ptr) {
155
+ * storage. For POSIX compliant systems this will fallback
173
- TCGv_ptr ptr;
156
+ * to regular msync call. Otherwise it will trigger whole file sync
174
- if (ptr_is_env) {
157
+ * (including the metadata case there is no support to skip that otherwise)
175
- ptr = cpu_env;
158
+ *
176
- } else {
159
+ * @addr - start of the memory area to be synced
177
- ptr = get_fpstatus_ptr(1);
160
+ * @length - length of the are to be synced
178
- }
161
+ * @fd - file descriptor for the file to be synced
179
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
162
+ * (mandatory only for POSIX non-compliant systems)
180
- opr_sz, opr_sz, data, fn_gvec_ptr);
163
+ */
181
- if (!ptr_is_env) {
164
+int qemu_msync(void *addr, size_t length, int fd)
182
- tcg_temp_free_ptr(ptr);
165
+{
183
- }
166
+#ifdef CONFIG_POSIX
184
- } else {
167
+ size_t align_mask = ~(qemu_real_host_page_size - 1);
185
- tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
168
+
186
- opr_sz, opr_sz, data, fn_gvec);
169
+ /**
187
- }
170
+ * There are no strict reqs as per the length of mapping
188
- return 0;
171
+ * to be synced. Still the length needs to follow the address
189
-}
172
+ * alignment changes. Additionally - round the size to the multiple
190
-
173
+ * of PAGE_SIZE
191
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
174
+ */
192
{
175
+ length += ((uintptr_t)addr & (qemu_real_host_page_size - 1));
193
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
176
+ length = (length + ~align_mask) & align_mask;
194
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
177
+
195
}
178
+ addr = (void *)((uintptr_t)addr & align_mask);
196
}
179
+
197
}
180
+ return msync(addr, length, MS_SYNC);
198
- } else if ((insn & 0x0f000a00) == 0x0e000800
181
+#else /* CONFIG_POSIX */
199
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
182
+ /**
200
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
183
+ * Perform the sync based on the file descriptor
201
- goto illegal_op;
184
+ * The sync range will most probably be wider than the one
202
- }
185
+ * requested - but it will still get the job done
203
- return;
186
+ */
204
}
187
+ return qemu_fdatasync(fd);
205
goto illegal_op;
188
+#endif /* CONFIG_POSIX */
206
}
189
+}
207
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
190
+
208
}
191
#ifndef _WIN32
209
break;
192
/* Sets a specific flag */
210
}
193
int fcntl_setfl(int fd, int flag)
211
- if ((insn & 0xff000a00) == 0xfe000800
212
- && arm_dc_feature(s, ARM_FEATURE_V8)) {
213
- /* The Thumb2 and ARM encodings are identical. */
214
- if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
215
- goto illegal_op;
216
- }
217
- } else if (((insn >> 24) & 3) == 3) {
218
+ if (((insn >> 24) & 3) == 3) {
219
/* Translate into the equivalent ARM encoding. */
220
insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
221
if (disas_neon_data_insn(s, insn)) {
194
--
222
--
195
2.20.1
223
2.20.1
196
224
197
225
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert the Neon "load/store multiple structures" insns to decodetree.
2
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>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200430181003.21682-12-peter.maydell@linaro.org
11
---
6
---
12
include/hw/arm/aspeed.h | 24 ++--
7
target/arm/neon-ls.decode | 7 ++
13
hw/arm/aspeed.c | 243 ++++++++++++++++++++++------------------
8
target/arm/translate-neon.inc.c | 124 ++++++++++++++++++++++++++++++++
14
2 files changed, 143 insertions(+), 124 deletions(-)
9
target/arm/translate.c | 91 +----------------------
15
10
3 files changed, 133 insertions(+), 89 deletions(-)
16
diff --git a/include/hw/arm/aspeed.h b/include/hw/arm/aspeed.h
11
12
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed.h
14
--- a/target/arm/neon-ls.decode
19
+++ b/include/hw/arm/aspeed.h
15
+++ b/target/arm/neon-ls.decode
20
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
21
17
# 0b1111_1001_xxx0_xxxx_xxxx_xxxx_xxxx_xxxx
22
typedef struct AspeedBoardState AspeedBoardState;
18
# This file works on the A32 encoding only; calling code for T32 has to
23
19
# transform the insn into the A32 version first.
24
-typedef struct AspeedBoardConfig {
20
+
25
- const char *name;
21
+%vd_dp 22:1 12:4
26
- const char *desc;
22
+
27
- const char *soc_name;
23
+# Neon load/store multiple structures
28
- uint32_t hw_strap1;
24
+
29
- uint32_t hw_strap2;
25
+VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
30
- const char *fmc_model;
26
+ vd=%vd_dp
31
- const char *spi_model;
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
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
28
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/aspeed.c
29
--- a/target/arm/translate-neon.inc.c
61
+++ b/hw/arm/aspeed.c
30
+++ b/target/arm/translate-neon.inc.c
62
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype,
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VFML_scalar(DisasContext *s, arg_VFML_scalar *a)
63
}
32
gen_helper_gvec_fmlal_idx_a32);
33
return true;
64
}
34
}
65
35
+
66
-static void aspeed_board_init(MachineState *machine,
36
+static struct {
67
- const AspeedBoardConfig *cfg)
37
+ int nregs;
68
+static void aspeed_machine_init(MachineState *machine)
38
+ int interleave;
69
{
39
+ int spacing;
70
AspeedBoardState *bmc;
40
+} const neon_ls_element_type[11] = {
71
+ AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
41
+ {1, 4, 1},
72
AspeedSoCClass *sc;
42
+ {1, 4, 2},
73
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
43
+ {4, 1, 1},
74
ram_addr_t max_ram_size;
44
+ {2, 2, 2},
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
45
+ {1, 3, 1},
76
UINT32_MAX);
46
+ {1, 3, 2},
77
47
+ {3, 1, 1},
78
object_initialize_child(OBJECT(machine), "soc", &bmc->soc,
48
+ {1, 1, 1},
79
- (sizeof(bmc->soc)), cfg->soc_name, &error_abort,
49
+ {1, 2, 1},
80
+ (sizeof(bmc->soc)), amc->soc_name, &error_abort,
50
+ {1, 2, 2},
81
NULL);
51
+ {2, 1, 1}
82
52
+};
83
sc = ASPEED_SOC_GET_CLASS(&bmc->soc);
53
+
84
54
+static void gen_neon_ldst_base_update(DisasContext *s, int rm, int rn,
85
object_property_set_uint(OBJECT(&bmc->soc), ram_size, "ram-size",
55
+ int stride)
86
&error_abort);
56
+{
87
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap1, "hw-strap1",
57
+ if (rm != 15) {
88
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap1, "hw-strap1",
58
+ TCGv_i32 base;
89
&error_abort);
59
+
90
- object_property_set_int(OBJECT(&bmc->soc), cfg->hw_strap2, "hw-strap2",
60
+ base = load_reg(s, rn);
91
+ object_property_set_int(OBJECT(&bmc->soc), amc->hw_strap2, "hw-strap2",
61
+ if (rm == 13) {
92
&error_abort);
62
+ tcg_gen_addi_i32(base, base, stride);
93
- object_property_set_int(OBJECT(&bmc->soc), cfg->num_cs, "num-cs",
63
+ } else {
94
+ object_property_set_int(OBJECT(&bmc->soc), amc->num_cs, "num-cs",
64
+ TCGv_i32 index;
95
&error_abort);
65
+ index = load_reg(s, rm);
96
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
66
+ tcg_gen_add_i32(base, base, index);
97
&error_abort);
67
+ tcg_temp_free_i32(index);
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
68
+ }
99
"max_ram", max_ram_size - ram_size);
69
+ store_reg(s, rn, base);
100
memory_region_add_subregion(&bmc->ram_container, ram_size, &bmc->max_ram);
70
+ }
101
71
+}
102
- aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
72
+
103
- aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
73
+static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
104
+ aspeed_board_init_flashes(&bmc->soc.fmc, amc->fmc_model, &error_abort);
74
+{
105
+ aspeed_board_init_flashes(&bmc->soc.spi[0], amc->spi_model, &error_abort);
75
+ /* Neon load/store multiple structures */
106
76
+ int nregs, interleave, spacing, reg, n;
107
/* Install first FMC flash content as a boot rom. */
77
+ MemOp endian = s->be_data;
108
if (drive0) {
78
+ int mmu_idx = get_mem_index(s);
109
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
79
+ int size = a->size;
110
aspeed_board_binfo.loader_start = sc->memmap[ASPEED_SDRAM];
80
+ TCGv_i64 tmp64;
111
aspeed_board_binfo.nb_cpus = bmc->soc.num_cpus;
81
+ TCGv_i32 addr, tmp;
112
82
+
113
- if (cfg->i2c_init) {
83
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
114
- cfg->i2c_init(bmc);
84
+ return false;
115
+ if (amc->i2c_init) {
85
+ }
116
+ amc->i2c_init(bmc);
86
+
117
}
87
+ /* UNDEF accesses to D16-D31 if they don't exist */
118
88
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
119
for (i = 0; i < ARRAY_SIZE(bmc->soc.sdhci.slots); i++) {
89
+ return false;
120
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
90
+ }
121
0x60);
91
+ if (a->itype > 10) {
92
+ return false;
93
+ }
94
+ /* Catch UNDEF cases for bad values of align field */
95
+ switch (a->itype & 0xc) {
96
+ case 4:
97
+ if (a->align >= 2) {
98
+ return false;
99
+ }
100
+ break;
101
+ case 8:
102
+ if (a->align == 3) {
103
+ return false;
104
+ }
105
+ break;
106
+ default:
107
+ break;
108
+ }
109
+ nregs = neon_ls_element_type[a->itype].nregs;
110
+ interleave = neon_ls_element_type[a->itype].interleave;
111
+ spacing = neon_ls_element_type[a->itype].spacing;
112
+ if (size == 3 && (interleave | spacing) != 1) {
113
+ return false;
114
+ }
115
+
116
+ if (!vfp_access_check(s)) {
117
+ return true;
118
+ }
119
+
120
+ /* For our purposes, bytes are always little-endian. */
121
+ if (size == 0) {
122
+ endian = MO_LE;
123
+ }
124
+ /*
125
+ * Consecutive little-endian elements from a single register
126
+ * can be promoted to a larger little-endian operation.
127
+ */
128
+ if (interleave == 1 && endian == MO_LE) {
129
+ size = 3;
130
+ }
131
+ tmp64 = tcg_temp_new_i64();
132
+ addr = tcg_temp_new_i32();
133
+ tmp = tcg_const_i32(1 << size);
134
+ load_reg_var(s, addr, a->rn);
135
+ for (reg = 0; reg < nregs; reg++) {
136
+ for (n = 0; n < 8 >> size; n++) {
137
+ int xs;
138
+ for (xs = 0; xs < interleave; xs++) {
139
+ int tt = a->vd + reg + spacing * xs;
140
+
141
+ if (a->l) {
142
+ gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
143
+ neon_store_element64(tt, n, size, tmp64);
144
+ } else {
145
+ neon_load_element64(tmp64, tt, n, size);
146
+ gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
147
+ }
148
+ tcg_gen_add_i32(addr, addr, tmp);
149
+ }
150
+ }
151
+ }
152
+ tcg_temp_free_i32(addr);
153
+ tcg_temp_free_i32(tmp);
154
+ tcg_temp_free_i64(tmp64);
155
+
156
+ gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
157
+ return true;
158
+}
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
122
}
164
}
123
165
124
-static void aspeed_machine_init(MachineState *machine)
166
125
-{
167
-static struct {
126
- AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine);
168
- int nregs;
127
-
169
- int interleave;
128
- aspeed_board_init(machine, amc->board);
170
- int spacing;
129
-}
171
-} const neon_ls_element_type[11] = {
130
-
172
- {1, 4, 1},
131
static void aspeed_machine_class_init(ObjectClass *oc, void *data)
173
- {1, 4, 2},
132
{
174
- {4, 1, 1},
133
MachineClass *mc = MACHINE_CLASS(oc);
175
- {2, 2, 2},
134
- AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
176
- {1, 3, 1},
135
- const AspeedBoardConfig *board = data;
177
- {1, 3, 2},
136
178
- {3, 1, 1},
137
- mc->desc = board->desc;
179
- {1, 1, 1},
138
mc->init = aspeed_machine_init;
180
- {1, 2, 1},
139
mc->max_cpus = ASPEED_CPUS_NUM;
181
- {1, 2, 2},
140
mc->no_floppy = 1;
182
- {2, 1, 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
-};
183
-};
156
-
184
-
157
-static const AspeedBoardConfig aspeed_boards[] = {
185
/* Translate a NEON load/store element instruction. Return nonzero if the
158
- {
186
instruction is invalid. */
159
- .name = MACHINE_TYPE_NAME("palmetto-bmc"),
187
static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
160
- .desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)",
188
{
161
- .soc_name = "ast2400-a1",
189
int rd, rn, rm;
162
- .hw_strap1 = PALMETTO_BMC_HW_STRAP1,
190
- int op;
163
- .fmc_model = "n25q256a",
191
int nregs;
164
- .spi_model = "mx25l25635e",
192
- int interleave;
165
- .num_cs = 1,
193
- int spacing;
166
- .i2c_init = palmetto_bmc_i2c_init,
194
int stride;
167
- .ram = 256 * MiB,
195
int size;
168
- }, {
196
int reg;
169
- .name = MACHINE_TYPE_NAME("ast2500-evb"),
197
int load;
170
- .desc = "Aspeed AST2500 EVB (ARM1176)",
198
- int n;
171
- .soc_name = "ast2500-a1",
199
int vec_size;
172
- .hw_strap1 = AST2500_EVB_HW_STRAP1,
200
- int mmu_idx;
173
- .fmc_model = "w25q256",
201
- MemOp endian;
174
- .spi_model = "mx25l25635e",
202
TCGv_i32 addr;
175
- .num_cs = 1,
203
TCGv_i32 tmp;
176
- .i2c_init = ast2500_evb_i2c_init,
204
- TCGv_i32 tmp2;
177
- .ram = 512 * MiB,
205
- TCGv_i64 tmp64;
178
- }, {
206
179
- .name = MACHINE_TYPE_NAME("romulus-bmc"),
207
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
180
- .desc = "OpenPOWER Romulus BMC (ARM1176)",
208
return 1;
181
- .soc_name = "ast2500-a1",
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
182
- .hw_strap1 = ROMULUS_BMC_HW_STRAP1,
210
rn = (insn >> 16) & 0xf;
183
- .fmc_model = "n25q256a",
211
rm = insn & 0xf;
184
- .spi_model = "mx66l1g45g",
212
load = (insn & (1 << 21)) != 0;
185
- .num_cs = 2,
213
- endian = s->be_data;
186
- .i2c_init = romulus_bmc_i2c_init,
214
- mmu_idx = get_mem_index(s);
187
- .ram = 512 * MiB,
215
if ((insn & (1 << 23)) == 0) {
188
- }, {
216
- /* Load store all elements. */
189
- .name = MACHINE_TYPE_NAME("swift-bmc"),
217
- op = (insn >> 8) & 0xf;
190
- .desc = "OpenPOWER Swift BMC (ARM1176)",
218
- size = (insn >> 6) & 3;
191
- .soc_name = "ast2500-a1",
219
- if (op > 10)
192
- .hw_strap1 = SWIFT_BMC_HW_STRAP1,
220
- return 1;
193
- .fmc_model = "mx66l1g45g",
221
- /* Catch UNDEF cases for bad values of align field */
194
- .spi_model = "mx66l1g45g",
222
- switch (op & 0xc) {
195
- .num_cs = 2,
223
- case 4:
196
- .i2c_init = swift_bmc_i2c_init,
224
- if (((insn >> 5) & 1) == 1) {
197
- .ram = 512 * MiB,
225
- return 1;
198
- }, {
226
- }
199
- .name = MACHINE_TYPE_NAME("witherspoon-bmc"),
227
- break;
200
- .desc = "OpenPOWER Witherspoon BMC (ARM1176)",
228
- case 8:
201
- .soc_name = "ast2500-a1",
229
- if (((insn >> 4) & 3) == 3) {
202
- .hw_strap1 = WITHERSPOON_BMC_HW_STRAP1,
230
- return 1;
203
- .fmc_model = "mx25l25635e",
231
- }
204
- .spi_model = "mx66l1g45g",
232
- break;
205
- .num_cs = 2,
233
- default:
206
- .i2c_init = witherspoon_bmc_i2c_init,
234
- break;
207
- .ram = 512 * MiB,
235
- }
208
- }, {
236
- nregs = neon_ls_element_type[op].nregs;
209
- .name = MACHINE_TYPE_NAME("ast2600-evb"),
237
- interleave = neon_ls_element_type[op].interleave;
210
- .desc = "Aspeed AST2600 EVB (Cortex A7)",
238
- spacing = neon_ls_element_type[op].spacing;
211
- .soc_name = "ast2600-a0",
239
- if (size == 3 && (interleave | spacing) != 1) {
212
- .hw_strap1 = AST2600_EVB_HW_STRAP1,
240
- return 1;
213
- .hw_strap2 = AST2600_EVB_HW_STRAP2,
241
- }
214
- .fmc_model = "w25q512jv",
242
- /* For our purposes, bytes are always little-endian. */
215
- .spi_model = "mx66u51235f",
243
- if (size == 0) {
216
- .num_cs = 1,
244
- endian = MO_LE;
217
- .i2c_init = ast2600_evb_i2c_init,
245
- }
218
- .ram = 1 * GiB,
246
- /* Consecutive little-endian elements from a single register
219
- },
247
- * can be promoted to a larger little-endian operation.
220
-};
248
- */
249
- if (interleave == 1 && endian == MO_LE) {
250
- size = 3;
251
- }
252
- tmp64 = tcg_temp_new_i64();
253
- addr = tcg_temp_new_i32();
254
- tmp2 = tcg_const_i32(1 << size);
255
- load_reg_var(s, addr, rn);
256
- for (reg = 0; reg < nregs; reg++) {
257
- for (n = 0; n < 8 >> size; n++) {
258
- int xs;
259
- for (xs = 0; xs < interleave; xs++) {
260
- int tt = rd + reg + spacing * xs;
221
-
261
-
222
-static void aspeed_machine_types(void)
262
- if (load) {
223
+static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data)
263
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
224
{
264
- neon_store_element64(tt, n, size, tmp64);
225
- int i;
265
- } else {
226
+ MachineClass *mc = MACHINE_CLASS(oc);
266
- neon_load_element64(tmp64, tt, n, size);
227
+ AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc);
267
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
228
268
- }
229
- type_register_static(&aspeed_machine_type);
269
- tcg_gen_add_i32(addr, addr, tmp2);
230
- for (i = 0; i < ARRAY_SIZE(aspeed_boards); ++i) {
270
- }
231
- TypeInfo ti = {
271
- }
232
- .name = aspeed_boards[i].name,
272
- }
233
- .parent = TYPE_ASPEED_MACHINE,
273
- tcg_temp_free_i32(addr);
234
- .class_init = aspeed_machine_class_init,
274
- tcg_temp_free_i32(tmp2);
235
- .class_data = (void *)&aspeed_boards[i],
275
- tcg_temp_free_i64(tmp64);
236
- };
276
- stride = nregs * interleave * 8;
237
- type_register(&ti);
277
+ /* Load store all elements -- handled already by decodetree */
238
+ mc->desc = "OpenPOWER Palmetto BMC (ARM926EJ-S)";
278
+ return 1;
239
+ amc->soc_name = "ast2400-a1";
279
} else {
240
+ amc->hw_strap1 = PALMETTO_BMC_HW_STRAP1;
280
size = (insn >> 10) & 3;
241
+ amc->fmc_model = "n25q256a";
281
if (size == 3) {
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
--
282
--
363
2.20.1
283
2.20.1
364
284
365
285
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert the Neon "load single structure to all lanes" insns to
2
decodetree.
2
3
3
The SRAM must be enabled before using the Buffer Pool mode or the DMA
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
mode. This is not required on other SoCs.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-13-peter.maydell@linaro.org
7
---
8
target/arm/neon-ls.decode | 5 +++
9
target/arm/translate-neon.inc.c | 73 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 55 +------------------------
11
3 files changed, 80 insertions(+), 53 deletions(-)
5
12
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/i2c/aspeed_i2c.h | 3 +++
14
hw/i2c/aspeed_i2c.c | 37 +++++++++++++++++++++++++++++++++++++
15
2 files changed, 40 insertions(+)
16
17
diff --git a/include/hw/i2c/aspeed_i2c.h b/include/hw/i2c/aspeed_i2c.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/i2c/aspeed_i2c.h
15
--- a/target/arm/neon-ls.decode
20
+++ b/include/hw/i2c/aspeed_i2c.h
16
+++ b/target/arm/neon-ls.decode
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedI2CState {
17
@@ -XXX,XX +XXX,XX @@
22
qemu_irq irq;
18
23
19
VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
24
uint32_t intr_status;
20
vd=%vd_dp
25
+ uint32_t ctrl_global;
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;
34
+
21
+
35
} AspeedI2CClass;
22
+# Neon load single element to all lanes
36
23
+
37
I2CBus *aspeed_i2c_get_bus(DeviceState *dev, int busnr);
24
+VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
38
diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c
25
+ vd=%vd_dp
26
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/i2c/aspeed_i2c.c
28
--- a/target/arm/translate-neon.inc.c
41
+++ b/hw/i2c/aspeed_i2c.c
29
+++ b/target/arm/translate-neon.inc.c
42
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
43
#define I2C_CTRL_STATUS 0x00 /* Device Interrupt Status */
31
gen_neon_ldst_base_update(s, a->rm, a->rn, nregs * interleave * 8);
44
#define I2C_CTRL_ASSIGN 0x08 /* Device Interrupt Target
32
return true;
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
}
33
}
54
34
+
55
+static bool aspeed_i2c_check_sram(AspeedI2CBus *bus)
35
+static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
56
+{
36
+{
57
+ AspeedI2CState *s = bus->controller;
37
+ /* Neon load single structure to all lanes */
58
+ AspeedI2CClass *aic = ASPEED_I2C_GET_CLASS(s);
38
+ int reg, stride, vec_size;
39
+ int vd = a->vd;
40
+ int size = a->size;
41
+ int nregs = a->n + 1;
42
+ TCGv_i32 addr, tmp;
59
+
43
+
60
+ if (!aic->check_sram) {
44
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
45
+ return false;
46
+ }
47
+
48
+ /* UNDEF accesses to D16-D31 if they don't exist */
49
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
50
+ return false;
51
+ }
52
+
53
+ if (size == 3) {
54
+ if (nregs != 4 || a->a == 0) {
55
+ return false;
56
+ }
57
+ /* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
58
+ size = 2;
59
+ }
60
+ if (nregs == 1 && a->a == 1 && size == 0) {
61
+ return false;
62
+ }
63
+ if (nregs == 3 && a->a == 1) {
64
+ return false;
65
+ }
66
+
67
+ if (!vfp_access_check(s)) {
61
+ return true;
68
+ return true;
62
+ }
69
+ }
63
+
70
+
64
+ /*
71
+ /*
65
+ * AST2500: SRAM must be enabled before using the Buffer Pool or
72
+ * VLD1 to all lanes: T bit indicates how many Dregs to write.
66
+ * DMA mode.
73
+ * VLD2/3/4 to all lanes: T bit indicates register stride.
67
+ */
74
+ */
68
+ if (!(s->ctrl_global & I2C_CTRL_SRAM_EN) &&
75
+ stride = a->t ? 2 : 1;
69
+ (bus->cmd & (I2CD_RX_DMA_ENABLE | I2CD_TX_DMA_ENABLE |
76
+ vec_size = nregs == 1 ? stride * 8 : 8;
70
+ I2CD_RX_BUFF_ENABLE | I2CD_TX_BUFF_ENABLE))) {
77
+
71
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: SRAM is not enabled\n", __func__);
78
+ tmp = tcg_temp_new_i32();
72
+ return false;
79
+ addr = tcg_temp_new_i32();
80
+ load_reg_var(s, addr, a->rn);
81
+ for (reg = 0; reg < nregs; reg++) {
82
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
83
+ s->be_data | size);
84
+ if ((vd & 1) && vec_size == 16) {
85
+ /*
86
+ * We cannot write 16 bytes at once because the
87
+ * destination is unaligned.
88
+ */
89
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
90
+ 8, 8, tmp);
91
+ tcg_gen_gvec_mov(0, neon_reg_offset(vd + 1, 0),
92
+ neon_reg_offset(vd, 0), 8, 8);
93
+ } else {
94
+ tcg_gen_gvec_dup_i32(size, neon_reg_offset(vd, 0),
95
+ vec_size, vec_size, tmp);
96
+ }
97
+ tcg_gen_addi_i32(addr, addr, 1 << size);
98
+ vd += stride;
73
+ }
99
+ }
100
+ tcg_temp_free_i32(tmp);
101
+ tcg_temp_free_i32(addr);
102
+
103
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << size) * nregs);
74
+
104
+
75
+ return true;
105
+ return true;
76
+}
106
+}
77
+
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
/*
108
index XXXXXXX..XXXXXXX 100644
79
* The state machine needs some refinement. It is only used to track
109
--- a/target/arm/translate.c
80
* invalid STOP commands for the moment.
110
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_i2c_bus_handle_cmd(AspeedI2CBus *bus, uint64_t value)
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
82
bus->cmd &= ~0xFFFF;
112
int size;
83
bus->cmd |= value & 0xFFFF;
113
int reg;
84
114
int load;
85
+ if (!aspeed_i2c_check_sram(bus)) {
115
- int vec_size;
86
+ return;
116
TCGv_i32 addr;
87
+ }
117
TCGv_i32 tmp;
88
+
118
89
if (bus->cmd & I2CD_M_START_CMD) {
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
90
uint8_t state = aspeed_i2c_get_state(bus) & I2CD_MACTIVE ?
120
} else {
91
I2CD_MSTARTR : I2CD_MSTART;
121
size = (insn >> 10) & 3;
92
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
122
if (size == 3) {
93
switch (offset) {
123
- /* Load single element to all lanes. */
94
case I2C_CTRL_STATUS:
124
- int a = (insn >> 4) & 1;
95
return s->intr_status;
125
- if (!load) {
96
+ case I2C_CTRL_GLOBAL:
126
- return 1;
97
+ return s->ctrl_global;
127
- }
98
default:
128
- size = (insn >> 6) & 3;
99
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
129
- nregs = ((insn >> 8) & 3) + 1;
100
__func__, offset);
130
-
101
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_i2c_ctrl_read(void *opaque, hwaddr offset,
131
- if (size == 3) {
102
static void aspeed_i2c_ctrl_write(void *opaque, hwaddr offset,
132
- if (nregs != 4 || a == 0) {
103
uint64_t value, unsigned size)
133
- return 1;
104
{
134
- }
105
+ AspeedI2CState *s = opaque;
135
- /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
106
+
136
- size = 2;
107
switch (offset) {
137
- }
108
+ case I2C_CTRL_GLOBAL:
138
- if (nregs == 1 && a == 1 && size == 0) {
109
+ s->ctrl_global = value;
139
- return 1;
110
+ break;
140
- }
111
case I2C_CTRL_STATUS:
141
- if (nregs == 3 && a == 1) {
112
default:
142
- return 1;
113
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%" HWADDR_PRIx "\n",
143
- }
114
@@ -XXX,XX +XXX,XX @@ static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data)
144
- addr = tcg_temp_new_i32();
115
aic->pool_size = 0x100;
145
- load_reg_var(s, addr, rn);
116
aic->pool_base = 0x200;
146
-
117
aic->bus_pool_base = aspeed_2500_i2c_bus_pool_base;
147
- /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
118
+ aic->check_sram = true;
148
- * VLD2/3/4 to all lanes: bit 5 indicates register stride.
119
}
149
- */
120
150
- stride = (insn & (1 << 5)) ? 2 : 1;
121
static const TypeInfo aspeed_2500_i2c_info = {
151
- vec_size = nregs == 1 ? stride * 8 : 8;
152
-
153
- tmp = tcg_temp_new_i32();
154
- for (reg = 0; reg < nregs; reg++) {
155
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
156
- s->be_data | size);
157
- if ((rd & 1) && vec_size == 16) {
158
- /* We cannot write 16 bytes at once because the
159
- * destination is unaligned.
160
- */
161
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
162
- 8, 8, tmp);
163
- tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
164
- neon_reg_offset(rd, 0), 8, 8);
165
- } else {
166
- tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
167
- vec_size, vec_size, tmp);
168
- }
169
- tcg_gen_addi_i32(addr, addr, 1 << size);
170
- rd += stride;
171
- }
172
- tcg_temp_free_i32(tmp);
173
- tcg_temp_free_i32(addr);
174
- stride = (1 << size) * nregs;
175
+ /* Load single element to all lanes -- handled by decodetree */
176
+ return 1;
177
} else {
178
/* Single element. */
179
int idx = (insn >> 4) & 0xf;
122
--
180
--
123
2.20.1
181
2.20.1
124
182
125
183
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Convert the Neon "load/store single structure to one lane" insns to
2
2
decodetree.
3
HCR_EL2.TID3 requires that AArch32 reads of MVFR[012] are trapped to
3
4
EL2, and HCR_EL2.TID0 does the same for reads of FPSID.
4
As this is the last set of insns in the neon load/store group,
5
In order to handle this, introduce a new TCG helper function that
5
we can remove the whole disas_neon_ls_insn() function.
6
checks for these control bits before executing the VMRC instruction.
6
7
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20191201122018.25808-4-maz@kernel.org
9
Message-id: 20200430181003.21682-14-peter.maydell@linaro.org
15
[PMM: move helper declaration to helper.h; make it
16
TCG_CALL_NO_WG]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
10
---
19
target/arm/helper.h | 2 ++
11
target/arm/neon-ls.decode | 11 +++
20
target/arm/translate-vfp.inc.c | 20 ++++++++++++++++----
12
target/arm/translate-neon.inc.c | 89 +++++++++++++++++++
21
target/arm/vfp_helper.c | 29 +++++++++++++++++++++++++++++
13
target/arm/translate.c | 147 --------------------------------
22
3 files changed, 47 insertions(+), 4 deletions(-)
14
3 files changed, 100 insertions(+), 147 deletions(-)
23
15
24
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.h
18
--- a/target/arm/neon-ls.decode
27
+++ b/target/arm/helper.h
19
+++ b/target/arm/neon-ls.decode
28
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rintd, TCG_CALL_NO_RWG, f64, f64, ptr)
20
@@ -XXX,XX +XXX,XX @@ VLDST_multiple 1111 0100 0 . l:1 0 rn:4 .... itype:4 size:2 align:2 rm:4 \
29
DEF_HELPER_FLAGS_2(vjcvt, TCG_CALL_NO_RWG, i32, f64, env)
21
30
DEF_HELPER_FLAGS_2(fjcvtzs, TCG_CALL_NO_RWG, i64, f64, ptr)
22
VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
31
23
vd=%vd_dp
32
+DEF_HELPER_FLAGS_3(check_hcr_el2_trap, TCG_CALL_NO_WG, void, env, i32, i32)
24
+
33
+
25
+# Neon load/store single structure to one lane
34
/* neon_helper.c */
26
+%imm1_5_p1 5:1 !function=plus1
35
DEF_HELPER_FLAGS_3(neon_qadd_u8, TCG_CALL_NO_RWG, i32, env, i32, i32)
27
+%imm1_6_p1 6:1 !function=plus1
36
DEF_HELPER_FLAGS_3(neon_qadd_s8, TCG_CALL_NO_RWG, i32, env, i32, i32)
28
+
37
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
29
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
30
+ vd=%vd_dp size=0 stride=1
31
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
32
+ vd=%vd_dp size=1 stride=%imm1_5_p1
33
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
34
+ vd=%vd_dp size=2 stride=%imm1_6_p1
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-vfp.inc.c
37
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-vfp.inc.c
38
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static bool trans_VMSR_VMRS(DisasContext *s, arg_VMSR_VMRS *a)
39
@@ -XXX,XX +XXX,XX @@
42
if (a->l) {
40
* It might be possible to convert it to a standalone .c file eventually.
43
/* VMRS, move VFP special register to gp register */
41
*/
44
switch (a->reg) {
42
45
- case ARM_VFP_FPSID:
43
+static inline int plus1(DisasContext *s, int x)
46
- case ARM_VFP_FPEXC:
44
+{
47
- case ARM_VFP_FPINST:
45
+ return x + 1;
48
- case ARM_VFP_FPINST2:
46
+}
49
case ARM_VFP_MVFR0:
47
+
50
case ARM_VFP_MVFR1:
48
/* Include the generated Neon decoder */
51
case ARM_VFP_MVFR2:
49
#include "decode-neon-dp.inc.c"
52
+ case ARM_VFP_FPSID:
50
#include "decode-neon-ls.inc.c"
53
+ if (s->current_el == 1) {
51
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
54
+ TCGv_i32 tcg_reg, tcg_rt;
52
55
+
53
return true;
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
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/vfp_helper.c
74
+++ b/target/arm/vfp_helper.c
75
@@ -XXX,XX +XXX,XX @@ float64 HELPER(frint64_d)(float64 f, void *fpst)
76
return frint_d(f, fpst, 64);
77
}
54
}
78
55
+
79
+void HELPER(check_hcr_el2_trap)(CPUARMState *env, uint32_t rt, uint32_t reg)
56
+static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
80
+{
57
+{
81
+ uint32_t syndrome;
58
+ /* Neon load/store single structure to one lane */
82
+
59
+ int reg;
83
+ switch (reg) {
60
+ int nregs = a->n + 1;
84
+ case ARM_VFP_MVFR0:
61
+ int vd = a->vd;
85
+ case ARM_VFP_MVFR1:
62
+ TCGv_i32 addr, tmp;
86
+ case ARM_VFP_MVFR2:
63
+
87
+ if (!(arm_hcr_el2_eff(env) & HCR_TID3)) {
64
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
88
+ return;
65
+ return false;
66
+ }
67
+
68
+ /* UNDEF accesses to D16-D31 if they don't exist */
69
+ if (!dc_isar_feature(aa32_simd_r32, s) && (a->vd & 0x10)) {
70
+ return false;
71
+ }
72
+
73
+ /* Catch the UNDEF cases. This is unavoidably a bit messy. */
74
+ switch (nregs) {
75
+ case 1:
76
+ if (((a->align & (1 << a->size)) != 0) ||
77
+ (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
78
+ return false;
89
+ }
79
+ }
90
+ break;
80
+ break;
91
+ case ARM_VFP_FPSID:
81
+ case 3:
92
+ if (!(arm_hcr_el2_eff(env) & HCR_TID0)) {
82
+ if ((a->align & 1) != 0) {
93
+ return;
83
+ return false;
84
+ }
85
+ /* fall through */
86
+ case 2:
87
+ if (a->size == 2 && (a->align & 2) != 0) {
88
+ return false;
89
+ }
90
+ break;
91
+ case 4:
92
+ if ((a->size == 2) && ((a->align & 3) == 3)) {
93
+ return false;
94
+ }
94
+ }
95
+ break;
95
+ break;
96
+ default:
96
+ default:
97
+ g_assert_not_reached();
97
+ abort();
98
+ }
98
+ }
99
+
99
+ if ((vd + a->stride * (nregs - 1)) > 31) {
100
+ syndrome = ((EC_FPIDTRAP << ARM_EL_EC_SHIFT)
100
+ /*
101
+ | ARM_EL_IL
101
+ * Attempts to write off the end of the register file are
102
+ | (1 << 24) | (0xe << 20) | (7 << 14)
102
+ * UNPREDICTABLE; we choose to UNDEF because otherwise we would
103
+ | (reg << 10) | (rt << 5) | 1);
103
+ * access off the end of the array that holds the register data.
104
+
104
+ */
105
+ raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
105
+ return false;
106
+ }
107
+
108
+ if (!vfp_access_check(s)) {
109
+ return true;
110
+ }
111
+
112
+ tmp = tcg_temp_new_i32();
113
+ addr = tcg_temp_new_i32();
114
+ load_reg_var(s, addr, a->rn);
115
+ /*
116
+ * TODO: if we implemented alignment exceptions, we should check
117
+ * addr against the alignment encoded in a->align here.
118
+ */
119
+ for (reg = 0; reg < nregs; reg++) {
120
+ if (a->l) {
121
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
122
+ s->be_data | a->size);
123
+ neon_store_element(vd, a->reg_idx, a->size, tmp);
124
+ } else { /* Store */
125
+ neon_load_element(tmp, vd, a->reg_idx, a->size);
126
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
127
+ s->be_data | a->size);
128
+ }
129
+ vd += a->stride;
130
+ tcg_gen_addi_i32(addr, addr, 1 << a->size);
131
+ }
132
+ tcg_temp_free_i32(addr);
133
+ tcg_temp_free_i32(tmp);
134
+
135
+ gen_neon_ldst_base_update(s, a->rm, a->rn, (1 << a->size) * nregs);
136
+
137
+ return true;
106
+}
138
+}
107
+
139
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
#endif
140
index XXXXXXX..XXXXXXX 100644
141
--- a/target/arm/translate.c
142
+++ b/target/arm/translate.c
143
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
144
tcg_temp_free_i32(rd);
145
}
146
147
-
148
-/* Translate a NEON load/store element instruction. Return nonzero if the
149
- instruction is invalid. */
150
-static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
151
-{
152
- int rd, rn, rm;
153
- int nregs;
154
- int stride;
155
- int size;
156
- int reg;
157
- int load;
158
- TCGv_i32 addr;
159
- TCGv_i32 tmp;
160
-
161
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
162
- return 1;
163
- }
164
-
165
- /* FIXME: this access check should not take precedence over UNDEF
166
- * for invalid encodings; we will generate incorrect syndrome information
167
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
168
- */
169
- if (s->fp_excp_el) {
170
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
171
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
172
- return 0;
173
- }
174
-
175
- if (!s->vfp_enabled)
176
- return 1;
177
- VFP_DREG_D(rd, insn);
178
- rn = (insn >> 16) & 0xf;
179
- rm = insn & 0xf;
180
- load = (insn & (1 << 21)) != 0;
181
- if ((insn & (1 << 23)) == 0) {
182
- /* Load store all elements -- handled already by decodetree */
183
- return 1;
184
- } else {
185
- size = (insn >> 10) & 3;
186
- if (size == 3) {
187
- /* Load single element to all lanes -- handled by decodetree */
188
- return 1;
189
- } else {
190
- /* Single element. */
191
- int idx = (insn >> 4) & 0xf;
192
- int reg_idx;
193
- switch (size) {
194
- case 0:
195
- reg_idx = (insn >> 5) & 7;
196
- stride = 1;
197
- break;
198
- case 1:
199
- reg_idx = (insn >> 6) & 3;
200
- stride = (insn & (1 << 5)) ? 2 : 1;
201
- break;
202
- case 2:
203
- reg_idx = (insn >> 7) & 1;
204
- stride = (insn & (1 << 6)) ? 2 : 1;
205
- break;
206
- default:
207
- abort();
208
- }
209
- nregs = ((insn >> 8) & 3) + 1;
210
- /* Catch the UNDEF cases. This is unavoidably a bit messy. */
211
- switch (nregs) {
212
- case 1:
213
- if (((idx & (1 << size)) != 0) ||
214
- (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
215
- return 1;
216
- }
217
- break;
218
- case 3:
219
- if ((idx & 1) != 0) {
220
- return 1;
221
- }
222
- /* fall through */
223
- case 2:
224
- if (size == 2 && (idx & 2) != 0) {
225
- return 1;
226
- }
227
- break;
228
- case 4:
229
- if ((size == 2) && ((idx & 3) == 3)) {
230
- return 1;
231
- }
232
- break;
233
- default:
234
- abort();
235
- }
236
- if ((rd + stride * (nregs - 1)) > 31) {
237
- /* Attempts to write off the end of the register file
238
- * are UNPREDICTABLE; we choose to UNDEF because otherwise
239
- * the neon_load_reg() would write off the end of the array.
240
- */
241
- return 1;
242
- }
243
- tmp = tcg_temp_new_i32();
244
- addr = tcg_temp_new_i32();
245
- load_reg_var(s, addr, rn);
246
- for (reg = 0; reg < nregs; reg++) {
247
- if (load) {
248
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
249
- s->be_data | size);
250
- neon_store_element(rd, reg_idx, size, tmp);
251
- } else { /* Store */
252
- neon_load_element(tmp, rd, reg_idx, size);
253
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
254
- s->be_data | size);
255
- }
256
- rd += stride;
257
- tcg_gen_addi_i32(addr, addr, 1 << size);
258
- }
259
- tcg_temp_free_i32(addr);
260
- tcg_temp_free_i32(tmp);
261
- stride = nregs * (1 << size);
262
- }
263
- }
264
- if (rm != 15) {
265
- TCGv_i32 base;
266
-
267
- base = load_reg(s, rn);
268
- if (rm == 13) {
269
- tcg_gen_addi_i32(base, base, stride);
270
- } else {
271
- TCGv_i32 index;
272
- index = load_reg(s, rm);
273
- tcg_gen_add_i32(base, base, index);
274
- tcg_temp_free_i32(index);
275
- }
276
- store_reg(s, rn, base);
277
- }
278
- return 0;
279
-}
280
-
281
static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
282
{
283
switch (size) {
284
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
285
}
286
return;
287
}
288
- if ((insn & 0x0f100000) == 0x04000000) {
289
- /* NEON load/store. */
290
- if (disas_neon_ls_insn(s, insn)) {
291
- goto illegal_op;
292
- }
293
- return;
294
- }
295
if ((insn & 0x0e000f00) == 0x0c000100) {
296
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
297
/* iWMMXt register transfer. */
298
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
299
}
300
break;
301
case 12:
302
- if ((insn & 0x01100000) == 0x01000000) {
303
- if (disas_neon_ls_insn(s, insn)) {
304
- goto illegal_op;
305
- }
306
- break;
307
- }
308
goto illegal_op;
309
default:
310
illegal_op:
109
--
311
--
110
2.20.1
312
2.20.1
111
313
112
314
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
Convert the Neon 3-reg-same VADD and VSUB insns to decodetree.
2
2
3
HSTR_EL2 offers a way to trap ranges of CP15 system register
3
Note that we don't need the neon_3r_sizes[op] check here because all
4
accesses to EL2, and it looks like this register is completely
4
size values are OK for VADD and VSUB; we'll add this when we convert
5
ignored by QEMU.
5
the first insn that has size restrictions.
6
6
7
To avoid adding extra .accessfn filters all over the place (which
7
For this we need one of the GVecGen*Fn typedefs currently in
8
would have a direct performance impact), let's add a new TB flag
8
translate-a64.h; move them all to translate.h as a block so they
9
that gets set whenever HSTR_EL2 is non-zero and that QEMU translates
9
are visible to the 32-bit decoder.
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
10
13
Tested with a hand-crafted KVM guest accessing CBAR.
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200430181003.21682-15-peter.maydell@linaro.org
14
---
15
target/arm/translate-a64.h | 9 --------
16
target/arm/translate.h | 9 ++++++++
17
target/arm/neon-dp.decode | 17 +++++++++++++++
18
target/arm/translate-neon.inc.c | 38 +++++++++++++++++++++++++++++++++
19
target/arm/translate.c | 14 ++++--------
20
5 files changed, 68 insertions(+), 19 deletions(-)
14
21
15
Signed-off-by: Marc Zyngier <maz@kernel.org>
22
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
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]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
target/arm/cpu.h | 2 ++
22
target/arm/translate.h | 2 ++
23
target/arm/helper.c | 6 ++++++
24
target/arm/op_helper.c | 22 ++++++++++++++++++++++
25
target/arm/translate.c | 3 ++-
26
5 files changed, 34 insertions(+), 1 deletion(-)
27
28
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
29
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.h
24
--- a/target/arm/translate-a64.h
31
+++ b/target/arm/cpu.h
25
+++ b/target/arm/translate-a64.h
32
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
26
@@ -XXX,XX +XXX,XX @@ static inline int vec_full_reg_size(DisasContext *s)
33
FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
27
34
FIELD(TBFLAG_A32, CONDEXEC, 8, 8) /* Not cached. */
28
bool disas_sve(DisasContext *, uint32_t);
35
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
29
36
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 17, 1)
30
-/* Note that the gvec expanders operate on offsets + sizes. */
37
+
31
-typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
38
/* For M profile only, set if FPCCR.LSPACT is set */
32
-typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
39
FIELD(TBFLAG_A32, LSPACT, 18, 1) /* Not cached. */
33
- uint32_t, uint32_t);
40
/* For M profile only, set if we must create a new FP context */
34
-typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
35
- uint32_t, uint32_t, uint32_t);
36
-typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
37
- uint32_t, uint32_t, uint32_t);
38
-
39
#endif /* TARGET_ARM_TRANSLATE_A64_H */
41
diff --git a/target/arm/translate.h b/target/arm/translate.h
40
diff --git a/target/arm/translate.h b/target/arm/translate.h
42
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/translate.h
42
--- a/target/arm/translate.h
44
+++ b/target/arm/translate.h
43
+++ b/target/arm/translate.h
45
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
44
@@ -XXX,XX +XXX,XX @@ void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
46
bool pauth_active;
45
#define dc_isar_feature(name, ctx) \
47
/* True with v8.5-BTI and SCTLR_ELx.BT* set. */
46
({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
48
bool bt;
47
49
+ /* True if any CP15 access is trapped by HSTR_EL2 */
48
+/* Note that the gvec expanders operate on offsets + sizes. */
50
+ bool hstr_active;
49
+typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
51
/*
50
+typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
52
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
51
+ uint32_t, uint32_t);
53
* < 0, set by the current instruction.
52
+typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
53
+ uint32_t, uint32_t, uint32_t);
54
+typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
55
+ uint32_t, uint32_t, uint32_t);
56
+
57
#endif /* TARGET_ARM_TRANSLATE_H */
58
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
55
index XXXXXXX..XXXXXXX 100644
59
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
60
--- a/target/arm/neon-dp.decode
57
+++ b/target/arm/helper.c
61
+++ b/target/arm/neon-dp.decode
58
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
62
@@ -XXX,XX +XXX,XX @@
59
if (arm_el_is_aa64(env, 1)) {
63
#
60
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
64
# This file is processed by scripts/decodetree.py
61
}
65
#
66
+# VFP/Neon register fields; same as vfp.decode
67
+%vm_dp 5:1 0:4
68
+%vn_dp 7:1 16:4
69
+%vd_dp 22:1 12:4
70
71
# Encodings for Neon data processing instructions where the T32 encoding
72
# is a simple transformation of the A32 encoding.
73
@@ -XXX,XX +XXX,XX @@
74
# 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
75
# This file works on the A32 encoding only; calling code for T32 has to
76
# transform the insn into the A32 version first.
62
+
77
+
63
+ if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
78
+######################################################################
64
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
79
+# 3-reg-same grouping:
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
80
+# 1111 001 U 0 D sz:2 Vn:4 Vd:4 opc:4 N Q M op Vm:4
81
+######################################################################
82
+
83
+&3same vm vn vd q size
84
+
85
+@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
86
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
87
+
88
+VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
89
+VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
90
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/arm/translate-neon.inc.c
93
+++ b/target/arm/translate-neon.inc.c
94
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
95
96
return true;
97
}
98
+
99
+static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
100
+{
101
+ int vec_size = a->q ? 16 : 8;
102
+ int rd_ofs = neon_reg_offset(a->vd, 0);
103
+ int rn_ofs = neon_reg_offset(a->vn, 0);
104
+ int rm_ofs = neon_reg_offset(a->vm, 0);
105
+
106
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
107
+ return false;
66
+ }
108
+ }
67
+
109
+
68
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
110
+ /* UNDEF accesses to D16-D31 if they don't exist. */
69
}
111
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
70
112
+ ((a->vd | a->vn | a->vm) & 0x10)) {
71
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
113
+ return false;
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/op_helper.c
74
+++ b/target/arm/op_helper.c
75
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
76
raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
77
}
78
79
+ /*
80
+ * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
81
+ * to sysregs non accessible at EL0 to have UNDEF-ed already.
82
+ */
83
+ if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
84
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
85
+ uint32_t mask = 1 << ri->crn;
86
+
87
+ if (ri->type & ARM_CP_64BIT) {
88
+ mask = 1 << ri->crm;
89
+ }
90
+
91
+ /* T4 and T14 are RES0 */
92
+ mask &= ~((1 << 4) | (1 << 14));
93
+
94
+ if (env->cp15.hstr_el2 & mask) {
95
+ target_el = 2;
96
+ goto exept;
97
+ }
98
+ }
114
+ }
99
+
115
+
100
if (!ri->accessfn) {
116
+ if ((a->vn | a->vm | a->vd) & a->q) {
101
return;
117
+ return false;
102
}
118
+ }
103
@@ -XXX,XX +XXX,XX @@ void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
119
+
104
g_assert_not_reached();
120
+ if (!vfp_access_check(s)) {
105
}
121
+ return true;
106
122
+ }
107
+exept:
123
+
108
raise_exception(env, EXCP_UDEF, syndrome, target_el);
124
+ fn(a->size, rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
109
}
125
+ return true;
110
126
+}
127
+
128
+#define DO_3SAME(INSN, FUNC) \
129
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
130
+ { \
131
+ return do_3same(s, a, FUNC); \
132
+ }
133
+
134
+DO_3SAME(VADD, tcg_gen_gvec_add)
135
+DO_3SAME(VSUB, tcg_gen_gvec_sub)
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
136
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
137
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
138
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
139
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
140
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
116
return 1;
141
}
142
return 0;
143
144
- case NEON_3R_VADD_VSUB:
145
- if (u) {
146
- tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
147
- vec_size, vec_size);
148
- } else {
149
- tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
150
- vec_size, vec_size);
151
- }
152
- return 0;
153
-
154
case NEON_3R_VQADD:
155
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
156
rn_ofs, rm_ofs, vec_size, vec_size,
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
159
u ? &ushl_op[size] : &sshl_op[size]);
160
return 0;
161
+
162
+ case NEON_3R_VADD_VSUB:
163
+ /* Already handled by decodetree */
164
+ return 1;
117
}
165
}
118
166
119
- if (ri->accessfn ||
167
if (size == 3) {
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;
132
--
168
--
133
2.20.1
169
2.20.1
134
170
135
171
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
Convert the Neon logic ops in the 3-reg-same grouping to decodetree.
2
Note that for the logic ops the 'size' field forms part of their
3
decode and the actual operations are always bitwise.
2
4
3
This models the clock write one to clear registers, and fixes up some
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
incorrect behavior in all of the write to clear registers.
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200430181003.21682-16-peter.maydell@linaro.org
8
---
9
target/arm/neon-dp.decode | 12 +++++++++++
10
target/arm/translate-neon.inc.c | 19 +++++++++++++++++
11
target/arm/translate.c | 38 +--------------------------------
12
3 files changed, 32 insertions(+), 37 deletions(-)
5
13
6
There was also a typo in one of the register definitions.
14
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
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>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/misc/aspeed_scu.c | 19 ++++++++++++++-----
18
1 file changed, 14 insertions(+), 5 deletions(-)
19
20
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/misc/aspeed_scu.c
16
--- a/target/arm/neon-dp.decode
23
+++ b/hw/misc/aspeed_scu.c
17
+++ b/target/arm/neon-dp.decode
24
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@
25
#define AST2600_CLK_STOP_CTRL TO_REG(0x80)
19
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
26
#define AST2600_CLK_STOP_CTRL_CLR TO_REG(0x84)
20
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
27
#define AST2600_CLK_STOP_CTRL2 TO_REG(0x90)
21
28
-#define AST2600_CLK_STOP_CTR2L_CLR TO_REG(0x94)
22
+@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
29
+#define AST2600_CLK_STOP_CTRL2_CLR TO_REG(0x94)
23
+ &3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
30
#define AST2600_SDRAM_HANDSHAKE TO_REG(0x100)
24
+
31
#define AST2600_HPLL_PARAM TO_REG(0x200)
25
+VAND_3s 1111 001 0 0 . 00 .... .... 0001 ... 1 .... @3same_logic
32
#define AST2600_HPLL_EXT TO_REG(0x204)
26
+VBIC_3s 1111 001 0 0 . 01 .... .... 0001 ... 1 .... @3same_logic
33
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_ast2600_scu_read(void *opaque, hwaddr offset,
27
+VORR_3s 1111 001 0 0 . 10 .... .... 0001 ... 1 .... @3same_logic
34
return s->regs[reg];
28
+VORN_3s 1111 001 0 0 . 11 .... .... 0001 ... 1 .... @3same_logic
35
}
29
+VEOR_3s 1111 001 1 0 . 00 .... .... 0001 ... 1 .... @3same_logic
36
30
+VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
37
-static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
31
+VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
38
- unsigned size)
32
+VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
39
+static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset,
33
+
40
+ uint64_t data64, unsigned size)
34
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
41
{
35
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
42
AspeedSCUState *s = ASPEED_SCU(opaque);
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
43
int reg = TO_REG(offset);
37
index XXXXXXX..XXXXXXX 100644
44
+ /* Truncate here so bitwise operations below behave as expected */
38
--- a/target/arm/translate-neon.inc.c
45
+ uint32_t data = data64;
39
+++ b/target/arm/translate-neon.inc.c
46
40
@@ -XXX,XX +XXX,XX @@ static bool do_3same(DisasContext *s, arg_3same *a, GVecGen3Fn fn)
47
if (reg >= ASPEED_AST2600_SCU_NR_REGS) {
41
48
qemu_log_mask(LOG_GUEST_ERROR,
42
DO_3SAME(VADD, tcg_gen_gvec_add)
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_ast2600_scu_write(void *opaque, hwaddr offset, uint64_t data,
43
DO_3SAME(VSUB, tcg_gen_gvec_sub)
50
/* fall through */
44
+DO_3SAME(VAND, tcg_gen_gvec_and)
51
case AST2600_SYS_RST_CTRL:
45
+DO_3SAME(VBIC, tcg_gen_gvec_andc)
52
case AST2600_SYS_RST_CTRL2:
46
+DO_3SAME(VORR, tcg_gen_gvec_or)
53
+ case AST2600_CLK_STOP_CTRL:
47
+DO_3SAME(VORN, tcg_gen_gvec_orc)
54
+ case AST2600_CLK_STOP_CTRL2:
48
+DO_3SAME(VEOR, tcg_gen_gvec_xor)
55
/* W1S (Write 1 to set) registers */
49
+
56
s->regs[reg] |= data;
50
+/* These insns are all gvec_bitsel but with the inputs in various orders. */
57
return;
51
+#define DO_3SAME_BITSEL(INSN, O1, O2, O3) \
58
case AST2600_SYS_RST_CTRL_CLR:
52
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
59
case AST2600_SYS_RST_CTRL2_CLR:
53
+ uint32_t rn_ofs, uint32_t rm_ofs, \
60
+ case AST2600_CLK_STOP_CTRL_CLR:
54
+ uint32_t oprsz, uint32_t maxsz) \
61
+ case AST2600_CLK_STOP_CTRL2_CLR:
55
+ { \
62
case AST2600_HW_STRAP1_CLR:
56
+ tcg_gen_gvec_bitsel(vece, rd_ofs, O1, O2, O3, oprsz, maxsz); \
63
case AST2600_HW_STRAP2_CLR:
57
+ } \
64
- /* W1C (Write 1 to clear) registers */
58
+ DO_3SAME(INSN, gen_##INSN##_3s)
65
- s->regs[reg] &= ~data;
59
+
66
+ /*
60
+DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
67
+ * W1C (Write 1 to clear) registers are offset by one address from
61
+DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
68
+ * the data register
62
+DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
69
+ */
63
diff --git a/target/arm/translate.c b/target/arm/translate.c
70
+ s->regs[reg - 1] &= ~data;
64
index XXXXXXX..XXXXXXX 100644
71
return;
65
--- a/target/arm/translate.c
72
66
+++ b/target/arm/translate.c
73
case AST2600_RNG_DATA:
67
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
68
}
69
return 1;
70
71
- case NEON_3R_LOGIC: /* Logic ops. */
72
- switch ((u << 2) | size) {
73
- case 0: /* VAND */
74
- tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
75
- vec_size, vec_size);
76
- break;
77
- case 1: /* VBIC */
78
- tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
79
- vec_size, vec_size);
80
- break;
81
- case 2: /* VORR */
82
- tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
83
- vec_size, vec_size);
84
- break;
85
- case 3: /* VORN */
86
- tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
87
- vec_size, vec_size);
88
- break;
89
- case 4: /* VEOR */
90
- tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
91
- vec_size, vec_size);
92
- break;
93
- case 5: /* VBSL */
94
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
95
- vec_size, vec_size);
96
- break;
97
- case 6: /* VBIT */
98
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
99
- vec_size, vec_size);
100
- break;
101
- case 7: /* VBIF */
102
- tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
103
- vec_size, vec_size);
104
- break;
105
- }
106
- return 0;
107
-
108
case NEON_3R_VQADD:
109
tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
110
rn_ofs, rm_ofs, vec_size, vec_size,
111
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
112
return 0;
113
114
case NEON_3R_VADD_VSUB:
115
+ case NEON_3R_LOGIC:
116
/* Already handled by decodetree */
117
return 1;
118
}
74
--
119
--
75
2.20.1
120
2.20.1
76
121
77
122
diff view generated by jsdifflib
1
From: David Gibson <david@gibson.dropbear.id.au>
1
Convert the Neon 3-reg-same VMAX and VMIN insns to decodetree.
2
2
3
exynos4210_gic_realize() prints the number of cpus into some temporary
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
buffers, but it only allows 3 bytes space for it. That's plenty:
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
existing machines will only ever set this value to EXYNOS4210_NCPUS
5
Message-id: 20200430181003.21682-17-peter.maydell@linaro.org
6
(2). But the compiler can't always figure that out, so some[*] gcc9
6
---
7
versions emit -Wformat-truncation warnings.
7
target/arm/neon-dp.decode | 5 +++++
8
target/arm/translate-neon.inc.c | 14 ++++++++++++++
9
target/arm/translate.c | 21 ++-------------------
10
3 files changed, 21 insertions(+), 19 deletions(-)
8
11
9
We can fix that by hinting the constraint to the compiler with a
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
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
13
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/intc/exynos4210_gic.c
14
--- a/target/arm/neon-dp.decode
29
+++ b/hw/intc/exynos4210_gic.c
15
+++ b/target/arm/neon-dp.decode
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
31
char cpu_alias_name[sizeof(cpu_prefix) + 3];
17
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
32
char dist_alias_name[sizeof(cpu_prefix) + 3];
18
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
33
SysBusDevice *gicbusdev;
19
34
+ uint32_t n = s->num_cpu;
20
+VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
35
uint32_t i;
21
+VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
36
22
+VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
37
s->gic = qdev_create(NULL, "arm_gic");
23
+VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
38
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
24
+
39
memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",
25
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
40
EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);
26
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
41
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
42
- for (i = 0; i < s->num_cpu; i++) {
28
index XXXXXXX..XXXXXXX 100644
43
+ /*
29
--- a/target/arm/translate-neon.inc.c
44
+ * This clues in gcc that our on-stack buffers do, in fact have
30
+++ b/target/arm/translate-neon.inc.c
45
+ * enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
31
@@ -XXX,XX +XXX,XX @@ DO_3SAME(VEOR, tcg_gen_gvec_xor)
46
+ * doesn't figure this out, otherwise and gives spurious warnings.
32
DO_3SAME_BITSEL(VBSL, rd_ofs, rn_ofs, rm_ofs)
47
+ */
33
DO_3SAME_BITSEL(VBIT, rm_ofs, rn_ofs, rd_ofs)
48
+ assert(n <= EXYNOS4210_NCPUS);
34
DO_3SAME_BITSEL(VBIF, rm_ofs, rd_ofs, rn_ofs)
49
+ for (i = 0; i < n; i++) {
35
+
50
/* Map CPU interface per SMP Core */
36
+#define DO_3SAME_NO_SZ_3(INSN, FUNC) \
51
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
37
+ static bool trans_##INSN##_3s(DisasContext *s, arg_3same *a) \
52
memory_region_init_alias(&s->cpu_alias[i], obj,
38
+ { \
39
+ if (a->size == 3) { \
40
+ return false; \
41
+ } \
42
+ return do_3same(s, a, FUNC); \
43
+ }
44
+
45
+DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
46
+DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
47
+DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
48
+DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/translate.c
52
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
54
rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
55
return 0;
56
57
- case NEON_3R_VMAX:
58
- if (u) {
59
- tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
60
- vec_size, vec_size);
61
- } else {
62
- tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
63
- vec_size, vec_size);
64
- }
65
- return 0;
66
- case NEON_3R_VMIN:
67
- if (u) {
68
- tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
69
- vec_size, vec_size);
70
- } else {
71
- tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
72
- vec_size, vec_size);
73
- }
74
- return 0;
75
-
76
case NEON_3R_VSHL:
77
/* Note the operation is vshl vd,vm,vn */
78
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
79
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
80
81
case NEON_3R_VADD_VSUB:
82
case NEON_3R_LOGIC:
83
+ case NEON_3R_VMAX:
84
+ case NEON_3R_VMIN:
85
/* Already handled by decodetree */
86
return 1;
87
}
53
--
88
--
54
2.20.1
89
2.20.1
55
90
56
91
diff view generated by jsdifflib
New patch
1
Convert the Neon comparison ops in the 3-reg-same grouping
2
to decodetree.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-18-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 8 ++++++++
9
target/arm/translate-neon.inc.c | 22 ++++++++++++++++++++++
10
target/arm/translate.c | 23 +++--------------------
11
3 files changed, 33 insertions(+), 20 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
18
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
19
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
20
21
+VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
22
+VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
23
+VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
24
+VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
25
+
26
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
27
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
28
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
29
@@ -XXX,XX +XXX,XX @@ VMIN_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 1 .... @3same
30
31
VADD_3s 1111 001 0 0 . .. .... .... 1000 . . . 0 .... @3same
32
VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
33
+
34
+VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
35
+VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
36
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate-neon.inc.c
39
+++ b/target/arm/translate-neon.inc.c
40
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
41
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
42
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
43
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
44
+
45
+#define DO_3SAME_CMP(INSN, COND) \
46
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
47
+ uint32_t rn_ofs, uint32_t rm_ofs, \
48
+ uint32_t oprsz, uint32_t maxsz) \
49
+ { \
50
+ tcg_gen_gvec_cmp(COND, vece, rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz); \
51
+ } \
52
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
53
+
54
+DO_3SAME_CMP(VCGT_S, TCG_COND_GT)
55
+DO_3SAME_CMP(VCGT_U, TCG_COND_GTU)
56
+DO_3SAME_CMP(VCGE_S, TCG_COND_GE)
57
+DO_3SAME_CMP(VCGE_U, TCG_COND_GEU)
58
+DO_3SAME_CMP(VCEQ, TCG_COND_EQ)
59
+
60
+static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
61
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
62
+{
63
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
64
+}
65
+DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
u ? &mls_op[size] : &mla_op[size]);
72
return 0;
73
74
- case NEON_3R_VTST_VCEQ:
75
- if (u) { /* VCEQ */
76
- tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
77
- vec_size, vec_size);
78
- } else { /* VTST */
79
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
80
- vec_size, vec_size, &cmtst_op[size]);
81
- }
82
- return 0;
83
-
84
- case NEON_3R_VCGT:
85
- tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
86
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
87
- return 0;
88
-
89
- case NEON_3R_VCGE:
90
- tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
91
- rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
92
- return 0;
93
-
94
case NEON_3R_VSHL:
95
/* Note the operation is vshl vd,vm,vn */
96
tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
case NEON_3R_LOGIC:
99
case NEON_3R_VMAX:
100
case NEON_3R_VMIN:
101
+ case NEON_3R_VTST_VCEQ:
102
+ case NEON_3R_VCGT:
103
+ case NEON_3R_VCGE:
104
/* Already handled by decodetree */
105
return 1;
106
}
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
New patch
1
Convert the Neon VQADD/VQSUB insns in the 3-reg-same grouping
2
to decodetree.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200430181003.21682-19-peter.maydell@linaro.org
7
---
8
target/arm/neon-dp.decode | 6 ++++++
9
target/arm/translate-neon.inc.c | 15 +++++++++++++++
10
target/arm/translate.c | 14 ++------------
11
3 files changed, 23 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
+++ b/target/arm/neon-dp.decode
17
@@ -XXX,XX +XXX,XX @@
18
@3same .... ... . . . size:2 .... .... .... . q:1 . . .... \
19
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp
20
21
+VQADD_S_3s 1111 001 0 0 . .. .... .... 0000 . . . 1 .... @3same
22
+VQADD_U_3s 1111 001 1 0 . .. .... .... 0000 . . . 1 .... @3same
23
+
24
@3same_logic .... ... . . . .. .... .... .... . q:1 .. .... \
25
&3same vm=%vm_dp vn=%vn_dp vd=%vd_dp size=0
26
27
@@ -XXX,XX +XXX,XX @@ VBSL_3s 1111 001 1 0 . 01 .... .... 0001 ... 1 .... @3same_logic
28
VBIT_3s 1111 001 1 0 . 10 .... .... 0001 ... 1 .... @3same_logic
29
VBIF_3s 1111 001 1 0 . 11 .... .... 0001 ... 1 .... @3same_logic
30
31
+VQSUB_S_3s 1111 001 0 0 . .. .... .... 0010 . . . 1 .... @3same
32
+VQSUB_U_3s 1111 001 1 0 . .. .... .... 0010 . . . 1 .... @3same
33
+
34
VCGT_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 0 .... @3same
35
VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
36
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_VTST_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
42
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz, &cmtst_op[vece]);
43
}
44
DO_3SAME_NO_SZ_3(VTST, gen_VTST_3s)
45
+
46
+#define DO_3SAME_GVEC4(INSN, OPARRAY) \
47
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
48
+ uint32_t rn_ofs, uint32_t rm_ofs, \
49
+ uint32_t oprsz, uint32_t maxsz) \
50
+ { \
51
+ tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc), \
52
+ rn_ofs, rm_ofs, oprsz, maxsz, &OPARRAY[vece]); \
53
+ } \
54
+ DO_3SAME(INSN, gen_##INSN##_3s)
55
+
56
+DO_3SAME_GVEC4(VQADD_S, sqadd_op)
57
+DO_3SAME_GVEC4(VQADD_U, uqadd_op)
58
+DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
59
+DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
60
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate.c
63
+++ b/target/arm/translate.c
64
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
65
}
66
return 1;
67
68
- case NEON_3R_VQADD:
69
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
70
- rn_ofs, rm_ofs, vec_size, vec_size,
71
- (u ? uqadd_op : sqadd_op) + size);
72
- return 0;
73
-
74
- case NEON_3R_VQSUB:
75
- tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
76
- rn_ofs, rm_ofs, vec_size, vec_size,
77
- (u ? uqsub_op : sqsub_op) + size);
78
- return 0;
79
-
80
case NEON_3R_VMUL: /* VMUL */
81
if (u) {
82
/* Polynomial case allows only P8. */
83
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
84
case NEON_3R_VTST_VCEQ:
85
case NEON_3R_VCGT:
86
case NEON_3R_VCGE:
87
+ case NEON_3R_VQADD:
88
+ case NEON_3R_VQSUB:
89
/* Already handled by decodetree */
90
return 1;
91
}
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
Convert the Neon VMUL, VMLA, VMLS and VSHL insns in the
2
3-reg-same grouping to decodetree.
2
3
3
The current model only restores the Segment Register values but leaves
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the previous CS mapping behind. Introduce a helper setting the
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
register value and mapping the region at the requested address. Use
6
Message-id: 20200430181003.21682-20-peter.maydell@linaro.org
6
this helper when a Segment register is set and at reset.
7
---
8
target/arm/neon-dp.decode | 9 +++++++
9
target/arm/translate-neon.inc.c | 44 +++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 28 +++------------------
11
3 files changed, 56 insertions(+), 25 deletions(-)
7
12
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
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
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/ssi/aspeed_smc.c | 32 +++++++++++++++++++++-----------
15
1 file changed, 21 insertions(+), 11 deletions(-)
16
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/ssi/aspeed_smc.c
15
--- a/target/arm/neon-dp.decode
20
+++ b/hw/ssi/aspeed_smc.c
16
+++ b/target/arm/neon-dp.decode
21
@@ -XXX,XX +XXX,XX @@ static bool aspeed_smc_flash_overlap(const AspeedSMCState *s,
17
@@ -XXX,XX +XXX,XX @@ VCGT_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 0 .... @3same
22
return false;
18
VCGE_S_3s 1111 001 0 0 . .. .... .... 0011 . . . 1 .... @3same
23
}
19
VCGE_U_3s 1111 001 1 0 . .. .... .... 0011 . . . 1 .... @3same
24
20
25
+static void aspeed_smc_flash_set_segment_region(AspeedSMCState *s, int cs,
21
+VSHL_S_3s 1111 001 0 0 . .. .... .... 0100 . . . 0 .... @3same
26
+ uint64_t regval)
22
+VSHL_U_3s 1111 001 1 0 . .. .... .... 0100 . . . 0 .... @3same
23
+
24
VMAX_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 0 .... @3same
25
VMAX_U_3s 1111 001 1 0 . .. .... .... 0110 . . . 0 .... @3same
26
VMIN_S_3s 1111 001 0 0 . .. .... .... 0110 . . . 1 .... @3same
27
@@ -XXX,XX +XXX,XX @@ VSUB_3s 1111 001 1 0 . .. .... .... 1000 . . . 0 .... @3same
28
29
VTST_3s 1111 001 0 0 . .. .... .... 1000 . . . 1 .... @3same
30
VCEQ_3s 1111 001 1 0 . .. .... .... 1000 . . . 1 .... @3same
31
+
32
+VMLA_3s 1111 001 0 0 . .. .... .... 1001 . . . 0 .... @3same
33
+VMLS_3s 1111 001 1 0 . .. .... .... 1001 . . . 0 .... @3same
34
+
35
+VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
36
+VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
37
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate-neon.inc.c
40
+++ b/target/arm/translate-neon.inc.c
41
@@ -XXX,XX +XXX,XX @@ DO_3SAME_NO_SZ_3(VMAX_S, tcg_gen_gvec_smax)
42
DO_3SAME_NO_SZ_3(VMAX_U, tcg_gen_gvec_umax)
43
DO_3SAME_NO_SZ_3(VMIN_S, tcg_gen_gvec_smin)
44
DO_3SAME_NO_SZ_3(VMIN_U, tcg_gen_gvec_umin)
45
+DO_3SAME_NO_SZ_3(VMUL, tcg_gen_gvec_mul)
46
47
#define DO_3SAME_CMP(INSN, COND) \
48
static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
49
@@ -XXX,XX +XXX,XX @@ DO_3SAME_GVEC4(VQADD_S, sqadd_op)
50
DO_3SAME_GVEC4(VQADD_U, uqadd_op)
51
DO_3SAME_GVEC4(VQSUB_S, sqsub_op)
52
DO_3SAME_GVEC4(VQSUB_U, uqsub_op)
53
+
54
+static void gen_VMUL_p_3s(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
55
+ uint32_t rm_ofs, uint32_t oprsz, uint32_t maxsz)
27
+{
56
+{
28
+ AspeedSMCFlash *fl = &s->flashes[cs];
57
+ tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, oprsz, maxsz,
29
+ AspeedSegments seg;
58
+ 0, gen_helper_gvec_pmul_b);
30
+
31
+ s->ctrl->reg_to_segment(s, regval, &seg);
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
+}
59
+}
41
+
60
+
42
static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
61
+static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
43
uint64_t new)
62
+{
44
{
63
+ if (a->size != 0) {
45
- AspeedSMCFlash *fl = &s->flashes[cs];
64
+ return false;
46
AspeedSegments seg;
65
+ }
47
66
+ return do_3same(s, a, gen_VMUL_p_3s);
48
s->ctrl->reg_to_segment(s, new, &seg);
67
+}
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_flash_set_segment(AspeedSMCState *s, int cs,
68
+
50
aspeed_smc_flash_overlap(s, &seg, cs);
69
+#define DO_3SAME_GVEC3_NO_SZ_3(INSN, OPARRAY) \
51
70
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
52
/* All should be fine now to move the region */
71
+ uint32_t rn_ofs, uint32_t rm_ofs, \
53
- memory_region_transaction_begin();
72
+ uint32_t oprsz, uint32_t maxsz) \
54
- memory_region_set_size(&fl->mmio, seg.size);
73
+ { \
55
- memory_region_set_address(&fl->mmio, seg.addr - s->ctrl->flash_window_base);
74
+ tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, \
56
- memory_region_set_enabled(&fl->mmio, true);
75
+ oprsz, maxsz, &OPARRAY[vece]); \
57
- memory_region_transaction_commit();
76
+ } \
77
+ DO_3SAME_NO_SZ_3(INSN, gen_##INSN##_3s)
78
+
79
+
80
+DO_3SAME_GVEC3_NO_SZ_3(VMLA, mla_op)
81
+DO_3SAME_GVEC3_NO_SZ_3(VMLS, mls_op)
82
+
83
+#define DO_3SAME_GVEC3_SHIFT(INSN, OPARRAY) \
84
+ static void gen_##INSN##_3s(unsigned vece, uint32_t rd_ofs, \
85
+ uint32_t rn_ofs, uint32_t rm_ofs, \
86
+ uint32_t oprsz, uint32_t maxsz) \
87
+ { \
88
+ /* Note the operation is vshl vd,vm,vn */ \
89
+ tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, \
90
+ oprsz, maxsz, &OPARRAY[vece]); \
91
+ } \
92
+ DO_3SAME(INSN, gen_##INSN##_3s)
93
+
94
+DO_3SAME_GVEC3_SHIFT(VSHL_S, sshl_op)
95
+DO_3SAME_GVEC3_SHIFT(VSHL_U, ushl_op)
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_neon_data_insn(DisasContext *s, uint32_t insn)
101
}
102
return 1;
103
104
- case NEON_3R_VMUL: /* VMUL */
105
- if (u) {
106
- /* Polynomial case allows only P8. */
107
- if (size != 0) {
108
- return 1;
109
- }
110
- tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
111
- 0, gen_helper_gvec_pmul_b);
112
- } else {
113
- tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
114
- vec_size, vec_size);
115
- }
116
- return 0;
58
-
117
-
59
- s->regs[R_SEG_ADDR0 + cs] = new;
118
- case NEON_3R_VML: /* VMLA, VMLS */
60
+ aspeed_smc_flash_set_segment_region(s, cs, new);
119
- tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
61
}
120
- u ? &mls_op[size] : &mla_op[size]);
62
121
- return 0;
63
static uint64_t aspeed_smc_flash_default_read(void *opaque, hwaddr addr,
122
-
64
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
123
- case NEON_3R_VSHL:
65
qemu_set_irq(s->cs_lines[i], true);
124
- /* Note the operation is vshl vd,vm,vn */
66
}
125
- tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
67
126
- u ? &ushl_op[size] : &sshl_op[size]);
68
- /* setup default segment register values for all */
127
- return 0;
69
+ /* setup the default segment register values and regions for all */
128
-
70
for (i = 0; i < s->ctrl->max_slaves; ++i) {
129
case NEON_3R_VADD_VSUB:
71
- s->regs[R_SEG_ADDR0 + i] =
130
case NEON_3R_LOGIC:
72
- s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]);
131
case NEON_3R_VMAX:
73
+ aspeed_smc_flash_set_segment_region(s, i,
132
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
74
+ s->ctrl->segment_to_reg(s, &s->ctrl->segments[i]));
133
case NEON_3R_VCGE:
75
}
134
case NEON_3R_VQADD:
76
135
case NEON_3R_VQSUB:
77
/* HW strapping flash type for the AST2600 controllers */
136
+ case NEON_3R_VMUL:
137
+ case NEON_3R_VML:
138
+ case NEON_3R_VSHL:
139
/* Already handled by decodetree */
140
return 1;
141
}
78
--
142
--
79
2.20.1
143
2.20.1
80
144
81
145
diff view generated by jsdifflib
New patch
1
We're going to want at least some of the NeonGen* typedefs
2
for the refactored 32-bit Neon decoder, so move them all
3
to translate.h since it makes more sense to keep them in
4
one group.
1
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200430181003.21682-23-peter.maydell@linaro.org
9
---
10
target/arm/translate.h | 17 +++++++++++++++++
11
target/arm/translate-a64.c | 17 -----------------
12
2 files changed, 17 insertions(+), 17 deletions(-)
13
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
17
+++ b/target/arm/translate.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
19
typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
20
uint32_t, uint32_t, uint32_t);
21
22
+/* Function prototype for gen_ functions for calling Neon helpers */
23
+typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
24
+typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
25
+typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
26
+typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
27
+typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
28
+typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
29
+typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
30
+typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
31
+typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
32
+typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
33
+typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
34
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
35
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
36
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
37
+typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
38
+
39
#endif /* TARGET_ARM_TRANSLATE_H */
40
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/translate-a64.c
43
+++ b/target/arm/translate-a64.c
44
@@ -XXX,XX +XXX,XX @@ typedef struct AArch64DecodeTable {
45
AArch64DecodeFn *disas_fn;
46
} AArch64DecodeTable;
47
48
-/* Function prototype for gen_ functions for calling Neon helpers */
49
-typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
50
-typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
51
-typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
52
-typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
53
-typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
54
-typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
55
-typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
56
-typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
57
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
58
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
59
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
60
-typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
61
-typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
62
-typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
63
-typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
64
-
65
/* initialize TCG globals. */
66
void a64_translate_init(void)
67
{
68
--
69
2.20.1
70
71
diff view generated by jsdifflib