1
The following changes since commit eae587e8e3694b1aceab23239493fb4c7e1a80f5:
1
Some arm patches; my to-review queue is by no means empty, but
2
this is a big enough set of patches to be getting on with...
2
3
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qapi-2021-09-13' into staging (2021-09-13 11:00:30 +0100)
4
-- PMM
5
6
The following changes since commit cb9c6a8e5ad6a1f0ce164d352e3102df46986e22:
7
8
.gitlab-ci.d/windows: Work-around timeout and OpenGL problems of the MSYS2 jobs (2023-01-04 18:58:33 +0000)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210913
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230105
8
13
9
for you to fetch changes up to 9a2b2ecf4d25a3943918c95d2db4508b304161b5:
14
for you to fetch changes up to 93c9678de9dc7d2e68f9e8477da072bac30ef132:
10
15
11
hw/arm/mps2.c: Mark internal-only I2C buses as 'full' (2021-09-13 17:09:28 +0100)
16
hw/net: Fix read of uninitialized memory in imx_fec. (2023-01-05 15:33:00 +0000)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* mark MPS2/MPS3 board-internal i2c buses as 'full' so that command
20
* Implement AArch32 ARMv8-R support
16
line user-created devices are not plugged into them
21
* Add Cortex-R52 CPU
17
* Take an exception if PSTATE.IL is set
22
* fix handling of HLT semihosting in system mode
18
* Support an emulated ITS in the virt board
23
* hw/timer/ixm_epit: cleanup and fix bug in compare handling
19
* Add support for kudo-bmc board
24
* target/arm: Coding style fixes
20
* Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
25
* target/arm: Clean up includes
21
* cadence_uart: Fix clock handling issues that prevented
26
* nseries: minor code cleanups
22
u-boot from running
27
* target/arm: align exposed ID registers with Linux
28
* hw/arm/smmu-common: remove unnecessary inlines
29
* i.MX7D: Handle GPT timers
30
* i.MX7D: Connect IRQs to GPIO devices
31
* i.MX6UL: Add a specific GPT timer instance
32
* hw/net: Fix read of uninitialized memory in imx_fec
23
33
24
----------------------------------------------------------------
34
----------------------------------------------------------------
25
Bin Meng (6):
35
Alex Bennée (1):
26
hw/misc: zynq_slcr: Correctly compute output clocks in the reset exit phase
36
target/arm: fix handling of HLT semihosting in system mode
27
hw/char: cadence_uart: Disable transmit when input clock is disabled
28
hw/char: cadence_uart: Move clock/reset check to uart_can_receive()
29
hw/char: cadence_uart: Convert to memop_with_attrs() ops
30
hw/char: cadence_uart: Ignore access when unclocked or in reset for uart_{read, write}()
31
hw/char: cadence_uart: Log a guest error when device is unclocked or in reset
32
37
33
Chris Rauer (1):
38
Axel Heider (8):
34
hw/arm: Add support for kudo-bmc board.
39
hw/timer/imx_epit: improve comments
40
hw/timer/imx_epit: cleanup CR defines
41
hw/timer/imx_epit: define SR_OCIF
42
hw/timer/imx_epit: update interrupt state on CR write access
43
hw/timer/imx_epit: hard reset initializes CR with 0
44
hw/timer/imx_epit: factor out register write handlers
45
hw/timer/imx_epit: remove explicit fields cnt and freq
46
hw/timer/imx_epit: fix compare timer handling
35
47
36
Marc Zyngier (1):
48
Claudio Fontana (1):
37
hw/arm/virt: KVM: Probe for KVM_CAP_ARM_VM_IPA_SIZE when creating scratch VM
49
target/arm: cleanup cpu includes
38
50
39
Peter Maydell (5):
51
Fabiano Rosas (5):
40
target/arm: Take an exception if PSTATE.IL is set
52
target/arm: Fix checkpatch comment style warnings in helper.c
41
qdev: Support marking individual buses as 'full'
53
target/arm: Fix checkpatch space errors in helper.c
42
hw/arm/mps2-tz.c: Add extra data parameter to MakeDevFn
54
target/arm: Fix checkpatch brace errors in helper.c
43
hw/arm/mps2-tz.c: Mark internal-only I2C buses as 'full'
55
target/arm: Remove unused includes from m_helper.c
44
hw/arm/mps2.c: Mark internal-only I2C buses as 'full'
56
target/arm: Remove unused includes from helper.c
45
57
46
Richard Henderson (1):
58
Jean-Christophe Dubois (4):
47
target/arm: Merge disas_a64_insn into aarch64_tr_translate_insn
59
i.MX7D: Connect GPT timers to IRQ
60
i.MX7D: Compute clock frequency for the fixed frequency clocks.
61
i.MX6UL: Add a specific GPT timer instance for the i.MX6UL
62
i.MX7D: Connect IRQs to GPIO devices.
48
63
49
Shashi Mallela (9):
64
Peter Maydell (1):
50
hw/intc: GICv3 ITS initial framework
65
target/arm:Set lg_page_size to 0 if either S1 or S2 asks for it
51
hw/intc: GICv3 ITS register definitions added
52
hw/intc: GICv3 ITS command queue framework
53
hw/intc: GICv3 ITS Command processing
54
hw/intc: GICv3 ITS Feature enablement
55
hw/intc: GICv3 redistributor ITS processing
56
tests/data/acpi/virt: Add IORT files for ITS
57
hw/arm/virt: add ITS support in virt GIC
58
tests/data/acpi/virt: Update IORT files for ITS
59
66
60
docs/system/arm/nuvoton.rst | 1 +
67
Philippe Mathieu-Daudé (5):
61
hw/intc/gicv3_internal.h | 188 ++++-
68
hw/input/tsc2xxx: Constify set_transform()'s MouseTransformInfo arg
62
include/hw/arm/virt.h | 2 +
69
hw/arm/nseries: Constify various read-only arrays
63
include/hw/intc/arm_gicv3_common.h | 13 +
70
hw/arm/nseries: Silent -Wmissing-field-initializers warning
64
include/hw/intc/arm_gicv3_its_common.h | 32 +-
71
hw/arm/smmu-common: Reduce smmu_inv_notifiers_mr() scope
65
include/hw/qdev-core.h | 24 +
72
hw/arm/smmu-common: Avoid using inlined functions with external linkage
66
target/arm/cpu.h | 1 +
67
target/arm/kvm_arm.h | 4 +-
68
target/arm/syndrome.h | 5 +
69
target/arm/translate.h | 2 +
70
hw/arm/mps2-tz.c | 92 ++-
71
hw/arm/mps2.c | 12 +-
72
hw/arm/npcm7xx_boards.c | 34 +
73
hw/arm/virt.c | 29 +-
74
hw/char/cadence_uart.c | 61 +-
75
hw/intc/arm_gicv3.c | 14 +
76
hw/intc/arm_gicv3_common.c | 13 +
77
hw/intc/arm_gicv3_cpuif.c | 7 +-
78
hw/intc/arm_gicv3_dist.c | 5 +-
79
hw/intc/arm_gicv3_its.c | 1322 ++++++++++++++++++++++++++++++++
80
hw/intc/arm_gicv3_its_common.c | 7 +-
81
hw/intc/arm_gicv3_its_kvm.c | 2 +-
82
hw/intc/arm_gicv3_redist.c | 153 +++-
83
hw/misc/zynq_slcr.c | 31 +-
84
softmmu/qdev-monitor.c | 7 +-
85
target/arm/helper-a64.c | 1 +
86
target/arm/helper.c | 8 +
87
target/arm/kvm.c | 7 +-
88
target/arm/translate-a64.c | 255 +++---
89
target/arm/translate.c | 21 +
90
hw/intc/meson.build | 1 +
91
tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes
92
tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes
93
tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes
94
tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes
95
35 files changed, 2144 insertions(+), 210 deletions(-)
96
create mode 100644 hw/intc/arm_gicv3_its.c
97
create mode 100644 tests/data/acpi/virt/IORT
98
create mode 100644 tests/data/acpi/virt/IORT.memhp
99
create mode 100644 tests/data/acpi/virt/IORT.numamem
100
create mode 100644 tests/data/acpi/virt/IORT.pxb
101
73
74
Stephen Longfield (1):
75
hw/net: Fix read of uninitialized memory in imx_fec.
76
77
Tobias Röhmel (7):
78
target/arm: Don't add all MIDR aliases for cores that implement PMSA
79
target/arm: Make RVBAR available for all ARMv8 CPUs
80
target/arm: Make stage_2_format for cache attributes optional
81
target/arm: Enable TTBCR_EAE for ARMv8-R AArch32
82
target/arm: Add PMSAv8r registers
83
target/arm: Add PMSAv8r functionality
84
target/arm: Add ARM Cortex-R52 CPU
85
86
Zhuojia Shen (1):
87
target/arm: align exposed ID registers with Linux
88
89
include/hw/arm/fsl-imx7.h | 20 +
90
include/hw/arm/smmu-common.h | 3 -
91
include/hw/input/tsc2xxx.h | 4 +-
92
include/hw/timer/imx_epit.h | 8 +-
93
include/hw/timer/imx_gpt.h | 1 +
94
target/arm/cpu.h | 6 +
95
target/arm/internals.h | 4 +
96
hw/arm/fsl-imx6ul.c | 2 +-
97
hw/arm/fsl-imx7.c | 41 +-
98
hw/arm/nseries.c | 28 +-
99
hw/arm/smmu-common.c | 15 +-
100
hw/input/tsc2005.c | 2 +-
101
hw/input/tsc210x.c | 3 +-
102
hw/misc/imx6ul_ccm.c | 6 -
103
hw/misc/imx7_ccm.c | 49 ++-
104
hw/net/imx_fec.c | 8 +-
105
hw/timer/imx_epit.c | 376 +++++++++-------
106
hw/timer/imx_gpt.c | 25 ++
107
target/arm/cpu.c | 35 +-
108
target/arm/cpu64.c | 6 -
109
target/arm/cpu_tcg.c | 42 ++
110
target/arm/debug_helper.c | 3 +
111
target/arm/helper.c | 871 +++++++++++++++++++++++++++++---------
112
target/arm/m_helper.c | 16 -
113
target/arm/machine.c | 28 ++
114
target/arm/ptw.c | 152 +++++--
115
target/arm/tlb_helper.c | 4 +
116
target/arm/translate.c | 2 +-
117
tests/tcg/aarch64/sysregs.c | 24 +-
118
tests/tcg/aarch64/Makefile.target | 7 +-
119
30 files changed, 1330 insertions(+), 461 deletions(-)
120
diff view generated by jsdifflib
1
The various MPS2 boards have multiple I2C buses: typically a bus
1
In get_phys_addr_twostage() we set the lg_page_size of the result to
2
dedicated to the audio configuration, one for the LCD touchscreen
2
the maximum of the stage 1 and stage 2 page sizes. This works for
3
controller, one for a DDR4 EEPROM, and two which are connected to the
3
the case where we do want to create a TLB entry, because we know the
4
external Shield expansion connector. Mark the buses which are used
4
common TLB code only creates entries of the TARGET_PAGE_SIZE and
5
only for board-internal devices as 'full' so that if the user creates
5
asking for a size larger than that only means that invalidations
6
i2c devices on the commandline without specifying a bus name then
6
invalidate the whole larger area. However, if lg_page_size is
7
they will be connected to the I2C controller used for the Shield
7
smaller than TARGET_PAGE_SIZE this effectively means "don't create a
8
connector, where guest software will expect them.
8
TLB entry"; in this case if either S1 or S2 said "this covers less
9
than a page and can't go in a TLB" then the final result also should
10
be marked that way. Set the resulting page size to 0 if either
11
stage asked for a less-than-a-page entry, and expand the comment
12
to explain what's going on.
13
14
This has no effect for VMSA because currently the VMSA lookup always
15
returns results that cover at least TARGET_PAGE_SIZE; however when we
16
add v8R support it will reuse this code path, and for v8R the S1 and
17
S2 results can be smaller than TARGET_PAGE_SIZE.
9
18
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210903151435.22379-4-peter.maydell@linaro.org
21
Message-id: 20221212142708.610090-1-peter.maydell@linaro.org
13
---
22
---
14
hw/arm/mps2-tz.c | 57 ++++++++++++++++++++++++++++++++++++------------
23
target/arm/ptw.c | 16 +++++++++++++---
15
1 file changed, 43 insertions(+), 14 deletions(-)
24
1 file changed, 13 insertions(+), 3 deletions(-)
16
25
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
18
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
28
--- a/target/arm/ptw.c
20
+++ b/hw/arm/mps2-tz.c
29
+++ b/target/arm/ptw.c
21
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
22
31
}
23
/* Union describing the device-specific extra data we pass to the devfn. */
32
24
typedef union PPCExtraData {
33
/*
25
+ bool i2c_internal;
34
- * Use the maximum of the S1 & S2 page size, so that invalidation
26
} PPCExtraData;
35
- * of pages > TARGET_PAGE_SIZE works correctly.
27
36
+ * If either S1 or S2 returned a result smaller than TARGET_PAGE_SIZE,
28
/* Most of the devices in the AN505 FPGA image sit behind
37
+ * this means "don't put this in the TLB"; in this case, return a
29
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
38
+ * result with lg_page_size == 0 to achieve that. Otherwise,
30
object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
39
+ * use the maximum of the S1 & S2 page size, so that invalidation
31
s = SYS_BUS_DEVICE(i2c);
40
+ * of pages > TARGET_PAGE_SIZE works correctly. (This works even though
32
sysbus_realize(s, &error_fatal);
41
+ * we know the combined result permissions etc only cover the minimum
33
+
42
+ * of the S1 and S2 page size, because we know that the common TLB code
34
+ /*
43
+ * never actually creates TLB entries bigger than TARGET_PAGE_SIZE,
35
+ * If this is an internal-use-only i2c bus, mark it full
44
+ * and passing a larger page size value only affects invalidations.)
36
+ * so that user-created i2c devices are not plugged into it.
45
*/
37
+ * If we implement models of any on-board i2c devices that
46
- if (result->f.lg_page_size < s1_lgpgsz) {
38
+ * plug in to one of the internal-use-only buses, then we will
47
+ if (result->f.lg_page_size < TARGET_PAGE_BITS ||
39
+ * need to create and plugging those in here before we mark the
48
+ s1_lgpgsz < TARGET_PAGE_BITS) {
40
+ * bus as full.
49
+ result->f.lg_page_size = 0;
41
+ */
50
+ } else if (result->f.lg_page_size < s1_lgpgsz) {
42
+ if (extradata->i2c_internal) {
51
result->f.lg_page_size = s1_lgpgsz;
43
+ BusState *qbus = qdev_get_child_bus(DEVICE(i2c), "i2c");
52
}
44
+ qbus_mark_full(qbus);
53
45
+ }
46
+
47
return sysbus_mmio_get_region(s, 0);
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
51
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
52
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
53
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
54
- { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
55
- { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
56
- { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
57
- { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
58
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000, {},
59
+ { .i2c_internal = true /* touchscreen */ } },
60
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000, {},
61
+ { .i2c_internal = true /* audio conf */ } },
62
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000, {},
63
+ { .i2c_internal = false /* shield 0 */ } },
64
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000, {},
65
+ { .i2c_internal = false /* shield 1 */ } },
66
},
67
}, {
68
.name = "apb_ppcexp2",
69
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
70
}, {
71
.name = "apb_ppcexp1",
72
.ports = {
73
- { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
74
- { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
75
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000, {},
76
+ { .i2c_internal = true /* touchscreen */ } },
77
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000, {},
78
+ { .i2c_internal = true /* audio conf */ } },
79
{ "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
80
{ "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
81
{ "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
82
- { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
83
- { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
84
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000, {},
85
+ { .i2c_internal = false /* shield 0 */ } },
86
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000, {},
87
+ { .i2c_internal = false /* shield 1 */ } },
88
{ /* port 7 reserved */ },
89
- { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
90
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000, {},
91
+ { .i2c_internal = true /* DDR4 EEPROM */ } },
92
},
93
}, {
94
.name = "apb_ppcexp2",
95
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
96
}, {
97
.name = "apb_ppcexp1",
98
.ports = {
99
- { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000 },
100
- { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000 },
101
+ { "i2c0", make_i2c, &mms->i2c[0], 0x49200000, 0x1000, {},
102
+ { .i2c_internal = true /* touchscreen */ } },
103
+ { "i2c1", make_i2c, &mms->i2c[1], 0x49201000, 0x1000, {},
104
+ { .i2c_internal = true /* audio conf */ } },
105
{ "spi0", make_spi, &mms->spi[0], 0x49202000, 0x1000, { 53 } },
106
{ "spi1", make_spi, &mms->spi[1], 0x49203000, 0x1000, { 54 } },
107
{ "spi2", make_spi, &mms->spi[2], 0x49204000, 0x1000, { 55 } },
108
- { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000 },
109
- { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000 },
110
+ { "i2c2", make_i2c, &mms->i2c[2], 0x49205000, 0x1000, {},
111
+ { .i2c_internal = false /* shield 0 */ } },
112
+ { "i2c3", make_i2c, &mms->i2c[3], 0x49206000, 0x1000, {},
113
+ { .i2c_internal = false /* shield 1 */ } },
114
{ /* port 7 reserved */ },
115
- { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000 },
116
+ { "i2c4", make_i2c, &mms->i2c[4], 0x49208000, 0x1000, {},
117
+ { .i2c_internal = true /* DDR4 EEPROM */ } },
118
},
119
}, {
120
.name = "apb_ppcexp2",
121
--
54
--
122
2.20.1
55
2.25.1
123
124
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Updated expected IORT files applicable with latest GICv3
3
Cores with PMSA have the MPUIR register which has the
4
ITS changes.
4
same encoding as the MIDR alias with opc2=4. So we only
5
add that alias if we are not realizing a core that
6
implements PMSA.
5
7
6
Full diff of new file disassembly:
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
7
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20180629 (64-bit version)
11
* Copyright (c) 2000 - 2018 Intel Corporation
12
*
13
* Disassembly of tests/data/acpi/virt/IORT.pxb, Tue Jun 29 17:35:38 2021
14
*
15
* ACPI Data Table [IORT]
16
*
17
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
18
*/
19
20
[000h 0000 4] Signature : "IORT" [IO Remapping Table]
21
[004h 0004 4] Table Length : 0000007C
22
[008h 0008 1] Revision : 00
23
[009h 0009 1] Checksum : 07
24
[00Ah 0010 6] Oem ID : "BOCHS "
25
[010h 0016 8] Oem Table ID : "BXPC "
26
[018h 0024 4] Oem Revision : 00000001
27
[01Ch 0028 4] Asl Compiler ID : "BXPC"
28
[020h 0032 4] Asl Compiler Revision : 00000001
29
30
[024h 0036 4] Node Count : 00000002
31
[028h 0040 4] Node Offset : 00000030
32
[02Ch 0044 4] Reserved : 00000000
33
34
[030h 0048 1] Type : 00
35
[031h 0049 2] Length : 0018
36
[033h 0051 1] Revision : 00
37
[034h 0052 4] Reserved : 00000000
38
[038h 0056 4] Mapping Count : 00000000
39
[03Ch 0060 4] Mapping Offset : 00000000
40
41
[040h 0064 4] ItsCount : 00000001
42
[044h 0068 4] Identifiers : 00000000
43
44
[048h 0072 1] Type : 02
45
[049h 0073 2] Length : 0034
46
[04Bh 0075 1] Revision : 00
47
[04Ch 0076 4] Reserved : 00000000
48
[050h 0080 4] Mapping Count : 00000001
49
[054h 0084 4] Mapping Offset : 00000020
50
51
[058h 0088 8] Memory Properties : [IORT Memory Access Properties]
52
[058h 0088 4] Cache Coherency : 00000001
53
[05Ch 0092 1] Hints (decoded below) : 00
54
Transient : 0
55
Write Allocate : 0
56
Read Allocate : 0
57
Override : 0
58
[05Dh 0093 2] Reserved : 0000
59
[05Fh 0095 1] Memory Flags (decoded below) : 03
60
Coherency : 1
61
Device Attribute : 1
62
[060h 0096 4] ATS Attribute : 00000000
63
[064h 0100 4] PCI Segment Number : 00000000
64
[068h 0104 1] Memory Size Limit : 00
65
[069h 0105 3] Reserved : 000000
66
67
[068h 0104 4] Input base : 00000000
68
[06Ch 0108 4] ID Count : 0000FFFF
69
[070h 0112 4] Output Base : 00000000
70
[074h 0116 4] Output Reference : 00000030
71
[078h 0120 4] Flags (decoded below) : 00000000
72
Single Mapping : 0
73
74
Raw Table Data: Length 124 (0x7C)
75
76
0000: 49 4F 52 54 7C 00 00 00 00 07 42 4F 43 48 53 20 // IORT|.....BOCHS
77
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
78
0020: 01 00 00 00 02 00 00 00 30 00 00 00 00 00 00 00 // ........0.......
79
0030: 00 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
80
0040: 01 00 00 00 00 00 00 00 02 34 00 00 00 00 00 00 // .........4......
81
0050: 01 00 00 00 20 00 00 00 01 00 00 00 00 00 00 03 // .... ...........
82
0060: 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 // ................
83
0070: 00 00 00 00 30 00 00 00 00 00 00 00 // ....0.......
84
85
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
86
Acked-by: Igor Mammedov <imammedo@redhat.com>
87
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
88
Message-id: 20210910143951.92242-10-shashi.mallela@linaro.org
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20221206102504.165775-2-tobias.roehmel@rwth-aachen.de
89
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
90
---
13
---
91
tests/qtest/bios-tables-test-allowed-diff.h | 4 ----
14
target/arm/helper.c | 13 +++++++++----
92
tests/data/acpi/virt/IORT | Bin 0 -> 124 bytes
15
1 file changed, 9 insertions(+), 4 deletions(-)
93
tests/data/acpi/virt/IORT.memhp | Bin 0 -> 124 bytes
94
tests/data/acpi/virt/IORT.numamem | Bin 0 -> 124 bytes
95
tests/data/acpi/virt/IORT.pxb | Bin 0 -> 124 bytes
96
5 files changed, 4 deletions(-)
97
16
98
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
99
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
100
--- a/tests/qtest/bios-tables-test-allowed-diff.h
19
--- a/target/arm/helper.c
101
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
20
+++ b/target/arm/helper.c
102
@@ -1,5 +1 @@
21
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
103
/* List of comma-separated changed AML files to ignore */
22
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
104
-"tests/data/acpi/virt/IORT",
23
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
105
-"tests/data/acpi/virt/IORT.memhp",
24
.readfn = midr_read },
106
-"tests/data/acpi/virt/IORT.numamem",
25
- /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */
107
-"tests/data/acpi/virt/IORT.pxb",
26
- { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
108
diff --git a/tests/data/acpi/virt/IORT b/tests/data/acpi/virt/IORT
27
- .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
109
index XXXXXXX..XXXXXXX 100644
28
- .access = PL1_R, .resetvalue = cpu->midr },
110
GIT binary patch
29
+ /* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
111
literal 124
30
{ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
112
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
31
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
113
QRGb+i3L*dhhtM#y0PN=p0RR91
32
.access = PL1_R, .resetvalue = cpu->midr },
114
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
115
literal 0
34
.accessfn = access_aa64_tid1,
116
HcmV?d00001
35
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
117
36
};
118
diff --git a/tests/data/acpi/virt/IORT.memhp b/tests/data/acpi/virt/IORT.memhp
37
+ ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
119
index XXXXXXX..XXXXXXX 100644
38
+ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
120
GIT binary patch
39
+ .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
121
literal 124
40
+ .access = PL1_R, .resetvalue = cpu->midr
122
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
41
+ };
123
QRGb+i3L*dhhtM#y0PN=p0RR91
42
ARMCPRegInfo id_cp_reginfo[] = {
124
43
/* These are common to v8 and pre-v8 */
125
literal 0
44
{ .name = "CTR",
126
HcmV?d00001
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
127
46
}
128
diff --git a/tests/data/acpi/virt/IORT.numamem b/tests/data/acpi/virt/IORT.numamem
47
if (arm_feature(env, ARM_FEATURE_V8)) {
129
index XXXXXXX..XXXXXXX 100644
48
define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
130
GIT binary patch
49
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
131
literal 124
50
+ define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo);
132
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
51
+ }
133
QRGb+i3L*dhhtM#y0PN=p0RR91
52
} else {
134
53
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
135
literal 0
54
}
136
HcmV?d00001
137
138
diff --git a/tests/data/acpi/virt/IORT.pxb b/tests/data/acpi/virt/IORT.pxb
139
index XXXXXXX..XXXXXXX 100644
140
GIT binary patch
141
literal 124
142
zcmebD4+^Pa00MR=e`k+i1*eDrX9XZ&1PX!JAesq?4S*O7Bw!2(4Uz`|CKCt^;wu0#
143
QRGb+i3L*dhhtM#y0PN=p0RR91
144
145
literal 0
146
HcmV?d00001
147
148
--
55
--
149
2.20.1
56
2.25.1
150
57
151
58
diff view generated by jsdifflib
1
The various MPS2 boards implemented in mps2.c have multiple I2C
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
buses: a bus dedicated to the audio configuration, one for the LCD
3
touchscreen controller, and two which are connected to the external
4
Shield expansion connector. Mark the buses which are used only for
5
board-internal devices as 'full' so that if the user creates i2c
6
devices on the commandline without specifying a bus name then they
7
will be connected to the I2C controller used for the Shield
8
connector, where guest software will expect them.
9
2
3
RVBAR shadows RVBAR_ELx where x is the highest exception
4
level if the highest EL is not EL3. This patch also allows
5
ARMv8 CPUs to change the reset address with
6
the rvbar property.
7
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20221206102504.165775-3-tobias.roehmel@rwth-aachen.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210903151435.22379-5-peter.maydell@linaro.org
13
---
12
---
14
hw/arm/mps2.c | 12 +++++++++++-
13
target/arm/cpu.c | 6 +++++-
15
1 file changed, 11 insertions(+), 1 deletion(-)
14
target/arm/helper.c | 21 ++++++++++++++-------
15
2 files changed, 19 insertions(+), 8 deletions(-)
16
16
17
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2.c
19
--- a/target/arm/cpu.c
20
+++ b/hw/arm/mps2.c
20
+++ b/target/arm/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
22
0x40023000, /* Audio */
22
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
23
0x40029000, /* Shield0 */
23
CPACR, CP11, 3);
24
0x4002a000}; /* Shield1 */
24
#endif
25
- sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
25
+ if (arm_feature(env, ARM_FEATURE_V8)) {
26
+ DeviceState *dev;
26
+ env->cp15.rvbar = cpu->rvbar_prop;
27
+
27
+ env->regs[15] = cpu->rvbar_prop;
28
+ dev = sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
29
+ if (i < 2) {
30
+ /*
31
+ * internal-only bus: mark it full to avoid user-created
32
+ * i2c devices being plugged into it.
33
+ */
34
+ BusState *qbus = qdev_get_child_bus(dev, "i2c");
35
+ qbus_mark_full(qbus);
36
+ }
28
+ }
37
}
29
}
38
create_unimplemented_device("i2s", 0x40024000, 0x400);
30
31
#if defined(CONFIG_USER_ONLY)
32
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
33
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
34
}
35
36
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
37
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
38
object_property_add_uint64_ptr(obj, "rvbar",
39
&cpu->rvbar_prop,
40
OBJ_PROP_FLAG_READWRITE);
41
diff --git a/target/arm/helper.c b/target/arm/helper.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/helper.c
44
+++ b/target/arm/helper.c
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
46
if (!arm_feature(env, ARM_FEATURE_EL3) &&
47
!arm_feature(env, ARM_FEATURE_EL2)) {
48
ARMCPRegInfo rvbar = {
49
- .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
50
+ .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
51
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
52
.access = PL1_R,
53
.fieldoffset = offsetof(CPUARMState, cp15.rvbar),
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
55
}
56
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
57
if (!arm_feature(env, ARM_FEATURE_EL3)) {
58
- ARMCPRegInfo rvbar = {
59
- .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
60
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
61
- .access = PL2_R,
62
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
63
+ ARMCPRegInfo rvbar[] = {
64
+ {
65
+ .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
66
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
67
+ .access = PL2_R,
68
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
69
+ },
70
+ { .name = "RVBAR", .type = ARM_CP_ALIAS,
71
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
72
+ .access = PL2_R,
73
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
74
+ },
75
};
76
- define_one_arm_cp_reg(cpu, &rvbar);
77
+ define_arm_cp_regs(cpu, rvbar);
78
}
79
}
39
80
40
--
81
--
41
2.20.1
82
2.25.1
42
83
43
84
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Added expected IORT files applicable with latest GICv3
3
The v8R PMSAv8 has a two-stage MPU translation process, but, unlike
4
ITS changes.Temporarily differences in these files are
4
VMSAv8, the stage 2 attributes are in the same format as the stage 1
5
okay.
5
attributes (8-bit MAIR format). Rather than converting the MAIR
6
format to the format used for VMSA stage 2 (bits [5:2] of a VMSA
7
stage 2 descriptor) and then converting back to do the attribute
8
combination, allow combined_attrs_nofwb() to accept s2 attributes
9
that are already in the MAIR format.
6
10
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
11
We move the assert() to combined_attrs_fwb(), because that function
8
Acked-by: Igor Mammedov <imammedo@redhat.com>
12
really does require a VMSA stage 2 attribute format. (We will never
13
get there for v8R, because PMSAv8 does not implement FEAT_S2FWB.)
14
15
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210910143951.92242-8-shashi.mallela@linaro.org
17
Message-id: 20221206102504.165775-4-tobias.roehmel@rwth-aachen.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
19
---
13
tests/qtest/bios-tables-test-allowed-diff.h | 4 ++++
20
target/arm/ptw.c | 10 ++++++++--
14
tests/data/acpi/virt/IORT | 0
21
1 file changed, 8 insertions(+), 2 deletions(-)
15
tests/data/acpi/virt/IORT.memhp | 0
16
tests/data/acpi/virt/IORT.numamem | 0
17
tests/data/acpi/virt/IORT.pxb | 0
18
5 files changed, 4 insertions(+)
19
create mode 100644 tests/data/acpi/virt/IORT
20
create mode 100644 tests/data/acpi/virt/IORT.memhp
21
create mode 100644 tests/data/acpi/virt/IORT.numamem
22
create mode 100644 tests/data/acpi/virt/IORT.pxb
23
22
24
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/tests/qtest/bios-tables-test-allowed-diff.h
25
--- a/target/arm/ptw.c
27
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
26
+++ b/target/arm/ptw.c
28
@@ -1 +1,5 @@
27
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_nofwb(uint64_t hcr,
29
/* List of comma-separated changed AML files to ignore */
28
{
30
+"tests/data/acpi/virt/IORT",
29
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
31
+"tests/data/acpi/virt/IORT.memhp",
30
32
+"tests/data/acpi/virt/IORT.numamem",
31
- s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
33
+"tests/data/acpi/virt/IORT.pxb",
32
+ if (s2.is_s2_format) {
34
diff --git a/tests/data/acpi/virt/IORT b/tests/data/acpi/virt/IORT
33
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
35
new file mode 100644
34
+ } else {
36
index XXXXXXX..XXXXXXX
35
+ s2_mair_attrs = s2.attrs;
37
diff --git a/tests/data/acpi/virt/IORT.memhp b/tests/data/acpi/virt/IORT.memhp
36
+ }
38
new file mode 100644
37
39
index XXXXXXX..XXXXXXX
38
s1lo = extract32(s1.attrs, 0, 4);
40
diff --git a/tests/data/acpi/virt/IORT.numamem b/tests/data/acpi/virt/IORT.numamem
39
s2lo = extract32(s2_mair_attrs, 0, 4);
41
new file mode 100644
40
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
42
index XXXXXXX..XXXXXXX
41
*/
43
diff --git a/tests/data/acpi/virt/IORT.pxb b/tests/data/acpi/virt/IORT.pxb
42
static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
44
new file mode 100644
43
{
45
index XXXXXXX..XXXXXXX
44
+ assert(s2.is_s2_format && !s1.is_s2_format);
45
+
46
switch (s2.attrs) {
47
case 7:
48
/* Use stage 1 attributes */
49
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
50
ARMCacheAttrs ret;
51
bool tagged = false;
52
53
- assert(s2.is_s2_format && !s1.is_s2_format);
54
+ assert(!s1.is_s2_format);
55
ret.is_s2_format = false;
56
57
if (s1.attrs == 0xf0) {
46
--
58
--
47
2.20.1
59
2.25.1
48
60
49
61
diff view generated by jsdifflib
1
From: Marc Zyngier <maz@kernel.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Although we probe for the IPA limits imposed by KVM (and the hardware)
3
ARMv8-R AArch32 CPUs behave as if TTBCR.EAE is always 1 even
4
when computing the memory map, we still use the old style '0' when
4
tough they don't have the TTBCR register.
5
creating a scratch VM in kvm_arm_create_scratch_host_vcpu().
5
See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
6
AArch32 architecture profile Version:A.c section C1.2.
6
7
7
On systems that are severely IPA challenged (such as the Apple M1),
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
8
this results in a failure as KVM cannot use the default 40bit that
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
'0' represents.
10
Message-id: 20221206102504.165775-5-tobias.roehmel@rwth-aachen.de
10
11
Instead, probe for the extension and use the reported IPA limit
12
if available.
13
14
Cc: Andrew Jones <drjones@redhat.com>
15
Cc: Eric Auger <eric.auger@redhat.com>
16
Cc: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Marc Zyngier <maz@kernel.org>
18
Reviewed-by: Andrew Jones <drjones@redhat.com>
19
Message-id: 20210822144441.1290891-2-maz@kernel.org
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
12
---
22
target/arm/kvm.c | 7 ++++++-
13
target/arm/internals.h | 4 ++++
23
1 file changed, 6 insertions(+), 1 deletion(-)
14
target/arm/debug_helper.c | 3 +++
15
target/arm/tlb_helper.c | 4 ++++
16
3 files changed, 11 insertions(+)
24
17
25
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
26
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/kvm.c
20
--- a/target/arm/internals.h
28
+++ b/target/arm/kvm.c
21
+++ b/target/arm/internals.h
29
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try,
22
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu);
30
struct kvm_vcpu_init *init)
23
static inline bool extended_addresses_enabled(CPUARMState *env)
31
{
24
{
32
int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1;
25
uint64_t tcr = env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
33
+ int max_vm_pa_size;
26
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
34
27
+ arm_feature(env, ARM_FEATURE_V8)) {
35
kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
28
+ return true;
36
if (kvmfd < 0) {
29
+ }
37
goto err;
30
return arm_el_is_aa64(env, 1) ||
31
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr & TTBCR_EAE));
32
}
33
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/debug_helper.c
36
+++ b/target/arm/debug_helper.c
37
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_debug_exception_fsr(CPUARMState *env)
38
39
if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
40
using_lpae = true;
41
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
42
+ arm_feature(env, ARM_FEATURE_V8)) {
43
+ using_lpae = true;
44
} else {
45
if (arm_feature(env, ARM_FEATURE_LPAE) &&
46
(env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
47
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/tlb_helper.c
50
+++ b/target/arm/tlb_helper.c
51
@@ -XXX,XX +XXX,XX @@ bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
52
if (el == 2 || arm_el_is_aa64(env, el)) {
53
return true;
38
}
54
}
39
- vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
55
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
40
+ max_vm_pa_size = ioctl(kvmfd, KVM_CHECK_EXTENSION, KVM_CAP_ARM_VM_IPA_SIZE);
56
+ arm_feature(env, ARM_FEATURE_V8)) {
41
+ if (max_vm_pa_size < 0) {
57
+ return true;
42
+ max_vm_pa_size = 0;
43
+ }
58
+ }
44
+ vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size);
59
if (arm_feature(env, ARM_FEATURE_LPAE)
45
if (vmfd < 0) {
60
&& (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
46
goto err;
61
return true;
47
}
48
--
62
--
49
2.20.1
63
2.25.1
50
64
51
65
diff view generated by jsdifflib
1
In v8A, the PSTATE.IL bit is set for various kinds of illegal
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
exception return or mode-change attempts. We already set PSTATE.IL
3
(or its AArch32 equivalent CPSR.IL) in all those cases, but we
4
weren't implementing the part of the behaviour where attempting to
5
execute an instruction with PSTATE.IL takes an immediate exception
6
with an appropriate syndrome value.
7
2
8
Add a new TB flags bit tracking PSTATE.IL/CPSR.IL, and generate code
3
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
9
to take an exception instead of whatever the instruction would have
4
Message-id: 20221206102504.165775-6-tobias.roehmel@rwth-aachen.de
10
been.
11
12
PSTATE.IL and CPSR.IL change only on exception entry, attempted
13
exception exit, and various AArch32 mode changes via cpsr_write().
14
These places generally already rebuild the hflags, so the only place
15
we need an extra rebuild_hflags call is in the illegal-return
16
codepath of the AArch64 exception_return helper.
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20210821195958.41312-2-richard.henderson@linaro.org
22
Message-Id: <20210817162118.24319-1-peter.maydell@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
[rth: Added missing returns; set IL bit in syndrome]
25
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
26
---
6
---
27
target/arm/cpu.h | 1 +
7
target/arm/cpu.h | 6 +
28
target/arm/syndrome.h | 5 +++++
8
target/arm/cpu.c | 28 +++-
29
target/arm/translate.h | 2 ++
9
target/arm/helper.c | 302 +++++++++++++++++++++++++++++++++++++++++++
30
target/arm/helper-a64.c | 1 +
10
target/arm/machine.c | 28 ++++
31
target/arm/helper.c | 8 ++++++++
11
4 files changed, 360 insertions(+), 4 deletions(-)
32
target/arm/translate-a64.c | 11 +++++++++++
33
target/arm/translate.c | 21 +++++++++++++++++++++
34
7 files changed, 49 insertions(+)
35
12
36
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
37
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
39
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
40
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
41
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
18
};
42
/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
19
uint64_t sctlr_el[4];
43
FIELD(TBFLAG_ANY, ALIGN_MEM, 12, 1)
20
};
44
+FIELD(TBFLAG_ANY, PSTATE__IL, 13, 1)
21
+ uint64_t vsctlr; /* Virtualization System control register. */
45
22
uint64_t cpacr_el1; /* Architectural feature access control register */
46
/*
23
uint64_t cptr_el[4]; /* ARMv8 feature trap registers */
47
* Bit usage when in AArch32 state, both A- and M-profile.
24
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
48
diff --git a/target/arm/syndrome.h b/target/arm/syndrome.h
25
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
26
*/
27
uint32_t *rbar[M_REG_NUM_BANKS];
28
uint32_t *rlar[M_REG_NUM_BANKS];
29
+ uint32_t *hprbar;
30
+ uint32_t *hprlar;
31
uint32_t mair0[M_REG_NUM_BANKS];
32
uint32_t mair1[M_REG_NUM_BANKS];
33
+ uint32_t hprselr;
34
} pmsav8;
35
36
/* v8M SAU */
37
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
38
bool has_mpu;
39
/* PMSAv7 MPU number of supported regions */
40
uint32_t pmsav7_dregion;
41
+ /* PMSAv8 MPU number of supported hyp regions */
42
+ uint32_t pmsav8r_hdregion;
43
/* v8M SAU number of supported regions */
44
uint32_t sau_sregion;
45
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
49
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/syndrome.h
48
--- a/target/arm/cpu.c
51
+++ b/target/arm/syndrome.h
49
+++ b/target/arm/cpu.c
52
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_wfx(int cv, int cond, int ti, bool is_16bit)
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
53
(cv << 24) | (cond << 20) | ti;
51
sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
54
}
52
}
55
53
}
56
+static inline uint32_t syn_illegalstate(void)
54
+
57
+{
55
+ if (cpu->pmsav8r_hdregion > 0) {
58
+ return (EC_ILLEGALSTATE << ARM_EL_EC_SHIFT) | ARM_EL_IL;
56
+ memset(env->pmsav8.hprbar, 0,
59
+}
57
+ sizeof(*env->pmsav8.hprbar) * cpu->pmsav8r_hdregion);
60
+
58
+ memset(env->pmsav8.hprlar, 0,
61
#endif /* TARGET_ARM_SYNDROME_H */
59
+ sizeof(*env->pmsav8.hprlar) * cpu->pmsav8r_hdregion);
62
diff --git a/target/arm/translate.h b/target/arm/translate.h
60
+ }
63
index XXXXXXX..XXXXXXX 100644
61
+
64
--- a/target/arm/translate.h
62
env->pmsav7.rnr[M_REG_NS] = 0;
65
+++ b/target/arm/translate.h
63
env->pmsav7.rnr[M_REG_S] = 0;
66
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
64
env->pmsav8.mair0[M_REG_NS] = 0;
67
bool hstr_active;
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
68
/* True if memory operations require alignment */
66
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
69
bool align_mem;
67
* to false or by setting pmsav7-dregion to 0.
70
+ /* True if PSTATE.IL is set */
68
*/
71
+ bool pstate_il;
69
- if (!cpu->has_mpu) {
72
/*
70
- cpu->pmsav7_dregion = 0;
73
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
71
- }
74
* < 0, set by the current instruction.
72
- if (cpu->pmsav7_dregion == 0) {
75
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
73
+ if (!cpu->has_mpu || cpu->pmsav7_dregion == 0) {
76
index XXXXXXX..XXXXXXX 100644
74
cpu->has_mpu = false;
77
--- a/target/arm/helper-a64.c
75
+ cpu->pmsav7_dregion = 0;
78
+++ b/target/arm/helper-a64.c
76
+ cpu->pmsav8r_hdregion = 0;
79
@@ -XXX,XX +XXX,XX @@ illegal_return:
80
if (!arm_singlestep_active(env)) {
81
env->pstate &= ~PSTATE_SS;
82
}
77
}
83
+ helper_rebuild_hflags_a64(env, cur_el);
78
84
qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
79
if (arm_feature(env, ARM_FEATURE_PMSA) &&
85
"resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
80
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
86
}
81
env->pmsav7.dracr = g_new0(uint32_t, nr);
82
}
83
}
84
+
85
+ if (cpu->pmsav8r_hdregion > 0xff) {
86
+ error_setg(errp, "PMSAv8 MPU EL2 #regions invalid %" PRIu32,
87
+ cpu->pmsav8r_hdregion);
88
+ return;
89
+ }
90
+
91
+ if (cpu->pmsav8r_hdregion) {
92
+ env->pmsav8.hprbar = g_new0(uint32_t,
93
+ cpu->pmsav8r_hdregion);
94
+ env->pmsav8.hprlar = g_new0(uint32_t,
95
+ cpu->pmsav8r_hdregion);
96
+ }
97
}
98
99
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
87
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
diff --git a/target/arm/helper.c b/target/arm/helper.c
88
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/helper.c
102
--- a/target/arm/helper.c
90
+++ b/target/arm/helper.c
103
+++ b/target/arm/helper.c
91
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
104
@@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
92
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
105
raw_write(env, ri, value);
106
}
107
108
+static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
109
+ uint64_t value)
110
+{
111
+ ARMCPU *cpu = env_archcpu(env);
112
+
113
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
114
+ env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
115
+}
116
+
117
+static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
118
+{
119
+ return env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
120
+}
121
+
122
+static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
123
+ uint64_t value)
124
+{
125
+ ARMCPU *cpu = env_archcpu(env);
126
+
127
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
128
+ env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
129
+}
130
+
131
+static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
132
+{
133
+ return env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
134
+}
135
+
136
+static void prselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
137
+ uint64_t value)
138
+{
139
+ ARMCPU *cpu = env_archcpu(env);
140
+
141
+ /*
142
+ * Ignore writes that would select not implemented region.
143
+ * This is architecturally UNPREDICTABLE.
144
+ */
145
+ if (value >= cpu->pmsav7_dregion) {
146
+ return;
147
+ }
148
+
149
+ env->pmsav7.rnr[M_REG_NS] = value;
150
+}
151
+
152
+static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
153
+ uint64_t value)
154
+{
155
+ ARMCPU *cpu = env_archcpu(env);
156
+
157
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
158
+ env->pmsav8.hprbar[env->pmsav8.hprselr] = value;
159
+}
160
+
161
+static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
162
+{
163
+ return env->pmsav8.hprbar[env->pmsav8.hprselr];
164
+}
165
+
166
+static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
167
+ uint64_t value)
168
+{
169
+ ARMCPU *cpu = env_archcpu(env);
170
+
171
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
172
+ env->pmsav8.hprlar[env->pmsav8.hprselr] = value;
173
+}
174
+
175
+static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
176
+{
177
+ return env->pmsav8.hprlar[env->pmsav8.hprselr];
178
+}
179
+
180
+static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
+ uint64_t value)
182
+{
183
+ uint32_t n;
184
+ uint32_t bit;
185
+ ARMCPU *cpu = env_archcpu(env);
186
+
187
+ /* Ignore writes to unimplemented regions */
188
+ int rmax = MIN(cpu->pmsav8r_hdregion, 32);
189
+ value &= MAKE_64BIT_MASK(0, rmax);
190
+
191
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
192
+
193
+ /* Register alias is only valid for first 32 indexes */
194
+ for (n = 0; n < rmax; ++n) {
195
+ bit = extract32(value, n, 1);
196
+ env->pmsav8.hprlar[n] = deposit32(
197
+ env->pmsav8.hprlar[n], 0, 1, bit);
198
+ }
199
+}
200
+
201
+static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
+{
203
+ uint32_t n;
204
+ uint32_t result = 0x0;
205
+ ARMCPU *cpu = env_archcpu(env);
206
+
207
+ /* Register alias is only valid for first 32 indexes */
208
+ for (n = 0; n < MIN(cpu->pmsav8r_hdregion, 32); ++n) {
209
+ if (env->pmsav8.hprlar[n] & 0x1) {
210
+ result |= (0x1 << n);
211
+ }
212
+ }
213
+ return result;
214
+}
215
+
216
+static void hprselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
217
+ uint64_t value)
218
+{
219
+ ARMCPU *cpu = env_archcpu(env);
220
+
221
+ /*
222
+ * Ignore writes that would select not implemented region.
223
+ * This is architecturally UNPREDICTABLE.
224
+ */
225
+ if (value >= cpu->pmsav8r_hdregion) {
226
+ return;
227
+ }
228
+
229
+ env->pmsav8.hprselr = value;
230
+}
231
+
232
+static void pmsav8r_regn_write(CPUARMState *env, const ARMCPRegInfo *ri,
233
+ uint64_t value)
234
+{
235
+ ARMCPU *cpu = env_archcpu(env);
236
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
237
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
238
+
239
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
240
+
241
+ if (ri->opc1 & 4) {
242
+ if (index >= cpu->pmsav8r_hdregion) {
243
+ return;
244
+ }
245
+ if (ri->opc2 & 0x1) {
246
+ env->pmsav8.hprlar[index] = value;
247
+ } else {
248
+ env->pmsav8.hprbar[index] = value;
249
+ }
250
+ } else {
251
+ if (index >= cpu->pmsav7_dregion) {
252
+ return;
253
+ }
254
+ if (ri->opc2 & 0x1) {
255
+ env->pmsav8.rlar[M_REG_NS][index] = value;
256
+ } else {
257
+ env->pmsav8.rbar[M_REG_NS][index] = value;
258
+ }
259
+ }
260
+}
261
+
262
+static uint64_t pmsav8r_regn_read(CPUARMState *env, const ARMCPRegInfo *ri)
263
+{
264
+ ARMCPU *cpu = env_archcpu(env);
265
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
266
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
267
+
268
+ if (ri->opc1 & 4) {
269
+ if (index >= cpu->pmsav8r_hdregion) {
270
+ return 0x0;
271
+ }
272
+ if (ri->opc2 & 0x1) {
273
+ return env->pmsav8.hprlar[index];
274
+ } else {
275
+ return env->pmsav8.hprbar[index];
276
+ }
277
+ } else {
278
+ if (index >= cpu->pmsav7_dregion) {
279
+ return 0x0;
280
+ }
281
+ if (ri->opc2 & 0x1) {
282
+ return env->pmsav8.rlar[M_REG_NS][index];
283
+ } else {
284
+ return env->pmsav8.rbar[M_REG_NS][index];
285
+ }
286
+ }
287
+}
288
+
289
+static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
290
+ { .name = "PRBAR",
291
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
292
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
293
+ .accessfn = access_tvm_trvm,
294
+ .readfn = prbar_read, .writefn = prbar_write },
295
+ { .name = "PRLAR",
296
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
297
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
298
+ .accessfn = access_tvm_trvm,
299
+ .readfn = prlar_read, .writefn = prlar_write },
300
+ { .name = "PRSELR", .resetvalue = 0,
301
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
302
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
303
+ .writefn = prselr_write,
304
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) },
305
+ { .name = "HPRBAR", .resetvalue = 0,
306
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
307
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
308
+ .readfn = hprbar_read, .writefn = hprbar_write },
309
+ { .name = "HPRLAR",
310
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
311
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
312
+ .readfn = hprlar_read, .writefn = hprlar_write },
313
+ { .name = "HPRSELR", .resetvalue = 0,
314
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
315
+ .access = PL2_RW,
316
+ .writefn = hprselr_write,
317
+ .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) },
318
+ { .name = "HPRENR",
319
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
320
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
321
+ .readfn = hprenr_read, .writefn = hprenr_write },
322
+};
323
+
324
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
325
/* Reset for all these registers is handled in arm_cpu_reset(),
326
* because the PMSAv7 is also used by M-profile CPUs, which do
327
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
328
.access = PL1_R, .type = ARM_CP_CONST,
329
.resetvalue = cpu->pmsav7_dregion << 8
330
};
331
+ /* HMPUIR is specific to PMSA V8 */
332
+ ARMCPRegInfo id_hmpuir_reginfo = {
333
+ .name = "HMPUIR",
334
+ .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4,
335
+ .access = PL2_R, .type = ARM_CP_CONST,
336
+ .resetvalue = cpu->pmsav8r_hdregion
337
+ };
338
static const ARMCPRegInfo crn0_wi_reginfo = {
339
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
340
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
341
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
342
define_arm_cp_regs(cpu, id_cp_reginfo);
343
if (!arm_feature(env, ARM_FEATURE_PMSA)) {
344
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
345
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
346
+ arm_feature(env, ARM_FEATURE_V8)) {
347
+ uint32_t i = 0;
348
+ char *tmp_string;
349
+
350
+ define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
351
+ define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo);
352
+ define_arm_cp_regs(cpu, pmsav8r_cp_reginfo);
353
+
354
+ /* Register alias is only valid for first 32 indexes */
355
+ for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
356
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
357
+ uint8_t opc1 = extract32(i, 4, 1);
358
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
359
+
360
+ tmp_string = g_strdup_printf("PRBAR%u", i);
361
+ ARMCPRegInfo tmp_prbarn_reginfo = {
362
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
363
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
364
+ .access = PL1_RW, .resetvalue = 0,
365
+ .accessfn = access_tvm_trvm,
366
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
367
+ };
368
+ define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
369
+ g_free(tmp_string);
370
+
371
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
372
+ tmp_string = g_strdup_printf("PRLAR%u", i);
373
+ ARMCPRegInfo tmp_prlarn_reginfo = {
374
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
375
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
376
+ .access = PL1_RW, .resetvalue = 0,
377
+ .accessfn = access_tvm_trvm,
378
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
379
+ };
380
+ define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
381
+ g_free(tmp_string);
382
+ }
383
+
384
+ /* Register alias is only valid for first 32 indexes */
385
+ for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) {
386
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
387
+ uint8_t opc1 = 0b100 | extract32(i, 4, 1);
388
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
389
+
390
+ tmp_string = g_strdup_printf("HPRBAR%u", i);
391
+ ARMCPRegInfo tmp_hprbarn_reginfo = {
392
+ .name = tmp_string,
393
+ .type = ARM_CP_NO_RAW,
394
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
395
+ .access = PL2_RW, .resetvalue = 0,
396
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
397
+ };
398
+ define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
399
+ g_free(tmp_string);
400
+
401
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
402
+ tmp_string = g_strdup_printf("HPRLAR%u", i);
403
+ ARMCPRegInfo tmp_hprlarn_reginfo = {
404
+ .name = tmp_string,
405
+ .type = ARM_CP_NO_RAW,
406
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
407
+ .access = PL2_RW, .resetvalue = 0,
408
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
409
+ };
410
+ define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
411
+ g_free(tmp_string);
412
+ }
413
} else if (arm_feature(env, ARM_FEATURE_V7)) {
414
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
415
}
416
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
417
sctlr.type |= ARM_CP_SUPPRESS_TB_END;
418
}
419
define_one_arm_cp_reg(cpu, &sctlr);
420
+
421
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
422
+ arm_feature(env, ARM_FEATURE_V8)) {
423
+ ARMCPRegInfo vsctlr = {
424
+ .name = "VSCTLR", .state = ARM_CP_STATE_AA32,
425
+ .cp = 15, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
426
+ .access = PL2_RW, .resetvalue = 0x0,
427
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.vsctlr),
428
+ };
429
+ define_one_arm_cp_reg(cpu, &vsctlr);
430
+ }
93
}
431
}
94
432
95
+ if (env->uncached_cpsr & CPSR_IL) {
433
if (cpu_isar_feature(aa64_lor, cpu)) {
96
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
434
diff --git a/target/arm/machine.c b/target/arm/machine.c
97
+ }
435
index XXXXXXX..XXXXXXX 100644
98
+
436
--- a/target/arm/machine.c
99
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
437
+++ b/target/arm/machine.c
438
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_needed(void *opaque)
439
arm_feature(env, ARM_FEATURE_V8);
100
}
440
}
101
441
102
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
442
+static bool pmsav8r_needed(void *opaque)
103
}
443
+{
444
+ ARMCPU *cpu = opaque;
445
+ CPUARMState *env = &cpu->env;
446
+
447
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
448
+ arm_feature(env, ARM_FEATURE_V8) &&
449
+ !arm_feature(env, ARM_FEATURE_M);
450
+}
451
+
452
+static const VMStateDescription vmstate_pmsav8r = {
453
+ .name = "cpu/pmsav8/pmsav8r",
454
+ .version_id = 1,
455
+ .minimum_version_id = 1,
456
+ .needed = pmsav8r_needed,
457
+ .fields = (VMStateField[]) {
458
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprbar, ARMCPU,
459
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
460
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprlar, ARMCPU,
461
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
462
+ VMSTATE_END_OF_LIST()
463
+ },
464
+};
465
+
466
static const VMStateDescription vmstate_pmsav8 = {
467
.name = "cpu/pmsav8",
468
.version_id = 1,
469
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
470
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
471
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
472
VMSTATE_END_OF_LIST()
473
+ },
474
+ .subsections = (const VMStateDescription * []) {
475
+ &vmstate_pmsav8r,
476
+ NULL
104
}
477
}
105
478
};
106
+ if (env->pstate & PSTATE_IL) {
479
107
+ DP_TBFLAG_ANY(flags, PSTATE__IL, 1);
108
+ }
109
+
110
if (cpu_isar_feature(aa64_mte, env_archcpu(env))) {
111
/*
112
* Set MTE_ACTIVE if any access may be Checked, and leave clear
113
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/translate-a64.c
116
+++ b/target/arm/translate-a64.c
117
@@ -XXX,XX +XXX,XX @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
118
s->fp_access_checked = false;
119
s->sve_access_checked = false;
120
121
+ if (s->pstate_il) {
122
+ /*
123
+ * Illegal execution state. This has priority over BTI
124
+ * exceptions, but comes after instruction abort exceptions.
125
+ */
126
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
127
+ syn_illegalstate(), default_exception_el(s));
128
+ return;
129
+ }
130
+
131
if (dc_isar_feature(aa64_bti, s)) {
132
if (s->base.num_insns == 1) {
133
/*
134
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
135
#endif
136
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
137
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
138
+ dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
139
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
140
dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
141
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
142
diff --git a/target/arm/translate.c b/target/arm/translate.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/translate.c
145
+++ b/target/arm/translate.c
146
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
147
return;
148
}
149
150
+ if (s->pstate_il) {
151
+ /*
152
+ * Illegal execution state. This has priority over BTI
153
+ * exceptions, but comes after instruction abort exceptions.
154
+ */
155
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
156
+ syn_illegalstate(), default_exception_el(s));
157
+ return;
158
+ }
159
+
160
if (cond == 0xf) {
161
/* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
162
* choose to UNDEF. In ARMv5 and above the space is used
163
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
164
#endif
165
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
166
dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
167
+ dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
168
169
if (arm_feature(env, ARM_FEATURE_M)) {
170
dc->vfp_enabled = 1;
171
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
172
}
173
dc->insn = insn;
174
175
+ if (dc->pstate_il) {
176
+ /*
177
+ * Illegal execution state. This has priority over BTI
178
+ * exceptions, but comes after instruction abort exceptions.
179
+ */
180
+ gen_exception_insn(dc, dc->pc_curr, EXCP_UDEF,
181
+ syn_illegalstate(), default_exception_el(dc));
182
+ return;
183
+ }
184
+
185
if (dc->eci) {
186
/*
187
* For M-profile continuable instructions, ECI/ICI handling
188
--
480
--
189
2.20.1
481
2.25.1
190
482
191
483
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Added ITS command queue handling for MAPTI,MAPI commands,handled ITS
3
Add PMSAv8r translation.
4
translation which triggers an LPI via INT command as well as write
4
5
to GITS_TRANSLATER register,defined enum to differentiate between ITS
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
6
command interrupt trigger and GITS_TRANSLATER based interrupt trigger.
7
Each of these commands make use of other functionalities implemented to
8
get device table entry,collection table entry or interrupt translation
9
table entry required for their processing.
10
11
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210910143951.92242-5-shashi.mallela@linaro.org
7
Message-id: 20221206102504.165775-7-tobias.roehmel@rwth-aachen.de
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
hw/intc/gicv3_internal.h | 12 +
10
target/arm/ptw.c | 126 ++++++++++++++++++++++++++++++++++++++---------
17
include/hw/intc/arm_gicv3_common.h | 2 +
11
1 file changed, 104 insertions(+), 22 deletions(-)
18
hw/intc/arm_gicv3_its.c | 365 ++++++++++++++++++++++++++++-
12
19
3 files changed, 378 insertions(+), 1 deletion(-)
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
21
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/gicv3_internal.h
15
--- a/target/arm/ptw.c
24
+++ b/hw/intc/gicv3_internal.h
16
+++ b/target/arm/ptw.c
25
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
17
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
26
#define ITTADDR_MASK MAKE_64BIT_MASK(ITTADDR_SHIFT, ITTADDR_LENGTH)
18
27
#define SIZE_MASK 0x1f
19
if (arm_feature(env, ARM_FEATURE_M)) {
28
20
return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
29
+/* MAPI command fields */
21
- } else {
30
+#define EVENTID_MASK ((1ULL << 32) - 1)
22
- return regime_sctlr(env, mmu_idx) & SCTLR_BR;
31
+
23
}
32
+/* MAPTI command fields */
24
+
33
+#define pINTID_SHIFT 32
25
+ if (mmu_idx == ARMMMUIdx_Stage2) {
34
+#define pINTID_MASK MAKE_64BIT_MASK(32, 32)
26
+ return false;
35
+
27
+ }
36
#define DEVID_SHIFT 32
28
+
37
#define DEVID_MASK MAKE_64BIT_MASK(32, 32)
29
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
38
39
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
40
* Values: | vPEID | ICID |
41
*/
42
#define ITS_ITT_ENTRY_SIZE 0xC
43
+#define ITE_ENTRY_INTTYPE_SHIFT 1
44
+#define ITE_ENTRY_INTID_SHIFT 2
45
+#define ITE_ENTRY_INTID_MASK MAKE_64BIT_MASK(2, 24)
46
+#define ITE_ENTRY_INTSP_SHIFT 26
47
+#define ITE_ENTRY_ICID_MASK MAKE_64BIT_MASK(0, 16)
48
49
/* 16 bits EventId */
50
#define ITS_IDBITS GICD_TYPER_IDBITS
51
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
52
index XXXXXXX..XXXXXXX 100644
53
--- a/include/hw/intc/arm_gicv3_common.h
54
+++ b/include/hw/intc/arm_gicv3_common.h
55
@@ -XXX,XX +XXX,XX @@
56
#define GICV3_MAXIRQ 1020
57
#define GICV3_MAXSPI (GICV3_MAXIRQ - GIC_INTERNAL)
58
59
+#define GICV3_LPI_INTID_START 8192
60
+
61
#define GICV3_REDIST_SIZE 0x20000
62
63
/* Number of SGI target-list bits */
64
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/intc/arm_gicv3_its.c
67
+++ b/hw/intc/arm_gicv3_its.c
68
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSClass {
69
void (*parent_reset)(DeviceState *dev);
70
};
71
72
+/*
73
+ * This is an internal enum used to distinguish between LPI triggered
74
+ * via command queue and LPI triggered via gits_translater write.
75
+ */
76
+typedef enum ItsCmdType {
77
+ NONE = 0, /* internal indication for GITS_TRANSLATER write */
78
+ CLEAR = 1,
79
+ DISCARD = 2,
80
+ INT = 3,
81
+} ItsCmdType;
82
+
83
+typedef struct {
84
+ uint32_t iteh;
85
+ uint64_t itel;
86
+} IteEntry;
87
+
88
static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
89
{
90
uint64_t result = 0;
91
@@ -XXX,XX +XXX,XX @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
92
return result;
93
}
30
}
94
31
95
+static bool get_cte(GICv3ITSState *s, uint16_t icid, uint64_t *cte,
32
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
96
+ MemTxResult *res)
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
34
return !(result->f.prot & (1 << access_type));
35
}
36
37
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
38
+ uint32_t secure)
97
+{
39
+{
98
+ AddressSpace *as = &s->gicv3->dma_as;
40
+ if (regime_el(env, mmu_idx) == 2) {
99
+ uint64_t l2t_addr;
41
+ return env->pmsav8.hprbar;
100
+ uint64_t value;
42
+ } else {
101
+ bool valid_l2t;
43
+ return env->pmsav8.rbar[secure];
102
+ uint32_t l2t_id;
44
+ }
103
+ uint32_t max_l2_entries;
104
+
105
+ if (s->ct.indirect) {
106
+ l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE);
107
+
108
+ value = address_space_ldq_le(as,
109
+ s->ct.base_addr +
110
+ (l2t_id * L1TABLE_ENTRY_SIZE),
111
+ MEMTXATTRS_UNSPECIFIED, res);
112
+
113
+ if (*res == MEMTX_OK) {
114
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
115
+
116
+ if (valid_l2t) {
117
+ max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
118
+
119
+ l2t_addr = value & ((1ULL << 51) - 1);
120
+
121
+ *cte = address_space_ldq_le(as, l2t_addr +
122
+ ((icid % max_l2_entries) * GITS_CTE_SIZE),
123
+ MEMTXATTRS_UNSPECIFIED, res);
124
+ }
125
+ }
126
+ } else {
127
+ /* Flat level table */
128
+ *cte = address_space_ldq_le(as, s->ct.base_addr +
129
+ (icid * GITS_CTE_SIZE),
130
+ MEMTXATTRS_UNSPECIFIED, res);
131
+ }
132
+
133
+ return (*cte & TABLE_ENTRY_VALID_MASK) != 0;
134
+}
45
+}
135
+
46
+
136
+static bool update_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
47
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
137
+ IteEntry ite)
48
+ uint32_t secure)
138
+{
49
+{
139
+ AddressSpace *as = &s->gicv3->dma_as;
50
+ if (regime_el(env, mmu_idx) == 2) {
140
+ uint64_t itt_addr;
51
+ return env->pmsav8.hprlar;
141
+ MemTxResult res = MEMTX_OK;
52
+ } else {
142
+
53
+ return env->pmsav8.rlar[secure];
143
+ itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
144
+ itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
145
+
146
+ address_space_stq_le(as, itt_addr + (eventid * (sizeof(uint64_t) +
147
+ sizeof(uint32_t))), ite.itel, MEMTXATTRS_UNSPECIFIED,
148
+ &res);
149
+
150
+ if (res == MEMTX_OK) {
151
+ address_space_stl_le(as, itt_addr + (eventid * (sizeof(uint64_t) +
152
+ sizeof(uint32_t))) + sizeof(uint32_t), ite.iteh,
153
+ MEMTXATTRS_UNSPECIFIED, &res);
154
+ }
155
+ if (res != MEMTX_OK) {
156
+ return false;
157
+ } else {
158
+ return true;
159
+ }
54
+ }
160
+}
55
+}
161
+
56
+
162
+static bool get_ite(GICv3ITSState *s, uint32_t eventid, uint64_t dte,
57
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
163
+ uint16_t *icid, uint32_t *pIntid, MemTxResult *res)
58
MMUAccessType access_type, ARMMMUIdx mmu_idx,
164
+{
59
bool secure, GetPhysAddrResult *result,
165
+ AddressSpace *as = &s->gicv3->dma_as;
60
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
166
+ uint64_t itt_addr;
61
bool hit = false;
167
+ bool status = false;
62
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
168
+ IteEntry ite = {};
63
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
169
+
64
+ int region_counter;
170
+ itt_addr = (dte & GITS_DTE_ITTADDR_MASK) >> GITS_DTE_ITTADDR_SHIFT;
65
+
171
+ itt_addr <<= ITTADDR_SHIFT; /* 256 byte aligned */
66
+ if (regime_el(env, mmu_idx) == 2) {
172
+
67
+ region_counter = cpu->pmsav8r_hdregion;
173
+ ite.itel = address_space_ldq_le(as, itt_addr +
68
+ } else {
174
+ (eventid * (sizeof(uint64_t) +
69
+ region_counter = cpu->pmsav7_dregion;
175
+ sizeof(uint32_t))), MEMTXATTRS_UNSPECIFIED,
70
+ }
176
+ res);
71
177
+
72
result->f.lg_page_size = TARGET_PAGE_BITS;
178
+ if (*res == MEMTX_OK) {
73
result->f.phys_addr = address;
179
+ ite.iteh = address_space_ldl_le(as, itt_addr +
74
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
180
+ (eventid * (sizeof(uint64_t) +
75
*mregion = -1;
181
+ sizeof(uint32_t))) + sizeof(uint32_t),
76
}
182
+ MEMTXATTRS_UNSPECIFIED, res);
77
183
+
78
+ if (mmu_idx == ARMMMUIdx_Stage2) {
184
+ if (*res == MEMTX_OK) {
79
+ fi->stage2 = true;
185
+ if (ite.itel & TABLE_ENTRY_VALID_MASK) {
80
+ }
186
+ if ((ite.itel >> ITE_ENTRY_INTTYPE_SHIFT) &
81
+
187
+ GITS_TYPE_PHYSICAL) {
82
/*
188
+ *pIntid = (ite.itel & ITE_ENTRY_INTID_MASK) >>
83
* Unlike the ARM ARM pseudocode, we don't need to check whether this
189
+ ITE_ENTRY_INTID_SHIFT;
84
* was an exception vector read from the vector table (which is always
190
+ *icid = ite.iteh & ITE_ENTRY_ICID_MASK;
85
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
191
+ status = true;
86
hit = true;
87
}
88
89
- for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
90
+ uint32_t bitmask;
91
+ if (arm_feature(env, ARM_FEATURE_M)) {
92
+ bitmask = 0x1f;
93
+ } else {
94
+ bitmask = 0x3f;
95
+ fi->level = 0;
96
+ }
97
+
98
+ for (n = region_counter - 1; n >= 0; n--) {
99
/* region search */
100
/*
101
- * Note that the base address is bits [31:5] from the register
102
- * with bits [4:0] all zeroes, but the limit address is bits
103
- * [31:5] from the register with bits [4:0] all ones.
104
+ * Note that the base address is bits [31:x] from the register
105
+ * with bits [x-1:0] all zeroes, but the limit address is bits
106
+ * [31:x] from the register with bits [x:0] all ones. Where x is
107
+ * 5 for Cortex-M and 6 for Cortex-R
108
*/
109
- uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
110
- uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
111
+ uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
112
+ uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
113
114
- if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
115
+ if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
116
/* Region disabled */
117
continue;
118
}
119
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
120
* PMSAv7 where highest-numbered-region wins)
121
*/
122
fi->type = ARMFault_Permission;
123
- fi->level = 1;
124
+ if (arm_feature(env, ARM_FEATURE_M)) {
125
+ fi->level = 1;
192
+ }
126
+ }
127
return true;
128
}
129
130
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
131
}
132
133
if (!hit) {
134
- /* background fault */
135
- fi->type = ARMFault_Background;
136
+ if (arm_feature(env, ARM_FEATURE_M)) {
137
+ fi->type = ARMFault_Background;
138
+ } else {
139
+ fi->type = ARMFault_Permission;
140
+ }
141
return true;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
145
/* hit using the background region */
146
get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
147
} else {
148
- uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
149
- uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
150
+ uint32_t matched_rbar = regime_rbar(env, mmu_idx, secure)[matchregion];
151
+ uint32_t matched_rlar = regime_rlar(env, mmu_idx, secure)[matchregion];
152
+ uint32_t ap = extract32(matched_rbar, 1, 2);
153
+ uint32_t xn = extract32(matched_rbar, 0, 1);
154
bool pxn = false;
155
156
if (arm_feature(env, ARM_FEATURE_V8_1M)) {
157
- pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
158
+ pxn = extract32(matched_rlar, 4, 1);
159
}
160
161
if (m_is_system_region(env, address)) {
162
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
163
xn = 1;
164
}
165
166
- result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
167
+ if (regime_el(env, mmu_idx) == 2) {
168
+ result->f.prot = simple_ap_to_rw_prot_is_user(ap,
169
+ mmu_idx != ARMMMUIdx_E2);
170
+ } else {
171
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
172
+ }
173
+
174
+ if (!arm_feature(env, ARM_FEATURE_M)) {
175
+ uint8_t attrindx = extract32(matched_rlar, 1, 3);
176
+ uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
177
+ uint8_t sh = extract32(matched_rlar, 3, 2);
178
+
179
+ if (regime_sctlr(env, mmu_idx) & SCTLR_WXN &&
180
+ result->f.prot & PAGE_WRITE && mmu_idx != ARMMMUIdx_Stage2) {
181
+ xn = 0x1;
193
+ }
182
+ }
194
+ }
183
+
195
+ }
184
+ if ((regime_el(env, mmu_idx) == 1) &&
196
+ return status;
185
+ regime_sctlr(env, mmu_idx) & SCTLR_UWXN && ap == 0x1) {
197
+}
186
+ pxn = 0x1;
198
+
199
+static uint64_t get_dte(GICv3ITSState *s, uint32_t devid, MemTxResult *res)
200
+{
201
+ AddressSpace *as = &s->gicv3->dma_as;
202
+ uint64_t l2t_addr;
203
+ uint64_t value;
204
+ bool valid_l2t;
205
+ uint32_t l2t_id;
206
+ uint32_t max_l2_entries;
207
+
208
+ if (s->dt.indirect) {
209
+ l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE);
210
+
211
+ value = address_space_ldq_le(as,
212
+ s->dt.base_addr +
213
+ (l2t_id * L1TABLE_ENTRY_SIZE),
214
+ MEMTXATTRS_UNSPECIFIED, res);
215
+
216
+ if (*res == MEMTX_OK) {
217
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
218
+
219
+ if (valid_l2t) {
220
+ max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
221
+
222
+ l2t_addr = value & ((1ULL << 51) - 1);
223
+
224
+ value = address_space_ldq_le(as, l2t_addr +
225
+ ((devid % max_l2_entries) * GITS_DTE_SIZE),
226
+ MEMTXATTRS_UNSPECIFIED, res);
227
+ }
187
+ }
228
+ }
188
+
229
+ } else {
189
+ result->cacheattrs.is_s2_format = false;
230
+ /* Flat level table */
190
+ result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8);
231
+ value = address_space_ldq_le(as, s->dt.base_addr +
191
+ result->cacheattrs.shareability = sh;
232
+ (devid * GITS_DTE_SIZE),
192
+ }
233
+ MEMTXATTRS_UNSPECIFIED, res);
193
+
234
+ }
194
if (result->f.prot && !xn && !(pxn && !is_user)) {
235
+
195
result->f.prot |= PAGE_EXEC;
236
+ return value;
196
}
237
+}
197
- /*
238
+
198
- * We don't need to look the attribute up in the MAIR0/MAIR1
239
+/*
199
- * registers because that only tells us about cacheability.
240
+ * This function handles the processing of following commands based on
200
- */
241
+ * the ItsCmdType parameter passed:-
201
+
242
+ * 1. triggering of lpi interrupt translation via ITS INT command
202
if (mregion) {
243
+ * 2. triggering of lpi interrupt translation via gits_translater register
203
*mregion = matchregion;
244
+ * 3. handling of ITS CLEAR command
204
}
245
+ * 4. handling of ITS DISCARD command
205
}
246
+ */
206
247
+static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
207
fi->type = ARMFault_Permission;
248
+ ItsCmdType cmd)
208
- fi->level = 1;
249
+{
209
+ if (arm_feature(env, ARM_FEATURE_M)) {
250
+ AddressSpace *as = &s->gicv3->dma_as;
210
+ fi->level = 1;
251
+ uint32_t devid, eventid;
211
+ }
252
+ MemTxResult res = MEMTX_OK;
212
return !(result->f.prot & (1 << access_type));
253
+ bool dte_valid;
254
+ uint64_t dte = 0;
255
+ uint32_t max_eventid;
256
+ uint16_t icid = 0;
257
+ uint32_t pIntid = 0;
258
+ bool ite_valid = false;
259
+ uint64_t cte = 0;
260
+ bool cte_valid = false;
261
+ bool result = false;
262
+
263
+ if (cmd == NONE) {
264
+ devid = offset;
265
+ } else {
266
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
267
+
268
+ offset += NUM_BYTES_IN_DW;
269
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
270
+ MEMTXATTRS_UNSPECIFIED, &res);
271
+ }
272
+
273
+ if (res != MEMTX_OK) {
274
+ return result;
275
+ }
276
+
277
+ eventid = (value & EVENTID_MASK);
278
+
279
+ dte = get_dte(s, devid, &res);
280
+
281
+ if (res != MEMTX_OK) {
282
+ return result;
283
+ }
284
+ dte_valid = dte & TABLE_ENTRY_VALID_MASK;
285
+
286
+ if (dte_valid) {
287
+ max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
288
+
289
+ ite_valid = get_ite(s, eventid, dte, &icid, &pIntid, &res);
290
+
291
+ if (res != MEMTX_OK) {
292
+ return result;
293
+ }
294
+
295
+ if (ite_valid) {
296
+ cte_valid = get_cte(s, icid, &cte, &res);
297
+ }
298
+
299
+ if (res != MEMTX_OK) {
300
+ return result;
301
+ }
302
+ }
303
+
304
+ if ((devid > s->dt.maxids.max_devids) || !dte_valid || !ite_valid ||
305
+ !cte_valid || (eventid > max_eventid)) {
306
+ qemu_log_mask(LOG_GUEST_ERROR,
307
+ "%s: invalid command attributes "
308
+ "devid %d or eventid %d or invalid dte %d or"
309
+ "invalid cte %d or invalid ite %d\n",
310
+ __func__, devid, eventid, dte_valid, cte_valid,
311
+ ite_valid);
312
+ /*
313
+ * in this implementation, in case of error
314
+ * we ignore this command and move onto the next
315
+ * command in the queue
316
+ */
317
+ } else {
318
+ /*
319
+ * Current implementation only supports rdbase == procnum
320
+ * Hence rdbase physical address is ignored
321
+ */
322
+ if (cmd == DISCARD) {
323
+ IteEntry ite = {};
324
+ /* remove mapping from interrupt translation table */
325
+ result = update_ite(s, eventid, dte, ite);
326
+ }
327
+ }
328
+
329
+ return result;
330
+}
331
+
332
+static bool process_mapti(GICv3ITSState *s, uint64_t value, uint32_t offset,
333
+ bool ignore_pInt)
334
+{
335
+ AddressSpace *as = &s->gicv3->dma_as;
336
+ uint32_t devid, eventid;
337
+ uint32_t pIntid = 0;
338
+ uint32_t max_eventid, max_Intid;
339
+ bool dte_valid;
340
+ MemTxResult res = MEMTX_OK;
341
+ uint16_t icid = 0;
342
+ uint64_t dte = 0;
343
+ IteEntry ite;
344
+ uint32_t int_spurious = INTID_SPURIOUS;
345
+ bool result = false;
346
+
347
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
348
+ offset += NUM_BYTES_IN_DW;
349
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
350
+ MEMTXATTRS_UNSPECIFIED, &res);
351
+
352
+ if (res != MEMTX_OK) {
353
+ return result;
354
+ }
355
+
356
+ eventid = (value & EVENTID_MASK);
357
+
358
+ if (!ignore_pInt) {
359
+ pIntid = ((value & pINTID_MASK) >> pINTID_SHIFT);
360
+ }
361
+
362
+ offset += NUM_BYTES_IN_DW;
363
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
364
+ MEMTXATTRS_UNSPECIFIED, &res);
365
+
366
+ if (res != MEMTX_OK) {
367
+ return result;
368
+ }
369
+
370
+ icid = value & ICID_MASK;
371
+
372
+ dte = get_dte(s, devid, &res);
373
+
374
+ if (res != MEMTX_OK) {
375
+ return result;
376
+ }
377
+ dte_valid = dte & TABLE_ENTRY_VALID_MASK;
378
+
379
+ max_eventid = (1UL << (((dte >> 1U) & SIZE_MASK) + 1));
380
+
381
+ if (!ignore_pInt) {
382
+ max_Intid = (1ULL << (GICD_TYPER_IDBITS + 1)) - 1;
383
+ }
384
+
385
+ if ((devid > s->dt.maxids.max_devids) || (icid > s->ct.maxids.max_collids)
386
+ || !dte_valid || (eventid > max_eventid) ||
387
+ (!ignore_pInt && (((pIntid < GICV3_LPI_INTID_START) ||
388
+ (pIntid > max_Intid)) && (pIntid != INTID_SPURIOUS)))) {
389
+ qemu_log_mask(LOG_GUEST_ERROR,
390
+ "%s: invalid command attributes "
391
+ "devid %d or icid %d or eventid %d or pIntid %d or"
392
+ "unmapped dte %d\n", __func__, devid, icid, eventid,
393
+ pIntid, dte_valid);
394
+ /*
395
+ * in this implementation, in case of error
396
+ * we ignore this command and move onto the next
397
+ * command in the queue
398
+ */
399
+ } else {
400
+ /* add ite entry to interrupt translation table */
401
+ ite.itel = (dte_valid & TABLE_ENTRY_VALID_MASK) |
402
+ (GITS_TYPE_PHYSICAL << ITE_ENTRY_INTTYPE_SHIFT);
403
+
404
+ if (ignore_pInt) {
405
+ ite.itel |= (eventid << ITE_ENTRY_INTID_SHIFT);
406
+ } else {
407
+ ite.itel |= (pIntid << ITE_ENTRY_INTID_SHIFT);
408
+ }
409
+ ite.itel |= (int_spurious << ITE_ENTRY_INTSP_SHIFT);
410
+ ite.iteh = icid;
411
+
412
+ result = update_ite(s, eventid, dte, ite);
413
+ }
414
+
415
+ return result;
416
+}
417
+
418
static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
419
uint64_t rdbase)
420
{
421
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
422
423
switch (cmd) {
424
case GITS_CMD_INT:
425
+ res = process_its_cmd(s, data, cq_offset, INT);
426
break;
427
case GITS_CMD_CLEAR:
428
+ res = process_its_cmd(s, data, cq_offset, CLEAR);
429
break;
430
case GITS_CMD_SYNC:
431
/*
432
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
433
result = process_mapc(s, cq_offset);
434
break;
435
case GITS_CMD_MAPTI:
436
+ result = process_mapti(s, data, cq_offset, false);
437
break;
438
case GITS_CMD_MAPI:
439
+ result = process_mapti(s, data, cq_offset, true);
440
break;
441
case GITS_CMD_DISCARD:
442
+ result = process_its_cmd(s, data, cq_offset, DISCARD);
443
break;
444
case GITS_CMD_INV:
445
case GITS_CMD_INVALL:
446
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
447
uint64_t data, unsigned size,
448
MemTxAttrs attrs)
449
{
450
- return MEMTX_OK;
451
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
452
+ bool result = true;
453
+ uint32_t devid = 0;
454
+
455
+ switch (offset) {
456
+ case GITS_TRANSLATER:
457
+ if (s->ctlr & ITS_CTLR_ENABLED) {
458
+ devid = attrs.requester_id;
459
+ result = process_its_cmd(s, data, devid, NONE);
460
+ }
461
+ break;
462
+ default:
463
+ break;
464
+ }
465
+
466
+ if (result) {
467
+ return MEMTX_OK;
468
+ } else {
469
+ return MEMTX_ERROR;
470
+ }
471
}
213
}
472
214
473
static bool its_writel(GICv3ITSState *s, hwaddr offset,
215
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
216
cacheattrs1 = result->cacheattrs;
217
memset(result, 0, sizeof(*result));
218
219
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi);
220
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
221
+ ret = get_phys_addr_pmsav8(env, ipa, access_type,
222
+ ptw->in_mmu_idx, is_secure, result, fi);
223
+ } else {
224
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
225
+ is_el0, result, fi);
226
+ }
227
fi->s2addr = ipa;
228
229
/* Combine the S1 and S2 perms. */
474
--
230
--
475
2.20.1
231
2.25.1
476
232
477
233
diff view generated by jsdifflib
1
From: Chris Rauer <crauer@google.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
kudo-bmc is a board supported by OpenBMC.
3
All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3
4
https://github.com/openbmc/openbmc/tree/master/meta-fii/meta-kudo
5
4
6
Since v1:
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
7
- hyphenated Cortex-A9
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
7
Message-id: 20221206102504.165775-8-tobias.roehmel@rwth-aachen.de
9
Tested: Booted kudo firmware.
10
Signed-off-by: Chris Rauer <crauer@google.com>
11
Reviewed-by: Patrick Venture <venture@google.com>
12
Message-id: 20210907223234.1165705-1-crauer@google.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
docs/system/arm/nuvoton.rst | 1 +
10
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
16
hw/arm/npcm7xx_boards.c | 34 ++++++++++++++++++++++++++++++++++
11
1 file changed, 42 insertions(+)
17
2 files changed, 35 insertions(+)
18
12
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
13
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/nuvoton.rst
15
--- a/target/arm/cpu_tcg.c
22
+++ b/docs/system/arm/nuvoton.rst
16
+++ b/target/arm/cpu_tcg.c
23
@@ -XXX,XX +XXX,XX @@ Hyperscale applications. The following machines are based on this chip :
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
24
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
25
- ``quanta-gbs-bmc`` Quanta GBS server BMC
26
- ``quanta-gsj`` Quanta GSJ server BMC
27
+- ``kudo-bmc`` Fii USA Kudo server BMC
28
29
There are also two more SoCs, NPCM710 and NPCM705, which are single-core
30
variants of NPCM750 and NPCM730, respectively. These are currently not
31
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/npcm7xx_boards.c
34
+++ b/hw/arm/npcm7xx_boards.c
35
@@ -XXX,XX +XXX,XX @@
36
#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
37
#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
38
#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
39
+#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
40
41
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
42
43
@@ -XXX,XX +XXX,XX @@ static void quanta_gbs_init(MachineState *machine)
44
npcm7xx_load_kernel(machine, soc);
45
}
19
}
46
20
47
+static void kudo_bmc_init(MachineState *machine)
21
+static void cortex_r52_initfn(Object *obj)
48
+{
22
+{
49
+ NPCM7xxState *soc;
23
+ ARMCPU *cpu = ARM_CPU(obj);
50
+
24
+
51
+ soc = npcm7xx_create_soc(machine, KUDO_BMC_POWER_ON_STRAPS);
25
+ set_feature(&cpu->env, ARM_FEATURE_V8);
52
+ npcm7xx_connect_dram(soc, machine->ram);
26
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
53
+ qdev_realize(DEVICE(soc), NULL, &error_fatal);
27
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
28
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
29
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
30
+ cpu->midr = 0x411fd133; /* r1p3 */
31
+ cpu->revidr = 0x00000000;
32
+ cpu->reset_fpsid = 0x41034023;
33
+ cpu->isar.mvfr0 = 0x10110222;
34
+ cpu->isar.mvfr1 = 0x12111111;
35
+ cpu->isar.mvfr2 = 0x00000043;
36
+ cpu->ctr = 0x8144c004;
37
+ cpu->reset_sctlr = 0x30c50838;
38
+ cpu->isar.id_pfr0 = 0x00000131;
39
+ cpu->isar.id_pfr1 = 0x10111001;
40
+ cpu->isar.id_dfr0 = 0x03010006;
41
+ cpu->id_afr0 = 0x00000000;
42
+ cpu->isar.id_mmfr0 = 0x00211040;
43
+ cpu->isar.id_mmfr1 = 0x40000000;
44
+ cpu->isar.id_mmfr2 = 0x01200000;
45
+ cpu->isar.id_mmfr3 = 0xf0102211;
46
+ cpu->isar.id_mmfr4 = 0x00000010;
47
+ cpu->isar.id_isar0 = 0x02101110;
48
+ cpu->isar.id_isar1 = 0x13112111;
49
+ cpu->isar.id_isar2 = 0x21232142;
50
+ cpu->isar.id_isar3 = 0x01112131;
51
+ cpu->isar.id_isar4 = 0x00010142;
52
+ cpu->isar.id_isar5 = 0x00010001;
53
+ cpu->isar.dbgdidr = 0x77168000;
54
+ cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
55
+ cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
56
+ cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
54
+
57
+
55
+ npcm7xx_load_bootrom(machine, soc);
58
+ cpu->pmsav7_dregion = 16;
56
+ npcm7xx_connect_flash(&soc->fiu[0], 0, "mx66u51235f",
59
+ cpu->pmsav8r_hdregion = 16;
57
+ drive_get(IF_MTD, 0, 0));
58
+ npcm7xx_connect_flash(&soc->fiu[1], 0, "mx66u51235f",
59
+ drive_get(IF_MTD, 3, 0));
60
+
61
+ npcm7xx_load_kernel(machine, soc);
62
+}
60
+}
63
+
61
+
64
static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type)
62
static void cortex_r5f_initfn(Object *obj)
65
{
63
{
66
NPCM7xxClass *sc = NPCM7XX_CLASS(object_class_by_name(type));
64
ARMCPU *cpu = ARM_CPU(obj);
67
@@ -XXX,XX +XXX,XX @@ static void gbs_bmc_machine_class_init(ObjectClass *oc, void *data)
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
68
mc->default_ram_size = 1 * GiB;
66
.class_init = arm_v7m_class_init },
69
}
67
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
68
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
71
+static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data)
69
+ { .name = "cortex-r52", .initfn = cortex_r52_initfn },
72
+{
70
{ .name = "ti925t", .initfn = ti925t_initfn },
73
+ NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc);
71
{ .name = "sa1100", .initfn = sa1100_initfn },
74
+ MachineClass *mc = MACHINE_CLASS(oc);
72
{ .name = "sa1110", .initfn = sa1110_initfn },
75
+
76
+ npcm7xx_set_soc_type(nmc, TYPE_NPCM730);
77
+
78
+ mc->desc = "Kudo BMC (Cortex-A9)";
79
+ mc->init = kudo_bmc_init;
80
+ mc->default_ram_size = 1 * GiB;
81
+};
82
+
83
static const TypeInfo npcm7xx_machine_types[] = {
84
{
85
.name = TYPE_NPCM7XX_MACHINE,
86
@@ -XXX,XX +XXX,XX @@ static const TypeInfo npcm7xx_machine_types[] = {
87
.name = MACHINE_TYPE_NAME("quanta-gbs-bmc"),
88
.parent = TYPE_NPCM7XX_MACHINE,
89
.class_init = gbs_bmc_machine_class_init,
90
+ }, {
91
+ .name = MACHINE_TYPE_NAME("kudo-bmc"),
92
+ .parent = TYPE_NPCM7XX_MACHINE,
93
+ .class_init = kudo_bmc_machine_class_init,
94
},
95
};
96
97
--
73
--
98
2.20.1
74
2.25.1
99
75
100
76
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Read or write to uart registers when unclocked or in reset should be
3
The check semihosting_enabled() wants to know if the guest is
4
ignored. Add the check there, and as a result of this, the check in
4
currently in user mode. Unlike the other cases the test was inverted
5
uart_write_tx_fifo() is now unnecessary.
5
causing us to block semihosting calls in non-EL0 modes.
6
6
7
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
7
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Fixes: 19b26317e9 (target/arm: Honour -semihosting-config userspace=on)
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20210901124521.30599-6-bmeng.cn@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/char/cadence_uart.c | 15 ++++++++++-----
13
target/arm/translate.c | 2 +-
14
1 file changed, 10 insertions(+), 5 deletions(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
15
16
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/char/cadence_uart.c
18
--- a/target/arm/translate.c
19
+++ b/hw/char/cadence_uart.c
19
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
20
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
21
static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
21
* semihosting, to provide some semblance of security
22
int size)
22
* (and for consistency with our 32-bit semihosting).
23
{
23
*/
24
- /* ignore characters when unclocked or in reset */
24
- if (semihosting_enabled(s->current_el != 0) &&
25
- if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
25
+ if (semihosting_enabled(s->current_el == 0) &&
26
- return;
26
(imm == (s->thumb ? 0x3c : 0xf000))) {
27
- }
27
gen_exception_internal_insn(s, EXCP_SEMIHOST);
28
-
29
if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
30
return;
28
return;
31
}
32
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
33
{
34
CadenceUARTState *s = opaque;
35
36
+ /* ignore access when unclocked or in reset */
37
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
38
+ return MEMTX_ERROR;
39
+ }
40
+
41
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
42
offset >>= 2;
43
if (offset >= CADENCE_UART_R_MAX) {
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_read(void *opaque, hwaddr offset,
45
CadenceUARTState *s = opaque;
46
uint32_t c = 0;
47
48
+ /* ignore access when unclocked or in reset */
49
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
50
+ return MEMTX_ERROR;
51
+ }
52
+
53
offset >>= 2;
54
if (offset >= CADENCE_UART_R_MAX) {
55
return MEMTX_DECODE_ERROR;
56
--
29
--
57
2.20.1
30
2.25.1
58
31
59
32
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Implemented lpi processing at redistributor to get lpi config info
3
Fix typos, add background information
4
from lpi configuration table,determine priority,set pending state in
5
lpi pending table and forward the lpi to cpuif.Added logic to invoke
6
redistributor lpi processing with translated LPI which set/clear LPI
7
from ITS device as part of ITS INT,CLEAR,DISCARD command and
8
GITS_TRANSLATER processing.
9
4
10
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
11
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210910143951.92242-7-shashi.mallela@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
8
---
16
hw/intc/gicv3_internal.h | 9 ++
9
hw/timer/imx_epit.c | 20 ++++++++++++++++----
17
include/hw/intc/arm_gicv3_common.h | 7 ++
10
1 file changed, 16 insertions(+), 4 deletions(-)
18
hw/intc/arm_gicv3.c | 14 +++
19
hw/intc/arm_gicv3_common.c | 1 +
20
hw/intc/arm_gicv3_cpuif.c | 7 +-
21
hw/intc/arm_gicv3_its.c | 23 +++++
22
hw/intc/arm_gicv3_redist.c | 141 +++++++++++++++++++++++++++++
23
7 files changed, 200 insertions(+), 2 deletions(-)
24
11
25
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
12
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
26
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/intc/gicv3_internal.h
14
--- a/hw/timer/imx_epit.c
28
+++ b/hw/intc/gicv3_internal.h
15
+++ b/hw/timer/imx_epit.c
29
@@ -XXX,XX +XXX,XX @@ FIELD(GICR_PENDBASER, PHYADDR, 16, 36)
16
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
30
FIELD(GICR_PENDBASER, OUTERCACHE, 56, 3)
31
FIELD(GICR_PENDBASER, PTZ, 62, 1)
32
33
+#define GICR_PROPBASER_IDBITS_THRESHOLD 0xd
34
+
35
#define ICC_CTLR_EL1_CBPR (1U << 0)
36
#define ICC_CTLR_EL1_EOIMODE (1U << 1)
37
#define ICC_CTLR_EL1_PMHE (1U << 6)
38
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
39
40
#define L1TABLE_ENTRY_SIZE 8
41
42
+#define LPI_CTE_ENABLED TABLE_ENTRY_VALID_MASK
43
+#define LPI_PRIORITY_MASK 0xfc
44
+
45
#define GITS_CMDQ_ENTRY_SIZE 32
46
#define NUM_BYTES_IN_DW 8
47
48
@@ -XXX,XX +XXX,XX @@ FIELD(MAPC, RDBASE, 16, 32)
49
* Valid = 1 bit,RDBase = 36 bits(considering max RDBASE)
50
*/
51
#define GITS_CTE_SIZE (0x8ULL)
52
+#define GITS_CTE_RDBASE_PROCNUM_MASK MAKE_64BIT_MASK(1, RDBASE_PROCNUM_LENGTH)
53
54
/* Special interrupt IDs */
55
#define INTID_SECURE 1020
56
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
57
unsigned size, MemTxAttrs attrs);
58
void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
59
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
60
+void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level);
61
+void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level);
62
+void gicv3_redist_update_lpi(GICv3CPUState *cs);
63
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
64
void gicv3_init_cpuif(GICv3State *s);
65
66
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
67
index XXXXXXX..XXXXXXX 100644
68
--- a/include/hw/intc/arm_gicv3_common.h
69
+++ b/include/hw/intc/arm_gicv3_common.h
70
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
71
* real state above; it doesn't need to be migrated.
72
*/
73
PendingIrq hppi;
74
+
75
+ /*
76
+ * Cached information recalculated from LPI tables
77
+ * in guest memory
78
+ */
79
+ PendingIrq hpplpi;
80
+
81
/* This is temporary working state, to avoid a malloc in gicv3_update() */
82
bool seenbetter;
83
};
84
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/intc/arm_gicv3.c
87
+++ b/hw/intc/arm_gicv3.c
88
@@ -XXX,XX +XXX,XX @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
89
cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
90
}
91
92
+ if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
93
+ (cs->hpplpi.prio != 0xff)) {
94
+ if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
95
+ cs->hppi.irq = cs->hpplpi.irq;
96
+ cs->hppi.prio = cs->hpplpi.prio;
97
+ cs->hppi.grp = cs->hpplpi.grp;
98
+ seenbetter = true;
99
+ }
100
+ }
101
+
102
/* If the best interrupt we just found would preempt whatever
103
* was the previous best interrupt before this update, then
104
* we know it's definitely the best one now.
105
@@ -XXX,XX +XXX,XX @@ static void gicv3_set_irq(void *opaque, int irq, int level)
106
107
static void arm_gicv3_post_load(GICv3State *s)
108
{
109
+ int i;
110
/* Recalculate our cached idea of the current highest priority
111
* pending interrupt, but don't set IRQ or FIQ lines.
112
*/
113
+ for (i = 0; i < s->num_cpu; i++) {
114
+ gicv3_redist_update_lpi(&s->cpu[i]);
115
+ }
116
gicv3_full_update_noirqset(s);
117
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */
118
gicv3_cache_all_target_cpustates(s);
119
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
120
index XXXXXXX..XXXXXXX 100644
121
--- a/hw/intc/arm_gicv3_common.c
122
+++ b/hw/intc/arm_gicv3_common.c
123
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_reset(DeviceState *dev)
124
memset(cs->gicr_ipriorityr, 0, sizeof(cs->gicr_ipriorityr));
125
126
cs->hppi.prio = 0xff;
127
+ cs->hpplpi.prio = 0xff;
128
129
/* State in the CPU interface must *not* be reset here, because it
130
* is part of the CPU's reset domain, not the GIC device's.
131
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/intc/arm_gicv3_cpuif.c
134
+++ b/hw/intc/arm_gicv3_cpuif.c
135
@@ -XXX,XX +XXX,XX @@ static void icc_activate_irq(GICv3CPUState *cs, int irq)
136
cs->gicr_iactiver0 = deposit32(cs->gicr_iactiver0, irq, 1, 1);
137
cs->gicr_ipendr0 = deposit32(cs->gicr_ipendr0, irq, 1, 0);
138
gicv3_redist_update(cs);
139
- } else {
140
+ } else if (irq < GICV3_LPI_INTID_START) {
141
gicv3_gicd_active_set(cs->gic, irq);
142
gicv3_gicd_pending_clear(cs->gic, irq);
143
gicv3_update(cs->gic, irq, 1);
144
+ } else {
145
+ gicv3_redist_lpi_pending(cs, irq, 0);
146
}
17
}
147
}
18
}
148
19
149
@@ -XXX,XX +XXX,XX @@ static void icc_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
20
+/*
150
trace_gicv3_icc_eoir_write(is_eoir0 ? 0 : 1,
21
+ * This is called both on hardware (device) reset and software reset.
151
gicv3_redist_affid(cs), value);
22
+ */
152
23
static void imx_epit_reset(DeviceState *dev)
153
- if (irq >= cs->gic->num_irq) {
24
{
154
+ if ((irq >= cs->gic->num_irq) &&
25
IMXEPITState *s = IMX_EPIT(dev);
155
+ !(cs->gic->lpi_enable && (irq >= GICV3_LPI_INTID_START))) {
26
156
/* This handles two cases:
27
- /*
157
* 1. If software writes the ID of a spurious interrupt [ie 1020-1023]
28
- * Soft reset doesn't touch some bits; hard reset clears them
158
* to the GICC_EOIR, the GIC ignores that write.
29
- */
159
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
30
+ /* Soft reset doesn't touch some bits; hard reset clears them */
160
index XXXXXXX..XXXXXXX 100644
31
s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
161
--- a/hw/intc/arm_gicv3_its.c
32
s->sr = 0;
162
+++ b/hw/intc/arm_gicv3_its.c
33
s->lr = EPIT_TIMER_MAX;
163
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
34
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
164
uint64_t cte = 0;
35
ptimer_transaction_begin(s->timer_cmp);
165
bool cte_valid = false;
36
ptimer_transaction_begin(s->timer_reload);
166
bool result = false;
37
167
+ uint64_t rdbase;
38
+ /* Update the frequency. Has been done already in case of a reset. */
168
39
if (!(s->cr & CR_SWR)) {
169
if (cmd == NONE) {
40
imx_epit_set_freq(s);
170
devid = offset;
41
}
171
@@ -XXX,XX +XXX,XX @@ static bool process_its_cmd(GICv3ITSState *s, uint64_t value, uint32_t offset,
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
172
* Current implementation only supports rdbase == procnum
43
break;
173
* Hence rdbase physical address is ignored
44
174
*/
45
case 1: /* SR - ACK*/
175
+ rdbase = (cte & GITS_CTE_RDBASE_PROCNUM_MASK) >> 1U;
46
- /* writing 1 to OCIF clear the OCIF bit */
176
+
47
+ /* writing 1 to OCIF clears the OCIF bit */
177
+ if (rdbase > s->gicv3->num_cpu) {
48
if (value & 0x01) {
178
+ return result;
49
s->sr = 0;
179
+ }
50
imx_epit_update_int(s);
180
+
51
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
181
+ if ((cmd == CLEAR) || (cmd == DISCARD)) {
52
0x00001000);
182
+ gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 0);
53
sysbus_init_mmio(sbd, &s->iomem);
183
+ } else {
54
184
+ gicv3_redist_process_lpi(&s->gicv3->cpu[rdbase], pIntid, 1);
55
+ /*
185
+ }
56
+ * The reload timer keeps running when the peripheral is enabled. It is a
186
+
57
+ * kind of wall clock that does not generate any interrupts. The callback
187
if (cmd == DISCARD) {
58
+ * needs to be provided, but it does nothing as the ptimer already supports
188
IteEntry ite = {};
59
+ * all necessary reloading functionality.
189
/* remove mapping from interrupt translation table */
60
+ */
190
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
61
s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
191
MemTxResult res = MEMTX_OK;
62
192
bool result = true;
63
+ /*
193
uint8_t cmd;
64
+ * The compare timer is running only when the peripheral configuration is
194
+ int i;
65
+ * in a state that will generate compare interrupts.
195
66
+ */
196
if (!(s->ctlr & ITS_CTLR_ENABLED)) {
67
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
197
return;
198
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
199
break;
200
case GITS_CMD_INV:
201
case GITS_CMD_INVALL:
202
+ /*
203
+ * Current implementation doesn't cache any ITS tables,
204
+ * but the calculated lpi priority information. We only
205
+ * need to trigger lpi priority re-calculation to be in
206
+ * sync with LPI config table or pending table changes.
207
+ */
208
+ for (i = 0; i < s->gicv3->num_cpu; i++) {
209
+ gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
210
+ }
211
break;
212
default:
213
break;
214
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/intc/arm_gicv3_redist.c
217
+++ b/hw/intc/arm_gicv3_redist.c
218
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
219
if (cs->gicr_typer & GICR_TYPER_PLPIS) {
220
if (value & GICR_CTLR_ENABLE_LPIS) {
221
cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
222
+ /* Check for any pending interr in pending table */
223
+ gicv3_redist_update_lpi(cs);
224
+ gicv3_redist_update(cs);
225
} else {
226
cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
227
}
228
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
229
return r;
230
}
68
}
231
69
232
+static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
233
+{
234
+ AddressSpace *as = &cs->gic->dma_as;
235
+ uint64_t lpict_baddr;
236
+ uint8_t lpite;
237
+ uint8_t prio;
238
+
239
+ lpict_baddr = cs->gicr_propbaser & R_GICR_PROPBASER_PHYADDR_MASK;
240
+
241
+ address_space_read(as, lpict_baddr + ((irq - GICV3_LPI_INTID_START) *
242
+ sizeof(lpite)), MEMTXATTRS_UNSPECIFIED, &lpite,
243
+ sizeof(lpite));
244
+
245
+ if (!(lpite & LPI_CTE_ENABLED)) {
246
+ return;
247
+ }
248
+
249
+ if (cs->gic->gicd_ctlr & GICD_CTLR_DS) {
250
+ prio = lpite & LPI_PRIORITY_MASK;
251
+ } else {
252
+ prio = ((lpite & LPI_PRIORITY_MASK) >> 1) | 0x80;
253
+ }
254
+
255
+ if ((prio < cs->hpplpi.prio) ||
256
+ ((prio == cs->hpplpi.prio) && (irq <= cs->hpplpi.irq))) {
257
+ cs->hpplpi.irq = irq;
258
+ cs->hpplpi.prio = prio;
259
+ /* LPIs are always non-secure Grp1 interrupts */
260
+ cs->hpplpi.grp = GICV3_G1NS;
261
+ }
262
+}
263
+
264
+void gicv3_redist_update_lpi(GICv3CPUState *cs)
265
+{
266
+ /*
267
+ * This function scans the LPI pending table and for each pending
268
+ * LPI, reads the corresponding entry from LPI configuration table
269
+ * to extract the priority info and determine if the current LPI
270
+ * priority is lower than the last computed high priority lpi interrupt.
271
+ * If yes, replace current LPI as the new high priority lpi interrupt.
272
+ */
273
+ AddressSpace *as = &cs->gic->dma_as;
274
+ uint64_t lpipt_baddr;
275
+ uint32_t pendt_size = 0;
276
+ uint8_t pend;
277
+ int i, bit;
278
+ uint64_t idbits;
279
+
280
+ idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
281
+ GICD_TYPER_IDBITS);
282
+
283
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
284
+ !cs->gicr_pendbaser) {
285
+ return;
286
+ }
287
+
288
+ cs->hpplpi.prio = 0xff;
289
+
290
+ lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
291
+
292
+ /* Determine the highest priority pending interrupt among LPIs */
293
+ pendt_size = (1ULL << (idbits + 1));
294
+
295
+ for (i = GICV3_LPI_INTID_START / 8; i < pendt_size / 8; i++) {
296
+ address_space_read(as, lpipt_baddr + i, MEMTXATTRS_UNSPECIFIED, &pend,
297
+ sizeof(pend));
298
+
299
+ while (pend) {
300
+ bit = ctz32(pend);
301
+ gicv3_redist_check_lpi_priority(cs, i * 8 + bit);
302
+ pend &= ~(1 << bit);
303
+ }
304
+ }
305
+}
306
+
307
+void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
308
+{
309
+ /*
310
+ * This function updates the pending bit in lpi pending table for
311
+ * the irq being activated or deactivated.
312
+ */
313
+ AddressSpace *as = &cs->gic->dma_as;
314
+ uint64_t lpipt_baddr;
315
+ bool ispend = false;
316
+ uint8_t pend;
317
+
318
+ /*
319
+ * get the bit value corresponding to this irq in the
320
+ * lpi pending table
321
+ */
322
+ lpipt_baddr = cs->gicr_pendbaser & R_GICR_PENDBASER_PHYADDR_MASK;
323
+
324
+ address_space_read(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
325
+ MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
326
+
327
+ ispend = extract32(pend, irq % 8, 1);
328
+
329
+ /* no change in the value of pending bit, return */
330
+ if (ispend == level) {
331
+ return;
332
+ }
333
+ pend = deposit32(pend, irq % 8, 1, level ? 1 : 0);
334
+
335
+ address_space_write(as, lpipt_baddr + ((irq / 8) * sizeof(pend)),
336
+ MEMTXATTRS_UNSPECIFIED, &pend, sizeof(pend));
337
+
338
+ /*
339
+ * check if this LPI is better than the current hpplpi, if yes
340
+ * just set hpplpi.prio and .irq without doing a full rescan
341
+ */
342
+ if (level) {
343
+ gicv3_redist_check_lpi_priority(cs, irq);
344
+ } else {
345
+ if (irq == cs->hpplpi.irq) {
346
+ gicv3_redist_update_lpi(cs);
347
+ }
348
+ }
349
+}
350
+
351
+void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
352
+{
353
+ uint64_t idbits;
354
+
355
+ idbits = MIN(FIELD_EX64(cs->gicr_propbaser, GICR_PROPBASER, IDBITS),
356
+ GICD_TYPER_IDBITS);
357
+
358
+ if (!(cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) || !cs->gicr_propbaser ||
359
+ !cs->gicr_pendbaser || (irq > (1ULL << (idbits + 1)) - 1) ||
360
+ irq < GICV3_LPI_INTID_START) {
361
+ return;
362
+ }
363
+
364
+ /* set/clear the pending bit for this irq */
365
+ gicv3_redist_lpi_pending(cs, irq, level);
366
+
367
+ gicv3_redist_update(cs);
368
+}
369
+
370
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)
371
{
372
/* Update redistributor state for a change in an external PPI input line */
373
--
70
--
374
2.20.1
71
2.25.1
375
376
diff view generated by jsdifflib
New patch
1
From: Axel Heider <axel.heider@hensoldt.net>
1
2
3
remove unused defines, add needed defines
4
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/hw/timer/imx_epit.h | 4 ++--
10
hw/timer/imx_epit.c | 4 ++--
11
2 files changed, 4 insertions(+), 4 deletions(-)
12
13
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/timer/imx_epit.h
16
+++ b/include/hw/timer/imx_epit.h
17
@@ -XXX,XX +XXX,XX @@
18
#define CR_OCIEN (1 << 2)
19
#define CR_RLD (1 << 3)
20
#define CR_PRESCALE_SHIFT (4)
21
-#define CR_PRESCALE_MASK (0xfff)
22
+#define CR_PRESCALE_BITS (12)
23
#define CR_SWR (1 << 16)
24
#define CR_IOVW (1 << 17)
25
#define CR_DBGEN (1 << 18)
26
@@ -XXX,XX +XXX,XX @@
27
#define CR_DOZEN (1 << 20)
28
#define CR_STOPEN (1 << 21)
29
#define CR_CLKSRC_SHIFT (24)
30
-#define CR_CLKSRC_MASK (0x3 << CR_CLKSRC_SHIFT)
31
+#define CR_CLKSRC_BITS (2)
32
33
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
34
35
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/timer/imx_epit.c
38
+++ b/hw/timer/imx_epit.c
39
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
40
uint32_t clksrc;
41
uint32_t prescaler;
42
43
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
44
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
45
+ clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
46
+ prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
47
48
s->freq = imx_ccm_get_clock_frequency(s->ccm,
49
imx_epit_clocks[clksrc]) / prescaler;
50
--
51
2.25.1
diff view generated by jsdifflib
New patch
1
From: Axel Heider <axel.heider@hensoldt.net>
1
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
---
6
include/hw/timer/imx_epit.h | 2 ++
7
hw/timer/imx_epit.c | 12 ++++++------
8
2 files changed, 8 insertions(+), 6 deletions(-)
9
10
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
11
index XXXXXXX..XXXXXXX 100644
12
--- a/include/hw/timer/imx_epit.h
13
+++ b/include/hw/timer/imx_epit.h
14
@@ -XXX,XX +XXX,XX @@
15
#define CR_CLKSRC_SHIFT (24)
16
#define CR_CLKSRC_BITS (2)
17
18
+#define SR_OCIF (1 << 0)
19
+
20
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
21
22
#define TYPE_IMX_EPIT "imx.epit"
23
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/timer/imx_epit.c
26
+++ b/hw/timer/imx_epit.c
27
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx_epit_clocks[] = {
28
*/
29
static void imx_epit_update_int(IMXEPITState *s)
30
{
31
- if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
32
+ if ((s->sr & SR_OCIF) && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
33
qemu_irq_raise(s->irq);
34
} else {
35
qemu_irq_lower(s->irq);
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
37
break;
38
39
case 1: /* SR - ACK*/
40
- /* writing 1 to OCIF clears the OCIF bit */
41
- if (value & 0x01) {
42
- s->sr = 0;
43
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
44
+ if (value & SR_OCIF) {
45
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
46
imx_epit_update_int(s);
47
}
48
break;
49
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
50
IMXEPITState *s = IMX_EPIT(opaque);
51
52
DPRINTF("sr was %d\n", s->sr);
53
-
54
- s->sr = 1;
55
+ /* Set interrupt status bit SR.OCIF and update the interrupt state */
56
+ s->sr |= SR_OCIF;
57
imx_epit_update_int(s);
58
}
59
60
--
61
2.25.1
diff view generated by jsdifflib
New patch
1
From: Axel Heider <axel.heider@hensoldt.net>
1
2
3
The interrupt state can change due to:
4
- reset clears both SR.OCIF and CR.OCIE
5
- write to CR.EN or CR.OCIE
6
7
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/timer/imx_epit.c | 16 ++++++++++++----
12
1 file changed, 12 insertions(+), 4 deletions(-)
13
14
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/timer/imx_epit.c
17
+++ b/hw/timer/imx_epit.c
18
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
19
if (s->cr & CR_SWR) {
20
/* handle the reset */
21
imx_epit_reset(DEVICE(s));
22
- /*
23
- * TODO: could we 'break' here? following operations appear
24
- * to duplicate the work imx_epit_reset() already did.
25
- */
26
}
27
28
+ /*
29
+ * The interrupt state can change due to:
30
+ * - reset clears both SR.OCIF and CR.OCIE
31
+ * - write to CR.EN or CR.OCIE
32
+ */
33
+ imx_epit_update_int(s);
34
+
35
+ /*
36
+ * TODO: could we 'break' here for reset? following operations appear
37
+ * to duplicate the work imx_epit_reset() already did.
38
+ */
39
+
40
ptimer_transaction_begin(s->timer_cmp);
41
ptimer_transaction_begin(s->timer_reload);
42
43
--
44
2.25.1
diff view generated by jsdifflib
New patch
1
From: Axel Heider <axel.heider@hensoldt.net>
1
2
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
7
hw/timer/imx_epit.c | 20 ++++++++++++++------
8
1 file changed, 14 insertions(+), 6 deletions(-)
9
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/timer/imx_epit.c
13
+++ b/hw/timer/imx_epit.c
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
15
/*
16
* This is called both on hardware (device) reset and software reset.
17
*/
18
-static void imx_epit_reset(DeviceState *dev)
19
+static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
20
{
21
- IMXEPITState *s = IMX_EPIT(dev);
22
-
23
/* Soft reset doesn't touch some bits; hard reset clears them */
24
- s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
25
+ if (is_hard_reset) {
26
+ s->cr = 0;
27
+ } else {
28
+ s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
29
+ }
30
s->sr = 0;
31
s->lr = EPIT_TIMER_MAX;
32
s->cmp = 0;
33
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
34
s->cr = value & 0x03ffffff;
35
if (s->cr & CR_SWR) {
36
/* handle the reset */
37
- imx_epit_reset(DEVICE(s));
38
+ imx_epit_reset(s, false);
39
}
40
41
/*
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
43
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
44
}
45
46
+static void imx_epit_dev_reset(DeviceState *dev)
47
+{
48
+ IMXEPITState *s = IMX_EPIT(dev);
49
+ imx_epit_reset(s, true);
50
+}
51
+
52
static void imx_epit_class_init(ObjectClass *klass, void *data)
53
{
54
DeviceClass *dc = DEVICE_CLASS(klass);
55
56
dc->realize = imx_epit_realize;
57
- dc->reset = imx_epit_reset;
58
+ dc->reset = imx_epit_dev_reset;
59
dc->vmsd = &vmstate_imx_timer_epit;
60
dc->desc = "i.MX periodic timer";
61
}
62
--
63
2.25.1
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Added functionality to trigger ITS command queue processing on
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
write to CWRITE register and process each command queue entry to
5
identify the command type and handle commands like MAPD,MAPC,SYNC.
6
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
11
Message-id: 20210910143951.92242-4-shashi.mallela@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
hw/intc/gicv3_internal.h | 40 +++++
7
hw/timer/imx_epit.c | 215 ++++++++++++++++++++++++--------------------
15
hw/intc/arm_gicv3_its.c | 319 +++++++++++++++++++++++++++++++++++++++
8
1 file changed, 117 insertions(+), 98 deletions(-)
16
2 files changed, 359 insertions(+)
17
9
18
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
19
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/gicv3_internal.h
12
--- a/hw/timer/imx_epit.c
21
+++ b/hw/intc/gicv3_internal.h
13
+++ b/hw/timer/imx_epit.c
22
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
23
#define L1TABLE_ENTRY_SIZE 8
15
}
24
25
#define GITS_CMDQ_ENTRY_SIZE 32
26
+#define NUM_BYTES_IN_DW 8
27
+
28
+#define CMD_MASK 0xff
29
+
30
+/* ITS Commands */
31
+#define GITS_CMD_CLEAR 0x04
32
+#define GITS_CMD_DISCARD 0x0F
33
+#define GITS_CMD_INT 0x03
34
+#define GITS_CMD_MAPC 0x09
35
+#define GITS_CMD_MAPD 0x08
36
+#define GITS_CMD_MAPI 0x0B
37
+#define GITS_CMD_MAPTI 0x0A
38
+#define GITS_CMD_INV 0x0C
39
+#define GITS_CMD_INVALL 0x0D
40
+#define GITS_CMD_SYNC 0x05
41
+
42
+/* MAPC command fields */
43
+#define ICID_LENGTH 16
44
+#define ICID_MASK ((1U << ICID_LENGTH) - 1)
45
+FIELD(MAPC, RDBASE, 16, 32)
46
+
47
+#define RDBASE_PROCNUM_LENGTH 16
48
+#define RDBASE_PROCNUM_MASK ((1ULL << RDBASE_PROCNUM_LENGTH) - 1)
49
+
50
+/* MAPD command fields */
51
+#define ITTADDR_LENGTH 44
52
+#define ITTADDR_SHIFT 8
53
+#define ITTADDR_MASK MAKE_64BIT_MASK(ITTADDR_SHIFT, ITTADDR_LENGTH)
54
+#define SIZE_MASK 0x1f
55
+
56
+#define DEVID_SHIFT 32
57
+#define DEVID_MASK MAKE_64BIT_MASK(32, 32)
58
+
59
+#define VALID_SHIFT 63
60
+#define CMD_FIELD_VALID_MASK (1ULL << VALID_SHIFT)
61
+#define L2_TABLE_VALID_MASK CMD_FIELD_VALID_MASK
62
+#define TABLE_ENTRY_VALID_MASK (1ULL << 0)
63
64
/**
65
* Default features advertised by this version of ITS
66
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
67
* Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits
68
*/
69
#define GITS_DTE_SIZE (0x8ULL)
70
+#define GITS_DTE_ITTADDR_SHIFT 6
71
+#define GITS_DTE_ITTADDR_MASK MAKE_64BIT_MASK(GITS_DTE_ITTADDR_SHIFT, \
72
+ ITTADDR_LENGTH)
73
74
/*
75
* 8 bytes Collection Table Entry size
76
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/intc/arm_gicv3_its.c
79
+++ b/hw/intc/arm_gicv3_its.c
80
@@ -XXX,XX +XXX,XX @@ static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
81
return result;
82
}
16
}
83
17
84
+static bool update_cte(GICv3ITSState *s, uint16_t icid, bool valid,
18
+static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
85
+ uint64_t rdbase)
19
+{
86
+{
20
+ uint32_t oldcr = s->cr;
87
+ AddressSpace *as = &s->gicv3->dma_as;
21
+
88
+ uint64_t value;
22
+ s->cr = value & 0x03ffffff;
89
+ uint64_t l2t_addr;
23
+
90
+ bool valid_l2t;
24
+ if (s->cr & CR_SWR) {
91
+ uint32_t l2t_id;
25
+ /* handle the reset */
92
+ uint32_t max_l2_entries;
26
+ imx_epit_reset(s, false);
93
+ uint64_t cte = 0;
94
+ MemTxResult res = MEMTX_OK;
95
+
96
+ if (!s->ct.valid) {
97
+ return true;
98
+ }
99
+
100
+ if (valid) {
101
+ /* add mapping entry to collection table */
102
+ cte = (valid & TABLE_ENTRY_VALID_MASK) | (rdbase << 1ULL);
103
+ }
27
+ }
104
+
28
+
105
+ /*
29
+ /*
106
+ * The specification defines the format of level 1 entries of a
30
+ * The interrupt state can change due to:
107
+ * 2-level table, but the format of level 2 entries and the format
31
+ * - reset clears both SR.OCIF and CR.OCIE
108
+ * of flat-mapped tables is IMPDEF.
32
+ * - write to CR.EN or CR.OCIE
109
+ */
33
+ */
110
+ if (s->ct.indirect) {
34
+ imx_epit_update_int(s);
111
+ l2t_id = icid / (s->ct.page_sz / L1TABLE_ENTRY_SIZE);
35
+
112
+
36
+ /*
113
+ value = address_space_ldq_le(as,
37
+ * TODO: could we 'break' here for reset? following operations appear
114
+ s->ct.base_addr +
38
+ * to duplicate the work imx_epit_reset() already did.
115
+ (l2t_id * L1TABLE_ENTRY_SIZE),
39
+ */
116
+ MEMTXATTRS_UNSPECIFIED, &res);
40
+
117
+
41
+ ptimer_transaction_begin(s->timer_cmp);
118
+ if (res != MEMTX_OK) {
42
+ ptimer_transaction_begin(s->timer_reload);
119
+ return false;
43
+
44
+ /* Update the frequency. Has been done already in case of a reset. */
45
+ if (!(s->cr & CR_SWR)) {
46
+ imx_epit_set_freq(s);
47
+ }
48
+
49
+ if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
50
+ if (s->cr & CR_ENMOD) {
51
+ if (s->cr & CR_RLD) {
52
+ ptimer_set_limit(s->timer_reload, s->lr, 1);
53
+ ptimer_set_limit(s->timer_cmp, s->lr, 1);
54
+ } else {
55
+ ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
56
+ ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
57
+ }
120
+ }
58
+ }
121
+
59
+
122
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
60
+ imx_epit_reload_compare_timer(s);
123
+
61
+ ptimer_run(s->timer_reload, 0);
124
+ if (valid_l2t) {
62
+ if (s->cr & CR_OCIEN) {
125
+ max_l2_entries = s->ct.page_sz / s->ct.entry_sz;
63
+ ptimer_run(s->timer_cmp, 0);
126
+
64
+ } else {
127
+ l2t_addr = value & ((1ULL << 51) - 1);
65
+ ptimer_stop(s->timer_cmp);
128
+
66
+ }
129
+ address_space_stq_le(as, l2t_addr +
67
+ } else if (!(s->cr & CR_EN)) {
130
+ ((icid % max_l2_entries) * GITS_CTE_SIZE),
68
+ /* stop both timers */
131
+ cte, MEMTXATTRS_UNSPECIFIED, &res);
69
+ ptimer_stop(s->timer_reload);
70
+ ptimer_stop(s->timer_cmp);
71
+ } else if (s->cr & CR_OCIEN) {
72
+ if (!(oldcr & CR_OCIEN)) {
73
+ imx_epit_reload_compare_timer(s);
74
+ ptimer_run(s->timer_cmp, 0);
132
+ }
75
+ }
133
+ } else {
76
+ } else {
134
+ /* Flat level table */
77
+ ptimer_stop(s->timer_cmp);
135
+ address_space_stq_le(as, s->ct.base_addr + (icid * GITS_CTE_SIZE),
78
+ }
136
+ cte, MEMTXATTRS_UNSPECIFIED, &res);
79
+
137
+ }
80
+ ptimer_transaction_commit(s->timer_cmp);
138
+ if (res != MEMTX_OK) {
81
+ ptimer_transaction_commit(s->timer_reload);
139
+ return false;
82
+}
140
+ } else {
83
+
141
+ return true;
84
+static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
142
+ }
85
+{
143
+}
86
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
144
+
87
+ if (value & SR_OCIF) {
145
+static bool process_mapc(GICv3ITSState *s, uint32_t offset)
88
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
146
+{
89
+ imx_epit_update_int(s);
147
+ AddressSpace *as = &s->gicv3->dma_as;
90
+ }
148
+ uint16_t icid;
91
+}
149
+ uint64_t rdbase;
92
+
150
+ bool valid;
93
+static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
151
+ MemTxResult res = MEMTX_OK;
94
+{
152
+ bool result = false;
95
+ s->lr = value;
153
+ uint64_t value;
96
+
154
+
97
+ ptimer_transaction_begin(s->timer_cmp);
155
+ offset += NUM_BYTES_IN_DW;
98
+ ptimer_transaction_begin(s->timer_reload);
156
+ offset += NUM_BYTES_IN_DW;
99
+ if (s->cr & CR_RLD) {
157
+
100
+ /* Also set the limit if the LRD bit is set */
158
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
101
+ /* If IOVW bit is set then set the timer value */
159
+ MEMTXATTRS_UNSPECIFIED, &res);
102
+ ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
160
+
103
+ ptimer_set_limit(s->timer_cmp, s->lr, 0);
161
+ if (res != MEMTX_OK) {
104
+ } else if (s->cr & CR_IOVW) {
162
+ return result;
105
+ /* If IOVW bit is set then set the timer value */
163
+ }
106
+ ptimer_set_count(s->timer_reload, s->lr);
164
+
107
+ }
165
+ icid = value & ICID_MASK;
166
+
167
+ rdbase = (value & R_MAPC_RDBASE_MASK) >> R_MAPC_RDBASE_SHIFT;
168
+ rdbase &= RDBASE_PROCNUM_MASK;
169
+
170
+ valid = (value & CMD_FIELD_VALID_MASK);
171
+
172
+ if ((icid > s->ct.maxids.max_collids) || (rdbase > s->gicv3->num_cpu)) {
173
+ qemu_log_mask(LOG_GUEST_ERROR,
174
+ "ITS MAPC: invalid collection table attributes "
175
+ "icid %d rdbase %lu\n", icid, rdbase);
176
+ /*
177
+ * in this implementation, in case of error
178
+ * we ignore this command and move onto the next
179
+ * command in the queue
180
+ */
181
+ } else {
182
+ result = update_cte(s, icid, valid, rdbase);
183
+ }
184
+
185
+ return result;
186
+}
187
+
188
+static bool update_dte(GICv3ITSState *s, uint32_t devid, bool valid,
189
+ uint8_t size, uint64_t itt_addr)
190
+{
191
+ AddressSpace *as = &s->gicv3->dma_as;
192
+ uint64_t value;
193
+ uint64_t l2t_addr;
194
+ bool valid_l2t;
195
+ uint32_t l2t_id;
196
+ uint32_t max_l2_entries;
197
+ uint64_t dte = 0;
198
+ MemTxResult res = MEMTX_OK;
199
+
200
+ if (s->dt.valid) {
201
+ if (valid) {
202
+ /* add mapping entry to device table */
203
+ dte = (valid & TABLE_ENTRY_VALID_MASK) |
204
+ ((size & SIZE_MASK) << 1U) |
205
+ (itt_addr << GITS_DTE_ITTADDR_SHIFT);
206
+ }
207
+ } else {
208
+ return true;
209
+ }
210
+
211
+ /*
108
+ /*
212
+ * The specification defines the format of level 1 entries of a
109
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
213
+ * 2-level table, but the format of level 2 entries and the format
110
+ * the timer interrupt may not fire properly. The commit must happen
214
+ * of flat-mapped tables is IMPDEF.
111
+ * before calling imx_epit_reload_compare_timer(), which reads
112
+ * s->timer_reload internally again.
215
+ */
113
+ */
216
+ if (s->dt.indirect) {
114
+ ptimer_transaction_commit(s->timer_reload);
217
+ l2t_id = devid / (s->dt.page_sz / L1TABLE_ENTRY_SIZE);
115
+ imx_epit_reload_compare_timer(s);
218
+
116
+ ptimer_transaction_commit(s->timer_cmp);
219
+ value = address_space_ldq_le(as,
117
+}
220
+ s->dt.base_addr +
118
+
221
+ (l2t_id * L1TABLE_ENTRY_SIZE),
119
+static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
222
+ MEMTXATTRS_UNSPECIFIED, &res);
120
+{
223
+
121
+ s->cmp = value;
224
+ if (res != MEMTX_OK) {
122
+
225
+ return false;
123
+ ptimer_transaction_begin(s->timer_cmp);
226
+ }
124
+ imx_epit_reload_compare_timer(s);
227
+
125
+ ptimer_transaction_commit(s->timer_cmp);
228
+ valid_l2t = (value & L2_TABLE_VALID_MASK) != 0;
126
+}
229
+
127
+
230
+ if (valid_l2t) {
128
static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
231
+ max_l2_entries = s->dt.page_sz / s->dt.entry_sz;
129
unsigned size)
232
+
130
{
233
+ l2t_addr = value & ((1ULL << 51) - 1);
131
IMXEPITState *s = IMX_EPIT(opaque);
234
+
132
- uint64_t oldcr;
235
+ address_space_stq_le(as, l2t_addr +
133
236
+ ((devid % max_l2_entries) * GITS_DTE_SIZE),
134
DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
237
+ dte, MEMTXATTRS_UNSPECIFIED, &res);
135
(uint32_t)value);
238
+ }
136
239
+ } else {
137
switch (offset >> 2) {
240
+ /* Flat level table */
138
case 0: /* CR */
241
+ address_space_stq_le(as, s->dt.base_addr + (devid * GITS_DTE_SIZE),
139
-
242
+ dte, MEMTXATTRS_UNSPECIFIED, &res);
140
- oldcr = s->cr;
243
+ }
141
- s->cr = value & 0x03ffffff;
244
+ if (res != MEMTX_OK) {
142
- if (s->cr & CR_SWR) {
245
+ return false;
143
- /* handle the reset */
246
+ } else {
144
- imx_epit_reset(s, false);
247
+ return true;
145
- }
248
+ }
146
-
249
+}
147
- /*
250
+
148
- * The interrupt state can change due to:
251
+static bool process_mapd(GICv3ITSState *s, uint64_t value, uint32_t offset)
149
- * - reset clears both SR.OCIF and CR.OCIE
252
+{
150
- * - write to CR.EN or CR.OCIE
253
+ AddressSpace *as = &s->gicv3->dma_as;
151
- */
254
+ uint32_t devid;
152
- imx_epit_update_int(s);
255
+ uint8_t size;
153
-
256
+ uint64_t itt_addr;
154
- /*
257
+ bool valid;
155
- * TODO: could we 'break' here for reset? following operations appear
258
+ MemTxResult res = MEMTX_OK;
156
- * to duplicate the work imx_epit_reset() already did.
259
+ bool result = false;
157
- */
260
+
158
-
261
+ devid = ((value & DEVID_MASK) >> DEVID_SHIFT);
159
- ptimer_transaction_begin(s->timer_cmp);
262
+
160
- ptimer_transaction_begin(s->timer_reload);
263
+ offset += NUM_BYTES_IN_DW;
161
-
264
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
162
- /* Update the frequency. Has been done already in case of a reset. */
265
+ MEMTXATTRS_UNSPECIFIED, &res);
163
- if (!(s->cr & CR_SWR)) {
266
+
164
- imx_epit_set_freq(s);
267
+ if (res != MEMTX_OK) {
165
- }
268
+ return result;
166
-
269
+ }
167
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
270
+
168
- if (s->cr & CR_ENMOD) {
271
+ size = (value & SIZE_MASK);
169
- if (s->cr & CR_RLD) {
272
+
170
- ptimer_set_limit(s->timer_reload, s->lr, 1);
273
+ offset += NUM_BYTES_IN_DW;
171
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
274
+ value = address_space_ldq_le(as, s->cq.base_addr + offset,
172
- } else {
275
+ MEMTXATTRS_UNSPECIFIED, &res);
173
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
276
+
174
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
277
+ if (res != MEMTX_OK) {
175
- }
278
+ return result;
176
- }
279
+ }
177
-
280
+
178
- imx_epit_reload_compare_timer(s);
281
+ itt_addr = (value & ITTADDR_MASK) >> ITTADDR_SHIFT;
179
- ptimer_run(s->timer_reload, 0);
282
+
180
- if (s->cr & CR_OCIEN) {
283
+ valid = (value & CMD_FIELD_VALID_MASK);
181
- ptimer_run(s->timer_cmp, 0);
284
+
182
- } else {
285
+ if ((devid > s->dt.maxids.max_devids) ||
183
- ptimer_stop(s->timer_cmp);
286
+ (size > FIELD_EX64(s->typer, GITS_TYPER, IDBITS))) {
184
- }
287
+ qemu_log_mask(LOG_GUEST_ERROR,
185
- } else if (!(s->cr & CR_EN)) {
288
+ "ITS MAPD: invalid device table attributes "
186
- /* stop both timers */
289
+ "devid %d or size %d\n", devid, size);
187
- ptimer_stop(s->timer_reload);
290
+ /*
188
- ptimer_stop(s->timer_cmp);
291
+ * in this implementation, in case of error
189
- } else if (s->cr & CR_OCIEN) {
292
+ * we ignore this command and move onto the next
190
- if (!(oldcr & CR_OCIEN)) {
293
+ * command in the queue
191
- imx_epit_reload_compare_timer(s);
294
+ */
192
- ptimer_run(s->timer_cmp, 0);
295
+ } else {
193
- }
296
+ result = update_dte(s, devid, valid, size, itt_addr);
194
- } else {
297
+ }
195
- ptimer_stop(s->timer_cmp);
298
+
196
- }
299
+ return result;
197
-
300
+}
198
- ptimer_transaction_commit(s->timer_cmp);
301
+
199
- ptimer_transaction_commit(s->timer_reload);
302
+/*
200
+ imx_epit_write_cr(s, (uint32_t)value);
303
+ * Current implementation blocks until all
201
break;
304
+ * commands are processed
202
305
+ */
203
- case 1: /* SR - ACK*/
306
+static void process_cmdq(GICv3ITSState *s)
204
- /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
307
+{
205
- if (value & SR_OCIF) {
308
+ uint32_t wr_offset = 0;
206
- s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
309
+ uint32_t rd_offset = 0;
207
- imx_epit_update_int(s);
310
+ uint32_t cq_offset = 0;
208
- }
311
+ uint64_t data;
209
+ case 1: /* SR */
312
+ AddressSpace *as = &s->gicv3->dma_as;
210
+ imx_epit_write_sr(s, (uint32_t)value);
313
+ MemTxResult res = MEMTX_OK;
211
break;
314
+ bool result = true;
212
315
+ uint8_t cmd;
213
- case 2: /* LR - set ticks */
316
+
214
- s->lr = value;
317
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
215
-
318
+ return;
216
- ptimer_transaction_begin(s->timer_cmp);
319
+ }
217
- ptimer_transaction_begin(s->timer_reload);
320
+
218
- if (s->cr & CR_RLD) {
321
+ wr_offset = FIELD_EX64(s->cwriter, GITS_CWRITER, OFFSET);
219
- /* Also set the limit if the LRD bit is set */
322
+
220
- /* If IOVW bit is set then set the timer value */
323
+ if (wr_offset > s->cq.max_entries) {
221
- ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
324
+ qemu_log_mask(LOG_GUEST_ERROR,
222
- ptimer_set_limit(s->timer_cmp, s->lr, 0);
325
+ "%s: invalid write offset "
223
- } else if (s->cr & CR_IOVW) {
326
+ "%d\n", __func__, wr_offset);
224
- /* If IOVW bit is set then set the timer value */
327
+ return;
225
- ptimer_set_count(s->timer_reload, s->lr);
328
+ }
226
- }
329
+
227
- /*
330
+ rd_offset = FIELD_EX64(s->creadr, GITS_CREADR, OFFSET);
228
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
331
+
229
- * the timer interrupt may not fire properly. The commit must happen
332
+ if (rd_offset > s->cq.max_entries) {
230
- * before calling imx_epit_reload_compare_timer(), which reads
333
+ qemu_log_mask(LOG_GUEST_ERROR,
231
- * s->timer_reload internally again.
334
+ "%s: invalid read offset "
232
- */
335
+ "%d\n", __func__, rd_offset);
233
- ptimer_transaction_commit(s->timer_reload);
336
+ return;
234
- imx_epit_reload_compare_timer(s);
337
+ }
235
- ptimer_transaction_commit(s->timer_cmp);
338
+
236
+ case 2: /* LR */
339
+ while (wr_offset != rd_offset) {
237
+ imx_epit_write_lr(s, (uint32_t)value);
340
+ cq_offset = (rd_offset * GITS_CMDQ_ENTRY_SIZE);
238
break;
341
+ data = address_space_ldq_le(as, s->cq.base_addr + cq_offset,
239
342
+ MEMTXATTRS_UNSPECIFIED, &res);
240
case 3: /* CMP */
343
+ if (res != MEMTX_OK) {
241
- s->cmp = value;
344
+ result = false;
242
-
345
+ }
243
- ptimer_transaction_begin(s->timer_cmp);
346
+ cmd = (data & CMD_MASK);
244
- imx_epit_reload_compare_timer(s);
347
+
245
- ptimer_transaction_commit(s->timer_cmp);
348
+ switch (cmd) {
246
-
349
+ case GITS_CMD_INT:
247
+ imx_epit_write_cmp(s, (uint32_t)value);
350
+ break;
248
break;
351
+ case GITS_CMD_CLEAR:
249
352
+ break;
250
default:
353
+ case GITS_CMD_SYNC:
251
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
354
+ /*
252
HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
355
+ * Current implementation makes a blocking synchronous call
253
-
356
+ * for every command issued earlier, hence the internal state
254
break;
357
+ * is already consistent by the time SYNC command is executed.
255
}
358
+ * Hence no further processing is required for SYNC command.
256
}
359
+ */
257
+
360
+ break;
258
static void imx_epit_cmp(void *opaque)
361
+ case GITS_CMD_MAPD:
259
{
362
+ result = process_mapd(s, data, cq_offset);
260
IMXEPITState *s = IMX_EPIT(opaque);
363
+ break;
364
+ case GITS_CMD_MAPC:
365
+ result = process_mapc(s, cq_offset);
366
+ break;
367
+ case GITS_CMD_MAPTI:
368
+ break;
369
+ case GITS_CMD_MAPI:
370
+ break;
371
+ case GITS_CMD_DISCARD:
372
+ break;
373
+ case GITS_CMD_INV:
374
+ case GITS_CMD_INVALL:
375
+ break;
376
+ default:
377
+ break;
378
+ }
379
+ if (result) {
380
+ rd_offset++;
381
+ rd_offset %= s->cq.max_entries;
382
+ s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, OFFSET, rd_offset);
383
+ } else {
384
+ /*
385
+ * in this implementation, in case of dma read/write error
386
+ * we stall the command processing
387
+ */
388
+ s->creadr = FIELD_DP64(s->creadr, GITS_CREADR, STALLED, 1);
389
+ qemu_log_mask(LOG_GUEST_ERROR,
390
+ "%s: %x cmd processing failed\n", __func__, cmd);
391
+ break;
392
+ }
393
+ }
394
+}
395
+
396
/*
397
* This function extracts the ITS Device and Collection table specific
398
* parameters (like base_addr, size etc) from GITS_BASER register.
399
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
400
extract_table_params(s);
401
extract_cmdq_params(s);
402
s->creadr = 0;
403
+ process_cmdq(s);
404
}
405
break;
406
case GITS_CBASER:
407
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
408
case GITS_CWRITER:
409
s->cwriter = deposit64(s->cwriter, 0, 32,
410
(value & ~R_GITS_CWRITER_RETRY_MASK));
411
+ if (s->cwriter != s->creadr) {
412
+ process_cmdq(s);
413
+ }
414
break;
415
case GITS_CWRITER + 4:
416
s->cwriter = deposit64(s->cwriter, 32, 32, value);
417
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
418
break;
419
case GITS_CWRITER:
420
s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK;
421
+ if (s->cwriter != s->creadr) {
422
+ process_cmdq(s);
423
+ }
424
break;
425
case GITS_CREADR:
426
if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
427
--
261
--
428
2.20.1
262
2.25.1
429
430
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Included creation of ITS as part of virt platform GIC
3
The CNT register is a read-only register. There is no need to
4
initialization. This Emulated ITS model now co-exists with kvm
4
store it's value, it can be calculated on demand.
5
ITS and is enabled in absence of kvm irq kernel support in a
5
The calculated frequency is needed temporarily only.
6
platform.
7
6
8
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
7
Note that this is a migration compatibility break for all boards
8
types that use the EPIT peripheral.
9
10
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210910143951.92242-9-shashi.mallela@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
---
13
include/hw/arm/virt.h | 2 ++
14
include/hw/timer/imx_epit.h | 2 -
14
target/arm/kvm_arm.h | 4 ++--
15
hw/timer/imx_epit.c | 73 ++++++++++++++-----------------------
15
hw/arm/virt.c | 29 +++++++++++++++++++++++++++--
16
2 files changed, 28 insertions(+), 47 deletions(-)
16
3 files changed, 31 insertions(+), 4 deletions(-)
17
17
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
18
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
20
--- a/include/hw/timer/imx_epit.h
21
+++ b/include/hw/arm/virt.h
21
+++ b/include/hw/timer/imx_epit.h
22
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
22
@@ -XXX,XX +XXX,XX @@ struct IMXEPITState {
23
MachineClass parent;
23
uint32_t sr;
24
bool disallow_affinity_adjustment;
24
uint32_t lr;
25
bool no_its;
25
uint32_t cmp;
26
+ bool no_tcg_its;
26
- uint32_t cnt;
27
bool no_pmu;
27
28
bool claim_edge_triggered_timers;
28
- uint32_t freq;
29
bool smbios_old_sys_ver;
29
qemu_irq irq;
30
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
30
};
31
bool highmem;
31
32
bool highmem_ecam;
32
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
33
bool its;
34
+ bool tcg_its;
35
bool virt;
36
bool ras;
37
bool mte;
38
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
39
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/kvm_arm.h
34
--- a/hw/timer/imx_epit.c
41
+++ b/target/arm/kvm_arm.h
35
+++ b/hw/timer/imx_epit.c
42
@@ -XXX,XX +XXX,XX @@ static inline const char *its_class_name(void)
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_update_int(IMXEPITState *s)
43
/* KVM implementation requires this capability */
44
return kvm_direct_msi_enabled() ? "arm-its-kvm" : NULL;
45
} else {
46
- /* Software emulation is not implemented yet */
47
- return NULL;
48
+ /* Software emulation based model */
49
+ return "arm-gicv3-its";
50
}
37
}
51
}
38
}
52
39
53
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
40
-/*
54
index XXXXXXX..XXXXXXX 100644
41
- * Must be called from within a ptimer_transaction_begin/commit block
55
--- a/hw/arm/virt.c
42
- * for both s->timer_cmp and s->timer_reload.
56
+++ b/hw/arm/virt.c
43
- */
57
@@ -XXX,XX +XXX,XX @@ static void create_its(VirtMachineState *vms)
44
-static void imx_epit_set_freq(IMXEPITState *s)
58
const char *itsclass = its_class_name();
45
+static uint32_t imx_epit_get_freq(IMXEPITState *s)
59
DeviceState *dev;
46
{
60
47
- uint32_t clksrc;
61
+ if (!strcmp(itsclass, "arm-gicv3-its")) {
48
- uint32_t prescaler;
62
+ if (!vms->tcg_its) {
49
-
63
+ itsclass = NULL;
50
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
64
+ }
51
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
65
+ }
52
-
53
- s->freq = imx_ccm_get_clock_frequency(s->ccm,
54
- imx_epit_clocks[clksrc]) / prescaler;
55
-
56
- DPRINTF("Setting ptimer frequency to %u\n", s->freq);
57
-
58
- if (s->freq) {
59
- ptimer_set_freq(s->timer_reload, s->freq);
60
- ptimer_set_freq(s->timer_cmp, s->freq);
61
- }
62
+ uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
63
+ uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
64
+ uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, imx_epit_clocks[clksrc]);
65
+ uint32_t freq = f_in / prescaler;
66
+ DPRINTF("ptimer frequency is %u\n", freq);
67
+ return freq;
68
}
69
70
/*
71
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
72
s->sr = 0;
73
s->lr = EPIT_TIMER_MAX;
74
s->cmp = 0;
75
- s->cnt = 0;
76
ptimer_transaction_begin(s->timer_cmp);
77
ptimer_transaction_begin(s->timer_reload);
78
- /* stop both timers */
66
+
79
+
67
if (!itsclass) {
80
+ /*
68
/* Do nothing if not supported */
81
+ * The reset switches off the input clock, so even if the CR.EN is still
69
return;
82
+ * set, the timers are no longer running.
70
@@ -XXX,XX +XXX,XX @@ static void create_v2m(VirtMachineState *vms)
83
+ */
71
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
84
+ assert(imx_epit_get_freq(s) == 0);
85
ptimer_stop(s->timer_cmp);
86
ptimer_stop(s->timer_reload);
87
- /* compute new frequency */
88
- imx_epit_set_freq(s);
89
/* init both timers to EPIT_TIMER_MAX */
90
ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
91
ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
92
- if (s->freq && (s->cr & CR_EN)) {
93
- /* if the timer is still enabled, restart it */
94
- ptimer_run(s->timer_reload, 0);
95
- }
96
ptimer_transaction_commit(s->timer_cmp);
97
ptimer_transaction_commit(s->timer_reload);
72
}
98
}
73
99
74
-static void create_gic(VirtMachineState *vms)
100
-static uint32_t imx_epit_update_count(IMXEPITState *s)
75
+static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
101
-{
102
- s->cnt = ptimer_get_count(s->timer_reload);
103
-
104
- return s->cnt;
105
-}
106
-
107
static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
76
{
108
{
77
MachineState *ms = MACHINE(vms);
109
IMXEPITState *s = IMX_EPIT(opaque);
78
/* We create a standalone GIC */
110
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
79
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms)
111
break;
80
nb_redist_regions);
112
81
qdev_prop_set_uint32(vms->gic, "redist-region-count[0]", redist0_count);
113
case 4: /* CNT */
82
114
- imx_epit_update_count(s);
83
+ if (!kvm_irqchip_in_kernel()) {
115
- reg_value = s->cnt;
84
+ if (vms->tcg_its) {
116
+ reg_value = ptimer_get_count(s->timer_reload);
85
+ object_property_set_link(OBJECT(vms->gic), "sysmem",
117
break;
86
+ OBJECT(mem), &error_fatal);
118
87
+ qdev_prop_set_bit(vms->gic, "has-lpi", true);
119
default:
88
+ }
120
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
89
+ }
121
{
90
+
122
if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
91
if (nb_redist_regions == 2) {
123
/* if the compare feature is on and timers are running */
92
uint32_t redist1_capacity =
124
- uint32_t tmp = imx_epit_update_count(s);
93
vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
125
+ uint32_t tmp = ptimer_get_count(s->timer_reload);
94
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
126
uint64_t next;
95
127
if (tmp > s->cmp) {
96
virt_flash_fdt(vms, sysmem, secure_sysmem ?: sysmem);
128
/* It'll fire in this round of the timer */
97
129
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
98
- create_gic(vms);
130
99
+ create_gic(vms, sysmem);
131
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
100
132
{
101
virt_cpu_post_init(vms, sysmem);
133
+ uint32_t freq = 0;
102
134
uint32_t oldcr = s->cr;
103
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
135
104
} else {
136
s->cr = value & 0x03ffffff;
105
/* Default allows ITS instantiation */
137
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
106
vms->its = true;
138
ptimer_transaction_begin(s->timer_cmp);
107
+
139
ptimer_transaction_begin(s->timer_reload);
108
+ if (vmc->no_tcg_its) {
140
109
+ vms->tcg_its = false;
141
- /* Update the frequency. Has been done already in case of a reset. */
110
+ } else {
142
+ /*
111
+ vms->tcg_its = true;
143
+ * Update the frequency. In case of a reset the input clock was
144
+ * switched off, so this can be skipped.
145
+ */
146
if (!(s->cr & CR_SWR)) {
147
- imx_epit_set_freq(s);
148
+ freq = imx_epit_get_freq(s);
149
+ if (freq) {
150
+ ptimer_set_freq(s->timer_reload, freq);
151
+ ptimer_set_freq(s->timer_cmp, freq);
112
+ }
152
+ }
113
}
153
}
114
154
115
/* Default disallows iommu instantiation */
155
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
116
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(6, 2)
156
+ if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
117
157
if (s->cr & CR_ENMOD) {
118
static void virt_machine_6_1_options(MachineClass *mc)
158
if (s->cr & CR_RLD) {
119
{
159
ptimer_set_limit(s->timer_reload, s->lr, 1);
120
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
160
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps imx_epit_ops = {
121
+
161
122
virt_machine_6_2_options(mc);
162
static const VMStateDescription vmstate_imx_timer_epit = {
123
compat_props_add(mc->compat_props, hw_compat_6_1, hw_compat_6_1_len);
163
.name = TYPE_IMX_EPIT,
124
+
164
- .version_id = 2,
125
+ /* qemu ITS was introduced with 6.2 */
165
- .minimum_version_id = 2,
126
+ vmc->no_tcg_its = true;
166
+ .version_id = 3,
127
}
167
+ .minimum_version_id = 3,
128
DEFINE_VIRT_MACHINE(6, 1)
168
.fields = (VMStateField[]) {
129
169
VMSTATE_UINT32(cr, IMXEPITState),
170
VMSTATE_UINT32(sr, IMXEPITState),
171
VMSTATE_UINT32(lr, IMXEPITState),
172
VMSTATE_UINT32(cmp, IMXEPITState),
173
- VMSTATE_UINT32(cnt, IMXEPITState),
174
- VMSTATE_UINT32(freq, IMXEPITState),
175
VMSTATE_PTIMER(timer_reload, IMXEPITState),
176
VMSTATE_PTIMER(timer_cmp, IMXEPITState),
177
VMSTATE_END_OF_LIST()
130
--
178
--
131
2.20.1
179
2.25.1
132
133
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Currently the clock/reset check is done in uart_receive(), but we
3
- fix #1263 for CR writes
4
can move the check to uart_can_receive() which is earlier.
4
- rework compare time handling
5
- The compare timer has to run even if CR.OCIEN is not set,
6
as SR.OCIF must be updated.
7
- The compare timer fires exactly once when the
8
compare value is less than the current value, but the
9
reload values is less than the compare value.
10
- The compare timer will never fire if the reload value is
11
less than the compare value. Disable it in this case.
5
12
6
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
13
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
[PMM: fixed minor style nits]
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210901124521.30599-4-bmeng.cn@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
hw/char/cadence_uart.c | 17 ++++++++++-------
18
hw/timer/imx_epit.c | 192 ++++++++++++++++++++++++++------------------
13
1 file changed, 10 insertions(+), 7 deletions(-)
19
1 file changed, 116 insertions(+), 76 deletions(-)
14
20
15
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
21
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/char/cadence_uart.c
23
--- a/hw/timer/imx_epit.c
18
+++ b/hw/char/cadence_uart.c
24
+++ b/hw/timer/imx_epit.c
19
@@ -XXX,XX +XXX,XX @@ static void uart_parameters_setup(CadenceUARTState *s)
25
@@ -XXX,XX +XXX,XX @@
20
static int uart_can_receive(void *opaque)
26
* Originally written by Hans Jiang
21
{
27
* Updated by Peter Chubb
22
CadenceUARTState *s = opaque;
28
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
23
- int ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
29
+ * Updated by Axel Heider
24
- uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
30
*
25
+ int ret;
31
* This code is licensed under GPL version 2 or later. See
26
+ uint32_t ch_mode;
32
* the COPYING file in the top-level directory.
27
+
33
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
28
+ /* ignore characters when unclocked or in reset */
34
return reg_value;
29
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
35
}
30
+ return 0;
36
37
-/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp */
38
-static void imx_epit_reload_compare_timer(IMXEPITState *s)
39
+/*
40
+ * Must be called from a ptimer_transaction_begin/commit block for
41
+ * s->timer_cmp, but outside of a transaction block of s->timer_reload,
42
+ * so the proper counter value is read.
43
+ */
44
+static void imx_epit_update_compare_timer(IMXEPITState *s)
45
{
46
- if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
47
- /* if the compare feature is on and timers are running */
48
- uint32_t tmp = ptimer_get_count(s->timer_reload);
49
- uint64_t next;
50
- if (tmp > s->cmp) {
51
- /* It'll fire in this round of the timer */
52
- next = tmp - s->cmp;
53
- } else { /* catch it next time around */
54
- next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
55
+ uint64_t counter = 0;
56
+ bool is_oneshot = false;
57
+ /*
58
+ * The compare timer only has to run if the timer peripheral is active
59
+ * and there is an input clock, Otherwise it can be switched off.
60
+ */
61
+ bool is_active = (s->cr & CR_EN) && imx_epit_get_freq(s);
62
+ if (is_active) {
63
+ /*
64
+ * Calculate next timeout for compare timer. Reading the reload
65
+ * counter returns proper results only if pending transactions
66
+ * on it are committed here. Otherwise stale values are be read.
67
+ */
68
+ counter = ptimer_get_count(s->timer_reload);
69
+ uint64_t limit = ptimer_get_limit(s->timer_cmp);
70
+ /*
71
+ * The compare timer is a periodic timer if the limit is at least
72
+ * the compare value. Otherwise it may fire at most once in the
73
+ * current round.
74
+ */
75
+ bool is_oneshot = (limit >= s->cmp);
76
+ if (counter >= s->cmp) {
77
+ /* The compare timer fires in the current round. */
78
+ counter -= s->cmp;
79
+ } else if (!is_oneshot) {
80
+ /*
81
+ * The compare timer fires after a reload, as it is below the
82
+ * compare value already in this round. Note that the counter
83
+ * value calculated below can be above the 32-bit limit, which
84
+ * is legal here because the compare timer is an internal
85
+ * helper ptimer only.
86
+ */
87
+ counter += limit - s->cmp;
88
+ } else {
89
+ /*
90
+ * The compare timer won't fire in this round, and the limit is
91
+ * set to a value below the compare value. This practically means
92
+ * it will never fire, so it can be switched off.
93
+ */
94
+ is_active = false;
95
}
96
- ptimer_set_count(s->timer_cmp, next);
97
}
98
+
99
+ /*
100
+ * Set the compare timer and let it run, or stop it. This is agnostic
101
+ * of CR.OCIEN bit, as this bit affects interrupt generation only. The
102
+ * compare timer needs to run even if no interrupts are to be generated,
103
+ * because the SR.OCIF bit must be updated also.
104
+ * Note that the timer might already be stopped or be running with
105
+ * counter values. However, finding out when an update is needed and
106
+ * when not is not trivial. It's much easier applying the setting again,
107
+ * as this does not harm either and the overhead is negligible.
108
+ */
109
+ if (is_active) {
110
+ ptimer_set_count(s->timer_cmp, counter);
111
+ ptimer_run(s->timer_cmp, is_oneshot ? 1 : 0);
112
+ } else {
113
+ ptimer_stop(s->timer_cmp);
31
+ }
114
+ }
32
+
115
+
33
+ ret = MAX(CADENCE_UART_RX_FIFO_SIZE, CADENCE_UART_TX_FIFO_SIZE);
116
}
34
+ ch_mode = s->r[R_MR] & UART_MR_CHMODE;
117
35
118
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
36
if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
119
{
37
ret = MIN(ret, CADENCE_UART_RX_FIFO_SIZE - s->rx_count);
120
- uint32_t freq = 0;
38
@@ -XXX,XX +XXX,XX @@ static void uart_receive(void *opaque, const uint8_t *buf, int size)
121
uint32_t oldcr = s->cr;
39
CadenceUARTState *s = opaque;
122
40
uint32_t ch_mode = s->r[R_MR] & UART_MR_CHMODE;
123
s->cr = value & 0x03ffffff;
41
124
42
- /* ignore characters when unclocked or in reset */
125
if (s->cr & CR_SWR) {
43
- if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
126
- /* handle the reset */
44
- return;
127
+ /*
128
+ * Reset clears CR.SWR again. It does not touch CR.EN, but the timers
129
+ * are still stopped because the input clock is disabled.
130
+ */
131
imx_epit_reset(s, false);
132
+ } else {
133
+ uint32_t freq;
134
+ uint32_t toggled_cr_bits = oldcr ^ s->cr;
135
+ /* re-initialize the limits if CR.RLD has changed */
136
+ bool set_limit = toggled_cr_bits & CR_RLD;
137
+ /* set the counter if the timer got just enabled and CR.ENMOD is set */
138
+ bool is_switched_on = (toggled_cr_bits & s->cr) & CR_EN;
139
+ bool set_counter = is_switched_on && (s->cr & CR_ENMOD);
140
+
141
+ ptimer_transaction_begin(s->timer_cmp);
142
+ ptimer_transaction_begin(s->timer_reload);
143
+ freq = imx_epit_get_freq(s);
144
+ if (freq) {
145
+ ptimer_set_freq(s->timer_reload, freq);
146
+ ptimer_set_freq(s->timer_cmp, freq);
147
+ }
148
+
149
+ if (set_limit || set_counter) {
150
+ uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
151
+ ptimer_set_limit(s->timer_reload, limit, set_counter ? 1 : 0);
152
+ if (set_limit) {
153
+ ptimer_set_limit(s->timer_cmp, limit, 0);
154
+ }
155
+ }
156
+ /*
157
+ * If there is an input clock and the peripheral is enabled, then
158
+ * ensure the wall clock timer is ticking. Otherwise stop the timers.
159
+ * The compare timer will be updated later.
160
+ */
161
+ if (freq && (s->cr & CR_EN)) {
162
+ ptimer_run(s->timer_reload, 0);
163
+ } else {
164
+ ptimer_stop(s->timer_reload);
165
+ }
166
+ /* Commit changes to reload timer, so they can propagate. */
167
+ ptimer_transaction_commit(s->timer_reload);
168
+ /* Update compare timer based on the committed reload timer value. */
169
+ imx_epit_update_compare_timer(s);
170
+ ptimer_transaction_commit(s->timer_cmp);
171
}
172
173
/*
174
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
175
* - write to CR.EN or CR.OCIE
176
*/
177
imx_epit_update_int(s);
178
-
179
- /*
180
- * TODO: could we 'break' here for reset? following operations appear
181
- * to duplicate the work imx_epit_reset() already did.
182
- */
183
-
184
- ptimer_transaction_begin(s->timer_cmp);
185
- ptimer_transaction_begin(s->timer_reload);
186
-
187
- /*
188
- * Update the frequency. In case of a reset the input clock was
189
- * switched off, so this can be skipped.
190
- */
191
- if (!(s->cr & CR_SWR)) {
192
- freq = imx_epit_get_freq(s);
193
- if (freq) {
194
- ptimer_set_freq(s->timer_reload, freq);
195
- ptimer_set_freq(s->timer_cmp, freq);
196
- }
45
- }
197
- }
46
-
198
-
47
if (ch_mode == NORMAL_MODE || ch_mode == ECHO_MODE) {
199
- if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
48
uart_write_rx_fifo(opaque, buf, size);
200
- if (s->cr & CR_ENMOD) {
201
- if (s->cr & CR_RLD) {
202
- ptimer_set_limit(s->timer_reload, s->lr, 1);
203
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
204
- } else {
205
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
206
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
207
- }
208
- }
209
-
210
- imx_epit_reload_compare_timer(s);
211
- ptimer_run(s->timer_reload, 0);
212
- if (s->cr & CR_OCIEN) {
213
- ptimer_run(s->timer_cmp, 0);
214
- } else {
215
- ptimer_stop(s->timer_cmp);
216
- }
217
- } else if (!(s->cr & CR_EN)) {
218
- /* stop both timers */
219
- ptimer_stop(s->timer_reload);
220
- ptimer_stop(s->timer_cmp);
221
- } else if (s->cr & CR_OCIEN) {
222
- if (!(oldcr & CR_OCIEN)) {
223
- imx_epit_reload_compare_timer(s);
224
- ptimer_run(s->timer_cmp, 0);
225
- }
226
- } else {
227
- ptimer_stop(s->timer_cmp);
228
- }
229
-
230
- ptimer_transaction_commit(s->timer_cmp);
231
- ptimer_transaction_commit(s->timer_reload);
232
}
233
234
static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
235
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
236
/* If IOVW bit is set then set the timer value */
237
ptimer_set_count(s->timer_reload, s->lr);
49
}
238
}
239
- /*
240
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
241
- * the timer interrupt may not fire properly. The commit must happen
242
- * before calling imx_epit_reload_compare_timer(), which reads
243
- * s->timer_reload internally again.
244
- */
245
+ /* Commit the changes to s->timer_reload, so they can propagate. */
246
ptimer_transaction_commit(s->timer_reload);
247
- imx_epit_reload_compare_timer(s);
248
+ /* Update the compare timer based on the committed reload timer value. */
249
+ imx_epit_update_compare_timer(s);
250
ptimer_transaction_commit(s->timer_cmp);
251
}
252
253
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
254
{
255
s->cmp = value;
256
257
+ /* Update the compare timer based on the committed reload timer value. */
258
ptimer_transaction_begin(s->timer_cmp);
259
- imx_epit_reload_compare_timer(s);
260
+ imx_epit_update_compare_timer(s);
261
ptimer_transaction_commit(s->timer_cmp);
262
}
263
264
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
265
{
266
IMXEPITState *s = IMX_EPIT(opaque);
267
268
+ /* The cmp ptimer can't be running when the peripheral is disabled */
269
+ assert(s->cr & CR_EN);
270
+
271
DPRINTF("sr was %d\n", s->sr);
272
/* Set interrupt status bit SR.OCIF and update the interrupt state */
273
s->sr |= SR_OCIF;
50
--
274
--
51
2.20.1
275
2.25.1
52
53
diff view generated by jsdifflib
1
The mps2-tz boards use a data-driven structure to create the devices
1
From: Fabiano Rosas <farosas@suse.de>
2
that sit behind peripheral protection controllers. Currently the
3
functions which create these devices are passed an 'opaque' pointer
4
which is always the address within the machine struct of the device
5
to create, and some "all devices need this" information like irqs and
6
addresses.
7
2
8
If a specific device needs more information than this, it is
3
Fix these:
9
currently not possible to pass that through from the PPCInfo
10
data structure. Add support for passing an extra data parameter,
11
so that we can more flexibly handle the needs of specific
12
device types. To provide some type-safety we make this extra
13
parameter a pointer to a union (which initially has no members).
14
4
15
In particular, we would like to be able to indicate which of the
5
WARNING: Block comments use a leading /* on a separate line
16
i2c controllers are for on-board devices only and which are
6
WARNING: Block comments use * on subsequent lines
17
connected to the external 'shield' expansion port; a subsequent
7
WARNING: Block comments use a trailing */ on a separate line
18
patch will use this mechanism for that purpose.
19
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Claudio Fontana <cfontana@suse.de>
11
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
12
Message-id: 20221213190537.511-2-farosas@suse.de
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20210903151435.22379-3-peter.maydell@linaro.org
23
---
14
---
24
hw/arm/mps2-tz.c | 35 ++++++++++++++++++++++-------------
15
target/arm/helper.c | 323 +++++++++++++++++++++++++++++---------------
25
1 file changed, 22 insertions(+), 13 deletions(-)
16
1 file changed, 215 insertions(+), 108 deletions(-)
26
17
27
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/mps2-tz.c
20
--- a/target/arm/helper.c
30
+++ b/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
22
@@ -XXX,XX +XXX,XX @@ uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
32
}
23
static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
33
}
24
uint64_t v)
34
25
{
35
+/* Union describing the device-specific extra data we pass to the devfn. */
26
- /* Raw write of a coprocessor register (as needed for migration, etc).
36
+typedef union PPCExtraData {
27
+ /*
37
+} PPCExtraData;
28
+ * Raw write of a coprocessor register (as needed for migration, etc).
38
+
29
* Note that constant registers are treated as write-ignored; the
39
/* Most of the devices in the AN505 FPGA image sit behind
30
* caller should check for success by whether a readback gives the
40
* Peripheral Protection Controllers. These data structures
31
* value written.
41
* define the layout of which devices sit behind which PPCs.
32
@@ -XXX,XX +XXX,XX @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
42
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
33
34
static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
35
{
36
- /* Return true if the regdef would cause an assertion if you called
37
+ /*
38
+ * Return true if the regdef would cause an assertion if you called
39
* read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
40
* program bug for it not to have the NO_RAW flag).
41
* NB that returning false here doesn't necessarily mean that calling
42
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
43
if (ri->type & ARM_CP_NO_RAW) {
44
continue;
45
}
46
- /* Write value and confirm it reads back as written
47
+ /*
48
+ * Write value and confirm it reads back as written
49
* (to catch read-only registers and partially read-only
50
* registers where the incoming migration value doesn't match)
51
*/
52
@@ -XXX,XX +XXX,XX @@ static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
53
54
void init_cpreg_list(ARMCPU *cpu)
55
{
56
- /* Initialise the cpreg_tuples[] array based on the cp_regs hash.
57
+ /*
58
+ * Initialise the cpreg_tuples[] array based on the cp_regs hash.
59
* Note that we require cpreg_tuples[] to be sorted by key ID.
60
*/
61
GList *keys;
62
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_el3_aa32ns(CPUARMState *env,
63
return CP_ACCESS_OK;
64
}
65
66
-/* Some secure-only AArch32 registers trap to EL3 if used from
67
+/*
68
+ * Some secure-only AArch32 registers trap to EL3 if used from
69
* Secure EL1 (but are just ordinary UNDEF in other non-EL3 contexts).
70
* Note that an access from Secure EL1 can only happen if EL3 is AArch64.
71
* We assume that the .access field is set to PL1_RW.
72
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
73
return CP_ACCESS_TRAP_UNCATEGORIZED;
74
}
75
76
-/* Check for traps to performance monitor registers, which are controlled
77
+/*
78
+ * Check for traps to performance monitor registers, which are controlled
79
* by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3.
43
*/
80
*/
44
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
81
static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
45
const char *name, hwaddr size,
82
@@ -XXX,XX +XXX,XX @@ static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
46
- const int *irqs);
83
ARMCPU *cpu = env_archcpu(env);
47
+ const int *irqs,
84
48
+ const PPCExtraData *extradata);
85
if (raw_read(env, ri) != value) {
49
86
- /* Unlike real hardware the qemu TLB uses virtual addresses,
50
typedef struct PPCPortInfo {
87
+ /*
51
const char *name;
88
+ * Unlike real hardware the qemu TLB uses virtual addresses,
52
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
89
* not modified virtual addresses, so this causes a TLB flush.
53
hwaddr addr;
90
*/
54
hwaddr size;
91
tlb_flush(CPU(cpu));
55
int irqs[3]; /* currently no device needs more IRQ lines than this */
92
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
56
+ PPCExtraData extradata; /* to pass device-specific info to the devfn */
93
57
} PPCPortInfo;
94
if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
58
95
&& !extended_addresses_enabled(env)) {
59
typedef struct PPCInfo {
96
- /* For VMSA (when not using the LPAE long descriptor page table
60
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
97
+ /*
61
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
98
+ * For VMSA (when not using the LPAE long descriptor page table
62
void *opaque,
99
* format) this register includes the ASID, so do a TLB flush.
63
const char *name, hwaddr size,
100
* For PMSA it is purely a process ID and no action is needed.
64
- const int *irqs)
101
*/
65
+ const int *irqs,
102
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
66
+ const PPCExtraData *extradata)
103
}
67
{
104
68
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
105
static const ARMCPRegInfo cp_reginfo[] = {
69
* and return a pointer to its MemoryRegion.
106
- /* Define the secure and non-secure FCSE identifier CP registers
70
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
107
+ /*
71
108
+ * Define the secure and non-secure FCSE identifier CP registers
72
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
109
* separately because there is no secure bank in V8 (no _EL3). This allows
73
const char *name, hwaddr size,
110
* the secure register to be properly reset and migrated. There is also no
74
- const int *irqs)
111
* v8 EL1 version of the register so the non-secure instance stands alone.
75
+ const int *irqs, const PPCExtraData *extradata)
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
76
{
113
.access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
77
/* The irq[] array is tx, rx, combined, in that order */
114
.fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
78
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
115
.resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
79
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
116
- /* Define the secure and non-secure context identifier CP registers
80
117
+ /*
81
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
118
+ * Define the secure and non-secure context identifier CP registers
82
const char *name, hwaddr size,
119
* separately because there is no secure bank in V8 (no _EL3). This allows
83
- const int *irqs)
120
* the secure register to be properly reset and migrated. In the
84
+ const int *irqs, const PPCExtraData *extradata)
121
* non-secure case, the 32-bit register will have reset and migration
85
{
122
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
86
MPS2SCC *scc = opaque;
123
};
87
DeviceState *sccdev;
124
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
125
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
89
126
- /* NB: Some of these registers exist in v8 but with more precise
90
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
127
+ /*
91
const char *name, hwaddr size,
128
+ * NB: Some of these registers exist in v8 but with more precise
92
- const int *irqs)
129
* definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]).
93
+ const int *irqs, const PPCExtraData *extradata)
130
*/
94
{
131
/* MMU Domain access control / MPU write buffer control */
95
MPS2FPGAIO *fpgaio = opaque;
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
96
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
133
.writefn = dacr_write, .raw_writefn = raw_write,
97
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
134
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
98
135
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
99
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
136
- /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
100
const char *name, hwaddr size,
137
+ /*
101
- const int *irqs)
138
+ * ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
102
+ const int *irqs,
139
* For v6 and v5, these mappings are overly broad.
103
+ const PPCExtraData *extradata)
140
*/
104
{
141
{ .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
105
SysBusDevice *s;
142
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
106
NICInfo *nd = &nd_table[0];
143
};
107
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
144
108
145
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
109
static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
146
- /* Not all pre-v6 cores implemented this WFI, so this is slightly
110
const char *name, hwaddr size,
147
+ /*
111
- const int *irqs)
148
+ * Not all pre-v6 cores implemented this WFI, so this is slightly
112
+ const int *irqs,
149
* over-broad.
113
+ const PPCExtraData *extradata)
150
*/
114
{
151
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
115
/*
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
116
* The AN524 makes the ethernet and USB share a PPC port.
153
};
117
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
154
118
155
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
119
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
156
- /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
120
const char *name, hwaddr size,
157
+ /*
121
- const int *irqs)
158
+ * Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
122
+ const int *irqs, const PPCExtraData *extradata)
159
* is UNPREDICTABLE; we choose to NOP as most implementations do).
123
{
160
*/
124
TZMPC *mpc = opaque;
161
{ .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
125
int i = mpc - &mms->mpc[0];
162
.access = PL1_W, .type = ARM_CP_WFI },
126
@@ -XXX,XX +XXX,XX @@ static void remap_irq_fn(void *opaque, int n, int level)
163
- /* L1 cache lockdown. Not architectural in v6 and earlier but in practice
127
164
+ /*
128
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
165
+ * L1 cache lockdown. Not architectural in v6 and earlier but in practice
129
const char *name, hwaddr size,
166
* implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and
130
- const int *irqs)
167
* OMAPCP will override this space.
131
+ const int *irqs, const PPCExtraData *extradata)
168
*/
132
{
169
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
133
/* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
170
{ .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
134
PL080State *dma = opaque;
171
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
135
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
172
.resetvalue = 0 },
136
173
- /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
137
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
174
+ /*
138
const char *name, hwaddr size,
175
+ * We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
139
- const int *irqs)
176
* implementing it as RAZ means the "debug architecture version" bits
140
+ const int *irqs, const PPCExtraData *extradata)
177
* will read as a reserved value, which should cause Linux to not try
141
{
178
* to use the debug hardware.
142
/*
179
*/
143
* The AN505 has five PL022 SPI controllers.
180
{ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
144
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
181
.access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
145
182
- /* MMU TLB control. Note that the wildcarding means we cover not just
146
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
183
+ /*
147
const char *name, hwaddr size,
184
+ * MMU TLB control. Note that the wildcarding means we cover not just
148
- const int *irqs)
185
* the unified TLB ops but also the dside/iside/inner-shareable variants.
149
+ const int *irqs, const PPCExtraData *extradata)
186
*/
150
{
187
{ .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
151
ArmSbconI2CState *i2c = opaque;
188
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
152
SysBusDevice *s;
189
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
190
/* In ARMv8 most bits of CPACR_EL1 are RES0. */
154
191
if (!arm_feature(env, ARM_FEATURE_V8)) {
155
static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
192
- /* ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
156
const char *name, hwaddr size,
193
+ /*
157
- const int *irqs)
194
+ * ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
158
+ const int *irqs, const PPCExtraData *extradata)
195
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
159
{
196
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
160
PL031State *pl031 = opaque;
197
*/
161
SysBusDevice *s;
198
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
162
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
199
value |= R_CPACR_ASEDIS_MASK;
163
}
200
}
164
201
165
mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
202
- /* VFPv3 and upwards with NEON implement 32 double precision
166
- pinfo->irqs);
203
+ /*
167
+ pinfo->irqs, &pinfo->extradata);
204
+ * VFPv3 and upwards with NEON implement 32 double precision
168
portname = g_strdup_printf("port[%d]", port);
205
* registers (D0-D31).
169
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
206
*/
170
&error_fatal);
207
if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
208
@@ -XXX,XX +XXX,XX @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
209
210
static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
211
{
212
- /* Call cpacr_write() so that we reset with the correct RAO bits set
213
+ /*
214
+ * Call cpacr_write() so that we reset with the correct RAO bits set
215
* for our CPU features.
216
*/
217
cpacr_write(env, ri, 0);
218
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
219
{ .name = "MVA_prefetch",
220
.cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1,
221
.access = PL1_W, .type = ARM_CP_NOP },
222
- /* We need to break the TB after ISB to execute self-modifying code
223
+ /*
224
+ * We need to break the TB after ISB to execute self-modifying code
225
* correctly and also to take any pending interrupts immediately.
226
* So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag.
227
*/
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
229
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
230
offsetof(CPUARMState, cp15.ifar_ns) },
231
.resetvalue = 0, },
232
- /* Watchpoint Fault Address Register : should actually only be present
233
+ /*
234
+ * Watchpoint Fault Address Register : should actually only be present
235
* for 1136, 1176, 11MPCore.
236
*/
237
{ .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
238
@@ -XXX,XX +XXX,XX @@ static bool event_supported(uint16_t number)
239
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
240
bool isread)
241
{
242
- /* Performance monitor registers user accessibility is controlled
243
+ /*
244
+ * Performance monitor registers user accessibility is controlled
245
* by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
246
* trapping to EL2 or EL3 for other accesses.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
249
(MDCR_HPME | MDCR_HPMD | MDCR_HPMN | MDCR_HCCD | MDCR_HLP)
250
#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
251
252
-/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
253
+/*
254
+ * Returns true if the counter (pass 31 for PMCCNTR) should count events using
255
* the current EL, security state, and register configuration.
256
*/
257
static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
258
@@ -XXX,XX +XXX,XX @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
259
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
260
uint64_t value)
261
{
262
- /* The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
263
+ /*
264
+ * The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
265
* PMXEVCNTR. We allow [0..31] to be written to PMSELR here; in the
266
* meanwhile, we check PMSELR.SEL when PMXEVTYPER and PMXEVCNTR are
267
* accessed.
268
@@ -XXX,XX +XXX,XX @@ static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
269
env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
270
pmevcntr_op_finish(env, counter);
271
}
272
- /* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
273
+ /*
274
+ * Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
275
* PMSELR value is equal to or greater than the number of implemented
276
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
277
*/
278
@@ -XXX,XX +XXX,XX @@ static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
279
}
280
return ret;
281
} else {
282
- /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
283
- * are CONSTRAINED UNPREDICTABLE. */
284
+ /*
285
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
286
+ * are CONSTRAINED UNPREDICTABLE.
287
+ */
288
return 0;
289
}
290
}
291
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
292
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
293
uint64_t value)
294
{
295
- /* Note that even though the AArch64 view of this register has bits
296
+ /*
297
+ * Note that even though the AArch64 view of this register has bits
298
* [10:0] all RES0 we can only mask the bottom 5, to comply with the
299
* architectural requirements for bits which are RES0 only in some
300
* contexts. (ARMv8 would permit us to do no masking at all, but ARMv7
301
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
302
if (!arm_feature(env, ARM_FEATURE_EL2)) {
303
valid_mask &= ~SCR_HCE;
304
305
- /* On ARMv7, SMD (or SCD as it is called in v7) is only
306
+ /*
307
+ * On ARMv7, SMD (or SCD as it is called in v7) is only
308
* supported if EL2 exists. The bit is UNK/SBZP when
309
* EL2 is unavailable. In QEMU ARMv7, we force it to always zero
310
* when EL2 is unavailable.
311
@@ -XXX,XX +XXX,XX @@ static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
312
{
313
ARMCPU *cpu = env_archcpu(env);
314
315
- /* Acquire the CSSELR index from the bank corresponding to the CCSIDR
316
+ /*
317
+ * Acquire the CSSELR index from the bank corresponding to the CCSIDR
318
* bank
319
*/
320
uint32_t index = A32_BANKED_REG_GET(env, csselr,
321
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
322
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
323
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
324
.access = PL1_W, .type = ARM_CP_NOP },
325
- /* Performance monitors are implementation defined in v7,
326
+ /*
327
+ * Performance monitors are implementation defined in v7,
328
* but with an ARM recommended set of registers, which we
329
* follow.
330
*
331
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
332
.writefn = csselr_write, .resetvalue = 0,
333
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
334
offsetof(CPUARMState, cp15.csselr_ns) } },
335
- /* Auxiliary ID register: this actually has an IMPDEF value but for now
336
+ /*
337
+ * Auxiliary ID register: this actually has an IMPDEF value but for now
338
* just RAZ for all cores:
339
*/
340
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
341
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
342
.access = PL1_R, .type = ARM_CP_CONST,
343
.accessfn = access_aa64_tid1,
344
.resetvalue = 0 },
345
- /* Auxiliary fault status registers: these also are IMPDEF, and we
346
+ /*
347
+ * Auxiliary fault status registers: these also are IMPDEF, and we
348
* choose to RAZ/WI for all cores.
349
*/
350
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
351
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
352
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
353
.access = PL1_RW, .accessfn = access_tvm_trvm,
354
.type = ARM_CP_CONST, .resetvalue = 0 },
355
- /* MAIR can just read-as-written because we don't implement caches
356
+ /*
357
+ * MAIR can just read-as-written because we don't implement caches
358
* and so don't need to care about memory attributes.
359
*/
360
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
361
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
362
.opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
363
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]),
364
.resetvalue = 0 },
365
- /* For non-long-descriptor page tables these are PRRR and NMRR;
366
+ /*
367
+ * For non-long-descriptor page tables these are PRRR and NMRR;
368
* regardless they still act as reads-as-written for QEMU.
369
*/
370
- /* MAIR0/1 are defined separately from their 64-bit counterpart which
371
+ /*
372
+ * MAIR0/1 are defined separately from their 64-bit counterpart which
373
* allows them to assign the correct fieldoffset based on the endianness
374
* handled in the field definitions.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
377
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
378
bool isread)
379
{
380
- /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
381
+ /*
382
+ * CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
383
* Writable only at the highest implemented exception level.
384
*/
385
int el = arm_current_el(env);
386
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
387
const ARMCPRegInfo *ri,
388
bool isread)
389
{
390
- /* The AArch64 register view of the secure physical timer is
391
+ /*
392
+ * The AArch64 register view of the secure physical timer is
393
* always accessible from EL3, and configurably accessible from
394
* Secure EL1.
395
*/
396
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
397
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
398
399
if (gt->ctl & 1) {
400
- /* Timer enabled: calculate and set current ISTATUS, irq, and
401
+ /*
402
+ * Timer enabled: calculate and set current ISTATUS, irq, and
403
* reset timer to when ISTATUS next has to change
404
*/
405
uint64_t offset = timeridx == GTIMER_VIRT ?
406
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
407
/* Next transition is when we hit cval */
408
nexttick = gt->cval + offset;
409
}
410
- /* Note that the desired next expiry time might be beyond the
411
+ /*
412
+ * Note that the desired next expiry time might be beyond the
413
* signed-64-bit range of a QEMUTimer -- in this case we just
414
* set the timer for as far in the future as possible. When the
415
* timer expires we will reset the timer for any remaining period.
416
@@ -XXX,XX +XXX,XX @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
417
/* Enable toggled */
418
gt_recalc_timer(cpu, timeridx);
419
} else if ((oldval ^ value) & 2) {
420
- /* IMASK toggled: don't need to recalculate,
421
+ /*
422
+ * IMASK toggled: don't need to recalculate,
423
* just set the interrupt line based on ISTATUS
424
*/
425
int irqstate = (oldval & 4) && !(value & 2);
426
@@ -XXX,XX +XXX,XX @@ static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
427
}
428
429
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
430
- /* Note that CNTFRQ is purely reads-as-written for the benefit
431
+ /*
432
+ * Note that CNTFRQ is purely reads-as-written for the benefit
433
* of software; writing it doesn't actually change the timer frequency.
434
* Our reset value matches the fixed frequency we implement the timer at.
435
*/
436
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
437
.readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
438
.writefn = gt_virt_redir_cval_write, .raw_writefn = raw_write,
439
},
440
- /* Secure timer -- this is actually restricted to only EL3
441
+ /*
442
+ * Secure timer -- this is actually restricted to only EL3
443
* and configurably Secure-EL1 via the accessfn.
444
*/
445
{ .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64,
446
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
447
448
#else
449
450
-/* In user-mode most of the generic timer registers are inaccessible
451
+/*
452
+ * In user-mode most of the generic timer registers are inaccessible
453
* however modern kernels (4.12+) allow access to cntvct_el0
454
*/
455
456
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
457
{
458
ARMCPU *cpu = env_archcpu(env);
459
460
- /* Currently we have no support for QEMUTimer in linux-user so we
461
+ /*
462
+ * Currently we have no support for QEMUTimer in linux-user so we
463
* can't call gt_get_countervalue(env), instead we directly
464
* call the lower level functions.
465
*/
466
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
467
bool isread)
468
{
469
if (ri->opc2 & 4) {
470
- /* The ATS12NSO* operations must trap to EL3 or EL2 if executed in
471
+ /*
472
+ * The ATS12NSO* operations must trap to EL3 or EL2 if executed in
473
* Secure EL1 (which can only happen if EL3 is AArch64).
474
* They are simply UNDEF if executed from NS EL1.
475
* They function normally from EL2 or EL3.
476
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
477
}
478
}
479
} else {
480
- /* fsr is a DFSR/IFSR value for the short descriptor
481
+ /*
482
+ * fsr is a DFSR/IFSR value for the short descriptor
483
* translation table format (with WnR always clear).
484
* Convert it to a 32-bit PAR.
485
*/
486
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
487
};
488
489
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
490
- /* Reset for all these registers is handled in arm_cpu_reset(),
491
+ /*
492
+ * Reset for all these registers is handled in arm_cpu_reset(),
493
* because the PMSAv7 is also used by M-profile CPUs, which do
494
* not register cpregs but still need the state to be reset.
495
*/
496
@@ -XXX,XX +XXX,XX @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
497
}
498
499
if (arm_feature(env, ARM_FEATURE_LPAE)) {
500
- /* With LPAE the TTBCR could result in a change of ASID
501
+ /*
502
+ * With LPAE the TTBCR could result in a change of ASID
503
* via the TTBCR.A1 bit, so do a TLB flush.
504
*/
505
tlb_flush(CPU(cpu));
506
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
507
offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
508
};
509
510
-/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
511
+/*
512
+ * Note that unlike TTBCR, writing to TTBCR2 does not require flushing
513
* qemu tlbs nor adjusting cached masks.
514
*/
515
static const ARMCPRegInfo ttbcr2_reginfo = {
516
@@ -XXX,XX +XXX,XX @@ static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
517
static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
518
uint64_t value)
519
{
520
- /* On OMAP there are registers indicating the max/min index of dcache lines
521
+ /*
522
+ * On OMAP there are registers indicating the max/min index of dcache lines
523
* containing a dirty line; cache flush operations have to reset these.
524
*/
525
env->cp15.c15_i_max = 0x000;
526
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
527
.crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
528
.type = ARM_CP_NO_RAW,
529
.readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
530
- /* TODO: Peripheral port remap register:
531
+ /*
532
+ * TODO: Peripheral port remap register:
533
* On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
534
* base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
535
* when MMU is off.
536
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
537
.cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
538
.fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
539
.resetvalue = 0, },
540
- /* XScale specific cache-lockdown: since we have no cache we NOP these
541
+ /*
542
+ * XScale specific cache-lockdown: since we have no cache we NOP these
543
* and hope the guest does not really rely on cache behaviour.
544
*/
545
{ .name = "XSCALE_LOCK_ICACHE_LINE",
546
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
547
};
548
549
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
550
- /* RAZ/WI the whole crn=15 space, when we don't have a more specific
551
+ /*
552
+ * RAZ/WI the whole crn=15 space, when we don't have a more specific
553
* implementation of this implementation-defined space.
554
* Ideally this should eventually disappear in favour of actually
555
* implementing the correct behaviour for all cores.
556
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
557
};
558
559
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
560
- /* The cache test-and-clean instructions always return (1 << 30)
561
+ /*
562
+ * The cache test-and-clean instructions always return (1 << 30)
563
* to indicate that there are no dirty cache lines.
564
*/
565
{ .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
566
@@ -XXX,XX +XXX,XX @@ static uint64_t mpidr_read_val(CPUARMState *env)
567
568
if (arm_feature(env, ARM_FEATURE_V7MP)) {
569
mpidr |= (1U << 31);
570
- /* Cores which are uniprocessor (non-coherent)
571
+ /*
572
+ * Cores which are uniprocessor (non-coherent)
573
* but still implement the MP extensions set
574
* bit 30. (For instance, Cortex-R5).
575
*/
576
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tocu(CPUARMState *env, const ARMCPRegInfo *ri,
577
return do_cacheop_pou_access(env, HCR_TOCU | HCR_TPU);
578
}
579
580
-/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
581
+/*
582
+ * See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
583
* Page D4-1736 (DDI0487A.b)
584
*/
585
586
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
587
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
588
uint64_t value)
589
{
590
- /* Invalidate by VA, EL2
591
+ /*
592
+ * Invalidate by VA, EL2
593
* Currently handles both VAE2 and VALE2, since we don't support
594
* flush-last-level-only.
595
*/
596
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
597
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
598
uint64_t value)
599
{
600
- /* Invalidate by VA, EL3
601
+ /*
602
+ * Invalidate by VA, EL3
603
* Currently handles both VAE3 and VALE3, since we don't support
604
* flush-last-level-only.
605
*/
606
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
607
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
608
uint64_t value)
609
{
610
- /* Invalidate by VA, EL1&0 (AArch64 version).
611
+ /*
612
+ * Invalidate by VA, EL1&0 (AArch64 version).
613
* Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
614
* since we don't support flush-for-specific-ASID-only or
615
* flush-last-level-only.
616
@@ -XXX,XX +XXX,XX @@ static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
617
bool isread)
618
{
619
if (!(env->pstate & PSTATE_SP)) {
620
- /* Access to SP_EL0 is undefined if it's being used as
621
+ /*
622
+ * Access to SP_EL0 is undefined if it's being used as
623
* the stack pointer.
624
*/
625
return CP_ACCESS_TRAP_UNCATEGORIZED;
626
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
627
}
628
629
if (raw_read(env, ri) == value) {
630
- /* Skip the TLB flush if nothing actually changed; Linux likes
631
+ /*
632
+ * Skip the TLB flush if nothing actually changed; Linux likes
633
* to do a lot of pointless SCTLR writes.
634
*/
635
return;
636
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
637
}
638
639
static const ARMCPRegInfo v8_cp_reginfo[] = {
640
- /* Minimal set of EL0-visible registers. This will need to be expanded
641
+ /*
642
+ * Minimal set of EL0-visible registers. This will need to be expanded
643
* significantly for system emulation of AArch64 CPUs.
644
*/
645
{ .name = "NZCV", .state = ARM_CP_STATE_AA64,
646
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
647
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
648
.access = PL1_RW,
649
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
650
- /* We rely on the access checks not allowing the guest to write to the
651
+ /*
652
+ * We rely on the access checks not allowing the guest to write to the
653
* state field when SPSel indicates that it's being used as the stack
654
* pointer.
655
*/
656
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
657
if (arm_feature(env, ARM_FEATURE_EL3)) {
658
valid_mask &= ~HCR_HCD;
659
} else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
660
- /* Architecturally HCR.TSC is RES0 if EL3 is not implemented.
661
+ /*
662
+ * Architecturally HCR.TSC is RES0 if EL3 is not implemented.
663
* However, if we're using the SMC PSCI conduit then QEMU is
664
* effectively acting like EL3 firmware and so the guest at
665
* EL2 should retain the ability to prevent EL1 from being
666
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
667
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
668
.writefn = tlbi_aa64_vae2is_write },
669
#ifndef CONFIG_USER_ONLY
670
- /* Unlike the other EL2-related AT operations, these must
671
+ /*
672
+ * Unlike the other EL2-related AT operations, these must
673
* UNDEF from EL3 if EL2 is not implemented, which is why we
674
* define them here rather than with the rest of the AT ops.
675
*/
676
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
677
.access = PL2_W, .accessfn = at_s1e2_access,
678
.type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
679
.writefn = ats_write64 },
680
- /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
681
+ /*
682
+ * The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
683
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
684
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
685
* to behave as if SCR.NS was 1.
686
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
687
.writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
688
{ .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
689
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
690
- /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
691
+ /*
692
+ * ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
693
* reset values as IMPDEF. We choose to reset to 3 to comply with
694
* both ARMv7 and ARMv8.
695
*/
696
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
697
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
698
bool isread)
699
{
700
- /* The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
701
+ /*
702
+ * The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
703
* At Secure EL1 it traps to EL3 or EL2.
704
*/
705
if (arm_current_el(env) == 3) {
706
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
707
}
708
}
709
710
-/* We don't know until after realize whether there's a GICv3
711
+/*
712
+ * We don't know until after realize whether there's a GICv3
713
* attached, and that is what registers the gicv3 sysregs.
714
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
715
* at runtime.
716
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
717
}
718
#endif
719
720
-/* Shared logic between LORID and the rest of the LOR* registers.
721
+/*
722
+ * Shared logic between LORID and the rest of the LOR* registers.
723
* Secure state exclusion has already been dealt with.
724
*/
725
static CPAccessResult access_lor_ns(CPUARMState *env,
726
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
727
728
define_arm_cp_regs(cpu, cp_reginfo);
729
if (!arm_feature(env, ARM_FEATURE_V8)) {
730
- /* Must go early as it is full of wildcards that may be
731
+ /*
732
+ * Must go early as it is full of wildcards that may be
733
* overridden by later definitions.
734
*/
735
define_arm_cp_regs(cpu, not_v8_cp_reginfo);
736
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
737
.access = PL1_R, .type = ARM_CP_CONST,
738
.accessfn = access_aa32_tid3,
739
.resetvalue = cpu->isar.id_pfr0 },
740
- /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know
741
+ /*
742
+ * ID_PFR1 is not a plain ARM_CP_CONST because we don't know
743
* the value of the GIC field until after we define these regs.
744
*/
745
{ .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
746
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
747
748
define_arm_cp_regs(cpu, el3_regs);
749
}
750
- /* The behaviour of NSACR is sufficiently various that we don't
751
+ /*
752
+ * The behaviour of NSACR is sufficiently various that we don't
753
* try to describe it in a single reginfo:
754
* if EL3 is 64 bit, then trap to EL3 from S EL1,
755
* reads as constant 0xc00 from NS EL1 and NS EL2
756
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
757
if (cpu_isar_feature(aa32_jazelle, cpu)) {
758
define_arm_cp_regs(cpu, jazelle_regs);
759
}
760
- /* Slightly awkwardly, the OMAP and StrongARM cores need all of
761
+ /*
762
+ * Slightly awkwardly, the OMAP and StrongARM cores need all of
763
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
764
* be read-only (ie write causes UNDEF exception).
765
*/
766
{
767
ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
768
- /* Pre-v8 MIDR space.
769
+ /*
770
+ * Pre-v8 MIDR space.
771
* Note that the MIDR isn't a simple constant register because
772
* of the TI925 behaviour where writes to another register can
773
* cause the MIDR value to change.
774
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
775
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
776
arm_feature(env, ARM_FEATURE_STRONGARM)) {
777
size_t i;
778
- /* Register the blanket "writes ignored" value first to cover the
779
+ /*
780
+ * Register the blanket "writes ignored" value first to cover the
781
* whole space. Then update the specific ID registers to allow write
782
* access, so that they ignore writes rather than causing them to
783
* UNDEF.
784
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
785
.raw_writefn = raw_write,
786
};
787
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
788
- /* Normally we would always end the TB on an SCTLR write, but Linux
789
+ /*
790
+ * Normally we would always end the TB on an SCTLR write, but Linux
791
* arch/arm/mach-pxa/sleep.S expects two instructions following
792
* an MMU enable to execute from cache. Imitate this behaviour.
793
*/
794
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
795
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
796
const ARMCPRegInfo *r, void *opaque)
797
{
798
- /* Define implementations of coprocessor registers.
799
+ /*
800
+ * Define implementations of coprocessor registers.
801
* We store these in a hashtable because typically
802
* there are less than 150 registers in a space which
803
* is 16*16*16*8*8 = 262144 in size.
804
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
805
default:
806
g_assert_not_reached();
807
}
808
- /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
809
+ /*
810
+ * The AArch64 pseudocode CheckSystemAccess() specifies that op1
811
* encodes a minimum access level for the register. We roll this
812
* runtime check into our general permission check code, so check
813
* here that the reginfo's specified permissions are strict enough
814
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
815
assert((r->access & ~mask) == 0);
816
}
817
818
- /* Check that the register definition has enough info to handle
819
+ /*
820
+ * Check that the register definition has enough info to handle
821
* reads and writes if they are permitted.
822
*/
823
if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
824
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
825
continue;
826
}
827
if (state == ARM_CP_STATE_AA32) {
828
- /* Under AArch32 CP registers can be common
829
+ /*
830
+ * Under AArch32 CP registers can be common
831
* (same for secure and non-secure world) or banked.
832
*/
833
char *name;
834
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
835
g_assert_not_reached();
836
}
837
} else {
838
- /* AArch64 registers get mapped to non-secure instance
839
- * of AArch32 */
840
+ /*
841
+ * AArch64 registers get mapped to non-secure instance
842
+ * of AArch32
843
+ */
844
add_cpreg_to_hashtable(cpu, r, opaque, state,
845
ARM_CP_SECSTATE_NS,
846
crm, opc1, opc2, r->name);
847
@@ -XXX,XX +XXX,XX @@ void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
848
849
static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
850
{
851
- /* Return true if it is not valid for us to switch to
852
+ /*
853
+ * Return true if it is not valid for us to switch to
854
* this CPU mode (ie all the UNPREDICTABLE cases in
855
* the ARM ARM CPSRWriteByInstr pseudocode).
856
*/
857
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
858
case ARM_CPU_MODE_UND:
859
case ARM_CPU_MODE_IRQ:
860
case ARM_CPU_MODE_FIQ:
861
- /* Note that we don't implement the IMPDEF NSACR.RFR which in v7
862
+ /*
863
+ * Note that we don't implement the IMPDEF NSACR.RFR which in v7
864
* allows FIQ mode to be Secure-only. (In v8 this doesn't exist.)
865
*/
866
- /* If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
867
+ /*
868
+ * If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
869
* and CPS are treated as illegal mode changes.
870
*/
871
if (write_type == CPSRWriteByInstr &&
872
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
873
env->GE = (val >> 16) & 0xf;
874
}
875
876
- /* In a V7 implementation that includes the security extensions but does
877
+ /*
878
+ * In a V7 implementation that includes the security extensions but does
879
* not include Virtualization Extensions the SCR.FW and SCR.AW bits control
880
* whether non-secure software is allowed to change the CPSR_F and CPSR_A
881
* bits respectively.
882
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
883
changed_daif = (env->daif ^ val) & mask;
884
885
if (changed_daif & CPSR_A) {
886
- /* Check to see if we are allowed to change the masking of async
887
+ /*
888
+ * Check to see if we are allowed to change the masking of async
889
* abort exceptions from a non-secure state.
890
*/
891
if (!(env->cp15.scr_el3 & SCR_AW)) {
892
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
893
}
894
895
if (changed_daif & CPSR_F) {
896
- /* Check to see if we are allowed to change the masking of FIQ
897
+ /*
898
+ * Check to see if we are allowed to change the masking of FIQ
899
* exceptions from a non-secure state.
900
*/
901
if (!(env->cp15.scr_el3 & SCR_FW)) {
902
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
903
mask &= ~CPSR_F;
904
}
905
906
- /* Check whether non-maskable FIQ (NMFI) support is enabled.
907
+ /*
908
+ * Check whether non-maskable FIQ (NMFI) support is enabled.
909
* If this bit is set software is not allowed to mask
910
* FIQs, but is allowed to set CPSR_F to 0.
911
*/
912
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
913
if (write_type != CPSRWriteRaw &&
914
((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
915
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
916
- /* Note that we can only get here in USR mode if this is a
917
+ /*
918
+ * Note that we can only get here in USR mode if this is a
919
* gdb stub write; for this case we follow the architectural
920
* behaviour for guest writes in USR mode of ignoring an attempt
921
* to switch mode. (Those are caught by translate.c for writes
922
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
923
*/
924
mask &= ~CPSR_M;
925
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
926
- /* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
927
+ /*
928
+ * Attempt to switch to an invalid mode: this is UNPREDICTABLE in
929
* v7, and has defined behaviour in v8:
930
* + leave CPSR.M untouched
931
* + allow changes to the other CPSR fields
932
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
933
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
934
}
935
936
-/* Physical Interrupt Target EL Lookup Table
937
+/*
938
+ * Physical Interrupt Target EL Lookup Table
939
*
940
* [ From ARM ARM section G1.13.4 (Table G1-15) ]
941
*
942
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
943
if (arm_feature(env, ARM_FEATURE_EL3)) {
944
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
945
} else {
946
- /* Either EL2 is the highest EL (and so the EL2 register width
947
+ /*
948
+ * Either EL2 is the highest EL (and so the EL2 register width
949
* is given by is64); or there is no EL2 or EL3, in which case
950
* the value of 'rw' does not affect the table lookup anyway.
951
*/
952
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
953
env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
954
}
955
956
- /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
957
+ /*
958
+ * Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
959
* mode, then we can copy to r8-r14. Otherwise, we copy to the
960
* FIQ bank for r8-r14.
961
*/
962
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
963
/* High vectors. When enabled, base address cannot be remapped. */
964
addr += 0xffff0000;
965
} else {
966
- /* ARM v7 architectures provide a vector base address register to remap
967
+ /*
968
+ * ARM v7 architectures provide a vector base address register to remap
969
* the interrupt vector table.
970
* This register is only followed in non-monitor mode, and is banked.
971
* Note: only bits 31:5 are valid.
972
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
973
aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
974
975
if (cur_el < new_el) {
976
- /* Entry vector offset depends on whether the implemented EL
977
+ /*
978
+ * Entry vector offset depends on whether the implemented EL
979
* immediately lower than the target level is using AArch32 or AArch64
980
*/
981
bool is_aa64;
982
@@ -XXX,XX +XXX,XX @@ static void handle_semihosting(CPUState *cs)
983
}
984
#endif
985
986
-/* Handle a CPU exception for A and R profile CPUs.
987
+/*
988
+ * Handle a CPU exception for A and R profile CPUs.
989
* Do any appropriate logging, handle PSCI calls, and then hand off
990
* to the AArch64-entry or AArch32-entry function depending on the
991
* target exception level's register width.
992
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
993
}
994
#endif
995
996
- /* Hooks may change global state so BQL should be held, also the
997
+ /*
998
+ * Hooks may change global state so BQL should be held, also the
999
* BQL needs to be held for any modification of
1000
* cs->interrupt_request.
1001
*/
1002
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
1003
};
1004
}
1005
1006
-/* Note that signed overflow is undefined in C. The following routines are
1007
- careful to use unsigned types where modulo arithmetic is required.
1008
- Failure to do so _will_ break on newer gcc. */
1009
+/*
1010
+ * Note that signed overflow is undefined in C. The following routines are
1011
+ * careful to use unsigned types where modulo arithmetic is required.
1012
+ * Failure to do so _will_ break on newer gcc.
1013
+ */
1014
1015
/* Signed saturating arithmetic. */
1016
1017
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
1018
return (a & mask) | (b & ~mask);
1019
}
1020
1021
-/* CRC helpers.
1022
+/*
1023
+ * CRC helpers.
1024
* The upper bytes of val (above the number specified by 'bytes') must have
1025
* been zeroed out by the caller.
1026
*/
1027
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
1028
return crc32c(acc, buf, bytes) ^ 0xffffffff;
1029
}
1030
1031
-/* Return the exception level to which FP-disabled exceptions should
1032
+/*
1033
+ * Return the exception level to which FP-disabled exceptions should
1034
* be taken, or 0 if FP is enabled.
1035
*/
1036
int fp_exception_el(CPUARMState *env, int cur_el)
1037
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1038
#ifndef CONFIG_USER_ONLY
1039
uint64_t hcr_el2;
1040
1041
- /* CPACR and the CPTR registers don't exist before v6, so FP is
1042
+ /*
1043
+ * CPACR and the CPTR registers don't exist before v6, so FP is
1044
* always accessible
1045
*/
1046
if (!arm_feature(env, ARM_FEATURE_V6)) {
1047
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1048
1049
hcr_el2 = arm_hcr_el2_eff(env);
1050
1051
- /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1052
+ /*
1053
+ * The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1054
* 0, 2 : trap EL0 and EL1/PL1 accesses
1055
* 1 : trap only EL0 accesses
1056
* 3 : trap no accesses
171
--
1057
--
172
2.20.1
1058
2.25.1
173
174
diff view generated by jsdifflib
New patch
1
From: Fabiano Rosas <farosas@suse.de>
1
2
3
Fix the following:
4
5
ERROR: spaces required around that '|' (ctx:VxV)
6
ERROR: space required before the open parenthesis '('
7
ERROR: spaces required around that '+' (ctx:VxB)
8
ERROR: space prohibited between function name and open parenthesis '('
9
10
(the last two still have some occurrences in macros which I left
11
behind because it might impact readability)
12
13
Signed-off-by: Fabiano Rosas <farosas@suse.de>
14
Reviewed-by: Claudio Fontana <cfontana@suse.de>
15
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
16
Message-id: 20221213190537.511-3-farosas@suse.de
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
target/arm/helper.c | 42 +++++++++++++++++++++---------------------
20
1 file changed, 21 insertions(+), 21 deletions(-)
21
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper.c
25
+++ b/target/arm/helper.c
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
27
uint32_t regidx = (uintptr_t)key;
28
const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
29
30
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
31
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
32
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
33
/* The value array need not be initialized at this point */
34
cpu->cpreg_array_len++;
35
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
36
37
ri = g_hash_table_lookup(cpu->cp_regs, key);
38
39
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
40
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
41
cpu->cpreg_array_len++;
42
}
43
}
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
45
.resetfn = arm_cp_reset_ignore },
46
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
47
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
48
- .access = PL0_R|PL1_W,
49
+ .access = PL0_R | PL1_W,
50
.fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
51
.resetvalue = 0},
52
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
53
- .access = PL0_R|PL1_W,
54
+ .access = PL0_R | PL1_W,
55
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
56
offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
57
.resetfn = arm_cp_reset_ignore },
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
59
.resetvalue = 0 },
60
/* The cache ops themselves: these all NOP for QEMU */
61
{ .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
62
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
63
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
64
{ .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
65
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
66
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
67
{ .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
68
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
69
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
70
{ .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
71
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
72
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
73
{ .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
74
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
75
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
76
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
77
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
78
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
79
};
80
81
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
82
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
83
ARMCPRegInfo cbar = {
84
.name = "CBAR",
85
.cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
86
- .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
87
+ .access = PL1_R | PL3_W, .resetvalue = cpu->reset_cbar,
88
.fieldoffset = offsetof(CPUARMState,
89
cp15.c15_config_base_address)
90
};
91
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
92
return;
93
94
if (old_mode == ARM_CPU_MODE_FIQ) {
95
- memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
96
- memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
97
+ memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
98
+ memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
99
} else if (mode == ARM_CPU_MODE_FIQ) {
100
- memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
101
- memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
102
+ memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
103
+ memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
104
}
105
106
i = bank_number(old_mode);
107
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
108
RESULT(sum, n, 16); \
109
if (sum >= 0) \
110
ge |= 3 << (n * 2); \
111
- } while(0)
112
+ } while (0)
113
114
#define SARITH8(a, b, n, op) do { \
115
int32_t sum; \
116
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
117
RESULT(sum, n, 8); \
118
if (sum >= 0) \
119
ge |= 1 << n; \
120
- } while(0)
121
+ } while (0)
122
123
124
#define ADD16(a, b, n) SARITH16(a, b, n, +)
125
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
126
RESULT(sum, n, 16); \
127
if ((sum >> 16) == 1) \
128
ge |= 3 << (n * 2); \
129
- } while(0)
130
+ } while (0)
131
132
#define ADD8(a, b, n) do { \
133
uint32_t sum; \
134
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
135
RESULT(sum, n, 8); \
136
if ((sum >> 8) == 1) \
137
ge |= 1 << n; \
138
- } while(0)
139
+ } while (0)
140
141
#define SUB16(a, b, n) do { \
142
uint32_t sum; \
143
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
144
RESULT(sum, n, 16); \
145
if ((sum >> 16) == 0) \
146
ge |= 3 << (n * 2); \
147
- } while(0)
148
+ } while (0)
149
150
#define SUB8(a, b, n) do { \
151
uint32_t sum; \
152
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
153
RESULT(sum, n, 8); \
154
if ((sum >> 8) == 0) \
155
ge |= 1 << n; \
156
- } while(0)
157
+ } while (0)
158
159
#define PFX u
160
#define ARITH_GE
161
--
162
2.25.1
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
Defined descriptors for ITS device table,collection table and ITS
3
Fix this:
4
command queue entities.Implemented register read/write functions,
4
ERROR: braces {} are necessary for all arms of this statement
5
extract ITS table parameters and command queue parameters,extended
6
gicv3 common to capture qemu address space(which host the ITS table
7
platform memories required for subsequent ITS processing) and
8
initialize the same in ITS device.
9
5
10
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
13
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
9
Message-id: 20221213190537.511-4-farosas@suse.de
14
Message-id: 20210910143951.92242-3-shashi.mallela@linaro.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/intc/gicv3_internal.h | 29 ++
12
target/arm/helper.c | 67 ++++++++++++++++++++++++++++-----------------
18
include/hw/intc/arm_gicv3_common.h | 3 +
13
1 file changed, 42 insertions(+), 25 deletions(-)
19
include/hw/intc/arm_gicv3_its_common.h | 23 ++
20
hw/intc/arm_gicv3_its.c | 376 +++++++++++++++++++++++++
21
4 files changed, 431 insertions(+)
22
14
23
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/gicv3_internal.h
17
--- a/target/arm/helper.c
26
+++ b/hw/intc/gicv3_internal.h
18
+++ b/target/arm/helper.c
27
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_BASER, INNERCACHE, 59, 3)
19
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
28
FIELD(GITS_BASER, INDIRECT, 62, 1)
20
env->CF = (val >> 29) & 1;
29
FIELD(GITS_BASER, VALID, 63, 1)
21
env->VF = (val << 3) & 0x80000000;
30
22
}
31
+FIELD(GITS_CBASER, SIZE, 0, 8)
23
- if (mask & CPSR_Q)
32
+FIELD(GITS_CBASER, SHAREABILITY, 10, 2)
24
+ if (mask & CPSR_Q) {
33
+FIELD(GITS_CBASER, PHYADDR, 12, 40)
25
env->QF = ((val & CPSR_Q) != 0);
34
+FIELD(GITS_CBASER, OUTERCACHE, 53, 3)
26
- if (mask & CPSR_T)
35
+FIELD(GITS_CBASER, INNERCACHE, 59, 3)
36
+FIELD(GITS_CBASER, VALID, 63, 1)
37
+
38
+FIELD(GITS_CREADR, STALLED, 0, 1)
39
+FIELD(GITS_CREADR, OFFSET, 5, 15)
40
+
41
+FIELD(GITS_CWRITER, RETRY, 0, 1)
42
+FIELD(GITS_CWRITER, OFFSET, 5, 15)
43
+
44
+FIELD(GITS_CTLR, ENABLED, 0, 1)
45
FIELD(GITS_CTLR, QUIESCENT, 31, 1)
46
47
FIELD(GITS_TYPER, PHYSICAL, 0, 1)
48
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, PTA, 19, 1)
49
FIELD(GITS_TYPER, CIDBITS, 32, 4)
50
FIELD(GITS_TYPER, CIL, 36, 1)
51
52
+#define GITS_IDREGS 0xFFD0
53
+
54
+#define ITS_CTLR_ENABLED (1U) /* ITS Enabled */
55
+
56
+#define GITS_BASER_RO_MASK (R_GITS_BASER_ENTRYSIZE_MASK | \
57
+ R_GITS_BASER_TYPE_MASK)
58
+
59
#define GITS_BASER_PAGESIZE_4K 0
60
#define GITS_BASER_PAGESIZE_16K 1
61
#define GITS_BASER_PAGESIZE_64K 2
62
@@ -XXX,XX +XXX,XX @@ FIELD(GITS_TYPER, CIL, 36, 1)
63
#define GITS_BASER_TYPE_DEVICE 1ULL
64
#define GITS_BASER_TYPE_COLLECTION 4ULL
65
66
+#define GITS_PAGE_SIZE_4K 0x1000
67
+#define GITS_PAGE_SIZE_16K 0x4000
68
+#define GITS_PAGE_SIZE_64K 0x10000
69
+
70
+#define L1TABLE_ENTRY_SIZE 8
71
+
72
+#define GITS_CMDQ_ENTRY_SIZE 32
73
+
74
/**
75
* Default features advertised by this version of ITS
76
*/
77
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
78
index XXXXXXX..XXXXXXX 100644
79
--- a/include/hw/intc/arm_gicv3_common.h
80
+++ b/include/hw/intc/arm_gicv3_common.h
81
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
82
int dev_fd; /* kvm device fd if backed by kvm vgic support */
83
Error *migration_blocker;
84
85
+ MemoryRegion *dma;
86
+ AddressSpace dma_as;
87
+
88
/* Distributor */
89
90
/* for a GIC with the security extensions the NS banked version of this
91
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
92
index XXXXXXX..XXXXXXX 100644
93
--- a/include/hw/intc/arm_gicv3_its_common.h
94
+++ b/include/hw/intc/arm_gicv3_its_common.h
95
@@ -XXX,XX +XXX,XX @@
96
97
#define GITS_TRANSLATER 0x0040
98
99
+typedef struct {
100
+ bool valid;
101
+ bool indirect;
102
+ uint16_t entry_sz;
103
+ uint32_t page_sz;
104
+ uint32_t max_entries;
105
+ union {
106
+ uint32_t max_devids;
107
+ uint32_t max_collids;
108
+ } maxids;
109
+ uint64_t base_addr;
110
+} TableDesc;
111
+
112
+typedef struct {
113
+ bool valid;
114
+ uint32_t max_entries;
115
+ uint64_t base_addr;
116
+} CmdQDesc;
117
+
118
struct GICv3ITSState {
119
SysBusDevice parent_obj;
120
121
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
122
uint64_t creadr;
123
uint64_t baser[8];
124
125
+ TableDesc dt;
126
+ TableDesc ct;
127
+ CmdQDesc cq;
128
+
129
Error *migration_blocker;
130
};
131
132
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/intc/arm_gicv3_its.c
135
+++ b/hw/intc/arm_gicv3_its.c
136
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSClass {
137
void (*parent_reset)(DeviceState *dev);
138
};
139
140
+static uint64_t baser_base_addr(uint64_t value, uint32_t page_sz)
141
+{
142
+ uint64_t result = 0;
143
+
144
+ switch (page_sz) {
145
+ case GITS_PAGE_SIZE_4K:
146
+ case GITS_PAGE_SIZE_16K:
147
+ result = FIELD_EX64(value, GITS_BASER, PHYADDR) << 12;
148
+ break;
149
+
150
+ case GITS_PAGE_SIZE_64K:
151
+ result = FIELD_EX64(value, GITS_BASER, PHYADDRL_64K) << 16;
152
+ result |= FIELD_EX64(value, GITS_BASER, PHYADDRH_64K) << 48;
153
+ break;
154
+
155
+ default:
156
+ break;
157
+ }
27
+ }
158
+ return result;
28
+ if (mask & CPSR_T) {
159
+}
29
env->thumb = ((val & CPSR_T) != 0);
160
+
30
+ }
161
+/*
31
if (mask & CPSR_IT_0_1) {
162
+ * This function extracts the ITS Device and Collection table specific
32
env->condexec_bits &= ~3;
163
+ * parameters (like base_addr, size etc) from GITS_BASER register.
33
env->condexec_bits |= (val >> 25) & 3;
164
+ * It is called during ITS enable and also during post_load migration
34
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
165
+ */
35
int i;
166
+static void extract_table_params(GICv3ITSState *s)
36
167
+{
37
old_mode = env->uncached_cpsr & CPSR_M;
168
+ uint16_t num_pages = 0;
38
- if (mode == old_mode)
169
+ uint8_t page_sz_type;
39
+ if (mode == old_mode) {
170
+ uint8_t type;
40
return;
171
+ uint32_t page_sz = 0;
41
+ }
172
+ uint64_t value;
42
173
+
43
if (old_mode == ARM_CPU_MODE_FIQ) {
174
+ for (int i = 0; i < 8; i++) {
44
memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
175
+ value = s->baser[i];
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
176
+
46
new_mode = ARM_CPU_MODE_UND;
177
+ if (!value) {
47
addr = 0x04;
178
+ continue;
48
mask = CPSR_I;
49
- if (env->thumb)
50
+ if (env->thumb) {
51
offset = 2;
52
- else
53
+ } else {
54
offset = 4;
179
+ }
55
+ }
180
+
56
break;
181
+ page_sz_type = FIELD_EX64(value, GITS_BASER, PAGESIZE);
57
case EXCP_SWI:
182
+
58
new_mode = ARM_CPU_MODE_SVC;
183
+ switch (page_sz_type) {
59
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_sat(uint16_t a, uint16_t b)
184
+ case 0:
60
185
+ page_sz = GITS_PAGE_SIZE_4K;
61
res = a + b;
186
+ break;
62
if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
187
+
63
- if (a & 0x8000)
188
+ case 1:
64
+ if (a & 0x8000) {
189
+ page_sz = GITS_PAGE_SIZE_16K;
65
res = 0x8000;
190
+ break;
66
- else
191
+
67
+ } else {
192
+ case 2:
68
res = 0x7fff;
193
+ case 3:
194
+ page_sz = GITS_PAGE_SIZE_64K;
195
+ break;
196
+
197
+ default:
198
+ g_assert_not_reached();
199
+ }
69
+ }
200
+
70
}
201
+ num_pages = FIELD_EX64(value, GITS_BASER, SIZE) + 1;
71
return res;
202
+
72
}
203
+ type = FIELD_EX64(value, GITS_BASER, TYPE);
73
@@ -XXX,XX +XXX,XX @@ static inline uint8_t add8_sat(uint8_t a, uint8_t b)
204
+
74
205
+ switch (type) {
75
res = a + b;
206
+
76
if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
207
+ case GITS_BASER_TYPE_DEVICE:
77
- if (a & 0x80)
208
+ memset(&s->dt, 0 , sizeof(s->dt));
78
+ if (a & 0x80) {
209
+ s->dt.valid = FIELD_EX64(value, GITS_BASER, VALID);
79
res = 0x80;
210
+
80
- else
211
+ if (!s->dt.valid) {
81
+ } else {
212
+ return;
82
res = 0x7f;
213
+ }
214
+
215
+ s->dt.page_sz = page_sz;
216
+ s->dt.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
217
+ s->dt.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
218
+
219
+ if (!s->dt.indirect) {
220
+ s->dt.max_entries = (num_pages * page_sz) / s->dt.entry_sz;
221
+ } else {
222
+ s->dt.max_entries = (((num_pages * page_sz) /
223
+ L1TABLE_ENTRY_SIZE) *
224
+ (page_sz / s->dt.entry_sz));
225
+ }
226
+
227
+ s->dt.maxids.max_devids = (1UL << (FIELD_EX64(s->typer, GITS_TYPER,
228
+ DEVBITS) + 1));
229
+
230
+ s->dt.base_addr = baser_base_addr(value, page_sz);
231
+
232
+ break;
233
+
234
+ case GITS_BASER_TYPE_COLLECTION:
235
+ memset(&s->ct, 0 , sizeof(s->ct));
236
+ s->ct.valid = FIELD_EX64(value, GITS_BASER, VALID);
237
+
238
+ /*
239
+ * GITS_TYPER.HCC is 0 for this implementation
240
+ * hence writes are discarded if ct.valid is 0
241
+ */
242
+ if (!s->ct.valid) {
243
+ return;
244
+ }
245
+
246
+ s->ct.page_sz = page_sz;
247
+ s->ct.indirect = FIELD_EX64(value, GITS_BASER, INDIRECT);
248
+ s->ct.entry_sz = FIELD_EX64(value, GITS_BASER, ENTRYSIZE);
249
+
250
+ if (!s->ct.indirect) {
251
+ s->ct.max_entries = (num_pages * page_sz) / s->ct.entry_sz;
252
+ } else {
253
+ s->ct.max_entries = (((num_pages * page_sz) /
254
+ L1TABLE_ENTRY_SIZE) *
255
+ (page_sz / s->ct.entry_sz));
256
+ }
257
+
258
+ if (FIELD_EX64(s->typer, GITS_TYPER, CIL)) {
259
+ s->ct.maxids.max_collids = (1UL << (FIELD_EX64(s->typer,
260
+ GITS_TYPER, CIDBITS) + 1));
261
+ } else {
262
+ /* 16-bit CollectionId supported when CIL == 0 */
263
+ s->ct.maxids.max_collids = (1UL << 16);
264
+ }
265
+
266
+ s->ct.base_addr = baser_base_addr(value, page_sz);
267
+
268
+ break;
269
+
270
+ default:
271
+ break;
272
+ }
83
+ }
84
}
85
return res;
86
}
87
@@ -XXX,XX +XXX,XX @@ static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
88
89
res = a - b;
90
if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
91
- if (a & 0x8000)
92
+ if (a & 0x8000) {
93
res = 0x8000;
94
- else
95
+ } else {
96
res = 0x7fff;
97
+ }
98
}
99
return res;
100
}
101
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
102
103
res = a - b;
104
if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
105
- if (a & 0x80)
106
+ if (a & 0x80) {
107
res = 0x80;
108
- else
109
+ } else {
110
res = 0x7f;
111
+ }
112
}
113
return res;
114
}
115
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_usat(uint16_t a, uint16_t b)
116
{
117
uint16_t res;
118
res = a + b;
119
- if (res < a)
120
+ if (res < a) {
121
res = 0xffff;
273
+ }
122
+ }
274
+}
123
return res;
275
+
124
}
276
+static void extract_cmdq_params(GICv3ITSState *s)
125
277
+{
126
static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
278
+ uint16_t num_pages = 0;
127
{
279
+ uint64_t value = s->cbaser;
128
- if (a > b)
280
+
129
+ if (a > b) {
281
+ num_pages = FIELD_EX64(value, GITS_CBASER, SIZE) + 1;
130
return a - b;
282
+
131
- else
283
+ memset(&s->cq, 0 , sizeof(s->cq));
132
+ } else {
284
+ s->cq.valid = FIELD_EX64(value, GITS_CBASER, VALID);
133
return 0;
285
+
286
+ if (s->cq.valid) {
287
+ s->cq.max_entries = (num_pages * GITS_PAGE_SIZE_4K) /
288
+ GITS_CMDQ_ENTRY_SIZE;
289
+ s->cq.base_addr = FIELD_EX64(value, GITS_CBASER, PHYADDR);
290
+ s->cq.base_addr <<= R_GITS_CBASER_PHYADDR_SHIFT;
291
+ }
134
+ }
292
+}
135
}
293
+
136
294
static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
137
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
295
uint64_t data, unsigned size,
296
MemTxAttrs attrs)
297
@@ -XXX,XX +XXX,XX @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
298
uint64_t value, MemTxAttrs attrs)
299
{
138
{
300
bool result = true;
139
uint8_t res;
301
+ int index;
140
res = a + b;
302
141
- if (res < a)
303
+ switch (offset) {
142
+ if (res < a) {
304
+ case GITS_CTLR:
143
res = 0xff;
305
+ s->ctlr |= (value & ~(s->ctlr));
306
+
307
+ if (s->ctlr & ITS_CTLR_ENABLED) {
308
+ extract_table_params(s);
309
+ extract_cmdq_params(s);
310
+ s->creadr = 0;
311
+ }
312
+ break;
313
+ case GITS_CBASER:
314
+ /*
315
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
316
+ * already enabled
317
+ */
318
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
319
+ s->cbaser = deposit64(s->cbaser, 0, 32, value);
320
+ s->creadr = 0;
321
+ s->cwriter = s->creadr;
322
+ }
323
+ break;
324
+ case GITS_CBASER + 4:
325
+ /*
326
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
327
+ * already enabled
328
+ */
329
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
330
+ s->cbaser = deposit64(s->cbaser, 32, 32, value);
331
+ s->creadr = 0;
332
+ s->cwriter = s->creadr;
333
+ }
334
+ break;
335
+ case GITS_CWRITER:
336
+ s->cwriter = deposit64(s->cwriter, 0, 32,
337
+ (value & ~R_GITS_CWRITER_RETRY_MASK));
338
+ break;
339
+ case GITS_CWRITER + 4:
340
+ s->cwriter = deposit64(s->cwriter, 32, 32, value);
341
+ break;
342
+ case GITS_CREADR:
343
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
344
+ s->creadr = deposit64(s->creadr, 0, 32,
345
+ (value & ~R_GITS_CREADR_STALLED_MASK));
346
+ } else {
347
+ /* RO register, ignore the write */
348
+ qemu_log_mask(LOG_GUEST_ERROR,
349
+ "%s: invalid guest write to RO register at offset "
350
+ TARGET_FMT_plx "\n", __func__, offset);
351
+ }
352
+ break;
353
+ case GITS_CREADR + 4:
354
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
355
+ s->creadr = deposit64(s->creadr, 32, 32, value);
356
+ } else {
357
+ /* RO register, ignore the write */
358
+ qemu_log_mask(LOG_GUEST_ERROR,
359
+ "%s: invalid guest write to RO register at offset "
360
+ TARGET_FMT_plx "\n", __func__, offset);
361
+ }
362
+ break;
363
+ case GITS_BASER ... GITS_BASER + 0x3f:
364
+ /*
365
+ * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
366
+ * already enabled
367
+ */
368
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
369
+ index = (offset - GITS_BASER) / 8;
370
+
371
+ if (offset & 7) {
372
+ value <<= 32;
373
+ value &= ~GITS_BASER_RO_MASK;
374
+ s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(0, 32);
375
+ s->baser[index] |= value;
376
+ } else {
377
+ value &= ~GITS_BASER_RO_MASK;
378
+ s->baser[index] &= GITS_BASER_RO_MASK | MAKE_64BIT_MASK(32, 32);
379
+ s->baser[index] |= value;
380
+ }
381
+ }
382
+ break;
383
+ case GITS_IIDR:
384
+ case GITS_IDREGS ... GITS_IDREGS + 0x2f:
385
+ /* RO registers, ignore the write */
386
+ qemu_log_mask(LOG_GUEST_ERROR,
387
+ "%s: invalid guest write to RO register at offset "
388
+ TARGET_FMT_plx "\n", __func__, offset);
389
+ break;
390
+ default:
391
+ result = false;
392
+ break;
393
+ }
144
+ }
394
return result;
145
return res;
395
}
146
}
396
147
397
@@ -XXX,XX +XXX,XX @@ static bool its_readl(GICv3ITSState *s, hwaddr offset,
148
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
398
uint64_t *data, MemTxAttrs attrs)
399
{
149
{
400
bool result = true;
150
- if (a > b)
401
+ int index;
151
+ if (a > b) {
402
152
return a - b;
403
+ switch (offset) {
153
- else
404
+ case GITS_CTLR:
154
+ } else {
405
+ *data = s->ctlr;
155
return 0;
406
+ break;
407
+ case GITS_IIDR:
408
+ *data = gicv3_iidr();
409
+ break;
410
+ case GITS_IDREGS ... GITS_IDREGS + 0x2f:
411
+ /* ID registers */
412
+ *data = gicv3_idreg(offset - GITS_IDREGS);
413
+ break;
414
+ case GITS_TYPER:
415
+ *data = extract64(s->typer, 0, 32);
416
+ break;
417
+ case GITS_TYPER + 4:
418
+ *data = extract64(s->typer, 32, 32);
419
+ break;
420
+ case GITS_CBASER:
421
+ *data = extract64(s->cbaser, 0, 32);
422
+ break;
423
+ case GITS_CBASER + 4:
424
+ *data = extract64(s->cbaser, 32, 32);
425
+ break;
426
+ case GITS_CREADR:
427
+ *data = extract64(s->creadr, 0, 32);
428
+ break;
429
+ case GITS_CREADR + 4:
430
+ *data = extract64(s->creadr, 32, 32);
431
+ break;
432
+ case GITS_CWRITER:
433
+ *data = extract64(s->cwriter, 0, 32);
434
+ break;
435
+ case GITS_CWRITER + 4:
436
+ *data = extract64(s->cwriter, 32, 32);
437
+ break;
438
+ case GITS_BASER ... GITS_BASER + 0x3f:
439
+ index = (offset - GITS_BASER) / 8;
440
+ if (offset & 7) {
441
+ *data = extract64(s->baser[index], 32, 32);
442
+ } else {
443
+ *data = extract64(s->baser[index], 0, 32);
444
+ }
445
+ break;
446
+ default:
447
+ result = false;
448
+ break;
449
+ }
156
+ }
450
return result;
451
}
157
}
452
158
453
@@ -XXX,XX +XXX,XX @@ static bool its_writell(GICv3ITSState *s, hwaddr offset,
159
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
454
uint64_t value, MemTxAttrs attrs)
160
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
161
162
static inline uint8_t do_usad(uint8_t a, uint8_t b)
455
{
163
{
456
bool result = true;
164
- if (a > b)
457
+ int index;
165
+ if (a > b) {
458
166
return a - b;
459
+ switch (offset) {
167
- else
460
+ case GITS_BASER ... GITS_BASER + 0x3f:
168
+ } else {
461
+ /*
169
return b - a;
462
+ * IMPDEF choice:- GITS_BASERn register becomes RO if ITS is
463
+ * already enabled
464
+ */
465
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
466
+ index = (offset - GITS_BASER) / 8;
467
+ s->baser[index] &= GITS_BASER_RO_MASK;
468
+ s->baser[index] |= (value & ~GITS_BASER_RO_MASK);
469
+ }
470
+ break;
471
+ case GITS_CBASER:
472
+ /*
473
+ * IMPDEF choice:- GITS_CBASER register becomes RO if ITS is
474
+ * already enabled
475
+ */
476
+ if (!(s->ctlr & ITS_CTLR_ENABLED)) {
477
+ s->cbaser = value;
478
+ s->creadr = 0;
479
+ s->cwriter = s->creadr;
480
+ }
481
+ break;
482
+ case GITS_CWRITER:
483
+ s->cwriter = value & ~R_GITS_CWRITER_RETRY_MASK;
484
+ break;
485
+ case GITS_CREADR:
486
+ if (s->gicv3->gicd_ctlr & GICD_CTLR_DS) {
487
+ s->creadr = value & ~R_GITS_CREADR_STALLED_MASK;
488
+ } else {
489
+ /* RO register, ignore the write */
490
+ qemu_log_mask(LOG_GUEST_ERROR,
491
+ "%s: invalid guest write to RO register at offset "
492
+ TARGET_FMT_plx "\n", __func__, offset);
493
+ }
494
+ break;
495
+ case GITS_TYPER:
496
+ /* RO registers, ignore the write */
497
+ qemu_log_mask(LOG_GUEST_ERROR,
498
+ "%s: invalid guest write to RO register at offset "
499
+ TARGET_FMT_plx "\n", __func__, offset);
500
+ break;
501
+ default:
502
+ result = false;
503
+ break;
504
+ }
170
+ }
505
return result;
506
}
171
}
507
172
508
@@ -XXX,XX +XXX,XX @@ static bool its_readll(GICv3ITSState *s, hwaddr offset,
173
/* Unsigned sum of absolute byte differences. */
509
uint64_t *data, MemTxAttrs attrs)
174
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
510
{
175
uint32_t mask;
511
bool result = true;
176
512
+ int index;
177
mask = 0;
513
178
- if (flags & 1)
514
+ switch (offset) {
179
+ if (flags & 1) {
515
+ case GITS_TYPER:
180
mask |= 0xff;
516
+ *data = s->typer;
181
- if (flags & 2)
517
+ break;
518
+ case GITS_BASER ... GITS_BASER + 0x3f:
519
+ index = (offset - GITS_BASER) / 8;
520
+ *data = s->baser[index];
521
+ break;
522
+ case GITS_CBASER:
523
+ *data = s->cbaser;
524
+ break;
525
+ case GITS_CREADR:
526
+ *data = s->creadr;
527
+ break;
528
+ case GITS_CWRITER:
529
+ *data = s->cwriter;
530
+ break;
531
+ default:
532
+ result = false;
533
+ break;
534
+ }
182
+ }
535
return result;
183
+ if (flags & 2) {
184
mask |= 0xff00;
185
- if (flags & 4)
186
+ }
187
+ if (flags & 4) {
188
mask |= 0xff0000;
189
- if (flags & 8)
190
+ }
191
+ if (flags & 8) {
192
mask |= 0xff000000;
193
+ }
194
return (a & mask) | (b & ~mask);
536
}
195
}
537
196
538
@@ -XXX,XX +XXX,XX @@ static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
539
540
gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
541
542
+ address_space_init(&s->gicv3->dma_as, s->gicv3->dma,
543
+ "gicv3-its-sysmem");
544
+
545
/* set the ITS default features supported */
546
s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL,
547
GITS_TYPE_PHYSICAL);
548
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_reset(DeviceState *dev)
549
GITS_CTE_SIZE - 1);
550
}
551
552
+static void gicv3_its_post_load(GICv3ITSState *s)
553
+{
554
+ if (s->ctlr & ITS_CTLR_ENABLED) {
555
+ extract_table_params(s);
556
+ extract_cmdq_params(s);
557
+ }
558
+}
559
+
560
static Property gicv3_its_props[] = {
561
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3",
562
GICv3State *),
563
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_class_init(ObjectClass *klass, void *data)
564
{
565
DeviceClass *dc = DEVICE_CLASS(klass);
566
GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass);
567
+ GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
568
569
dc->realize = gicv3_arm_its_realize;
570
device_class_set_props(dc, gicv3_its_props);
571
device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset);
572
+ icc->post_load = gicv3_its_post_load;
573
}
574
575
static const TypeInfo gicv3_its_info = {
576
--
197
--
577
2.20.1
198
2.25.1
578
579
diff view generated by jsdifflib
New patch
1
From: Fabiano Rosas <farosas@suse.de>
1
2
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
Message-id: 20221213190537.511-5-farosas@suse.de
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/m_helper.c | 16 ----------------
10
1 file changed, 16 deletions(-)
11
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/m_helper.c
15
+++ b/target/arm/m_helper.c
16
@@ -XXX,XX +XXX,XX @@
17
*/
18
19
#include "qemu/osdep.h"
20
-#include "qemu/units.h"
21
-#include "target/arm/idau.h"
22
-#include "trace.h"
23
#include "cpu.h"
24
#include "internals.h"
25
-#include "exec/gdbstub.h"
26
#include "exec/helper-proto.h"
27
-#include "qemu/host-utils.h"
28
#include "qemu/main-loop.h"
29
#include "qemu/bitops.h"
30
-#include "qemu/crc32c.h"
31
-#include "qemu/qemu-print.h"
32
#include "qemu/log.h"
33
#include "exec/exec-all.h"
34
-#include <zlib.h> /* For crc32 */
35
-#include "semihosting/semihost.h"
36
-#include "sysemu/cpus.h"
37
-#include "sysemu/kvm.h"
38
-#include "qemu/range.h"
39
-#include "qapi/qapi-commands-machine-target.h"
40
-#include "qapi/error.h"
41
-#include "qemu/guest-random.h"
42
#ifdef CONFIG_TCG
43
-#include "arm_ldst.h"
44
#include "exec/cpu_ldst.h"
45
#include "semihosting/common-semi.h"
46
#endif
47
--
48
2.25.1
diff view generated by jsdifflib
New patch
1
From: Fabiano Rosas <farosas@suse.de>
1
2
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
Message-id: 20221213190537.511-6-farosas@suse.de
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper.c | 7 -------
10
1 file changed, 7 deletions(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@
17
*/
18
19
#include "qemu/osdep.h"
20
-#include "qemu/units.h"
21
#include "qemu/log.h"
22
#include "trace.h"
23
#include "cpu.h"
24
#include "internals.h"
25
#include "exec/helper-proto.h"
26
-#include "qemu/host-utils.h"
27
#include "qemu/main-loop.h"
28
#include "qemu/timer.h"
29
#include "qemu/bitops.h"
30
@@ -XXX,XX +XXX,XX @@
31
#include "exec/exec-all.h"
32
#include <zlib.h> /* For crc32 */
33
#include "hw/irq.h"
34
-#include "semihosting/semihost.h"
35
-#include "sysemu/cpus.h"
36
#include "sysemu/cpu-timers.h"
37
#include "sysemu/kvm.h"
38
-#include "qemu/range.h"
39
#include "qapi/qapi-commands-machine-target.h"
40
#include "qapi/error.h"
41
#include "qemu/guest-random.h"
42
#ifdef CONFIG_TCG
43
-#include "arm_ldst.h"
44
-#include "exec/cpu_ldst.h"
45
#include "semihosting/common-semi.h"
46
#endif
47
#include "cpregs.h"
48
--
49
2.25.1
diff view generated by jsdifflib
New patch
1
From: Claudio Fontana <cfontana@suse.de>
1
2
3
Remove some unused headers.
4
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Message-id: 20221213190537.511-7-farosas@suse.de
11
[added back some includes that are still needed at this point]
12
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/cpu.c | 1 -
16
target/arm/cpu64.c | 6 ------
17
2 files changed, 7 deletions(-)
18
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
23
@@ -XXX,XX +XXX,XX @@
24
#include "target/arm/idau.h"
25
#include "qemu/module.h"
26
#include "qapi/error.h"
27
-#include "qapi/visitor.h"
28
#include "cpu.h"
29
#ifdef CONFIG_TCG
30
#include "hw/core/tcg-cpu-ops.h"
31
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu64.c
34
+++ b/target/arm/cpu64.c
35
@@ -XXX,XX +XXX,XX @@
36
#include "qemu/osdep.h"
37
#include "qapi/error.h"
38
#include "cpu.h"
39
-#ifdef CONFIG_TCG
40
-#include "hw/core/tcg-cpu-ops.h"
41
-#endif /* CONFIG_TCG */
42
#include "qemu/module.h"
43
-#if !defined(CONFIG_USER_ONLY)
44
-#include "hw/loader.h"
45
-#endif
46
#include "sysemu/kvm.h"
47
#include "sysemu/hvf.h"
48
#include "kvm_arm.h"
49
--
50
2.25.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
At present when input clock is disabled, any character transmitted
3
The pointed MouseTransformInfo structure is accessed read-only.
4
to tx fifo can still show on the serial line, which is wrong.
5
4
6
Fixes: b636db306e06 ("hw/char/cadence_uart: add clock support")
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20221220142520.24094-2-philmd@linaro.org
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20210901124521.30599-3-bmeng.cn@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
9
---
13
hw/char/cadence_uart.c | 5 +++++
10
include/hw/input/tsc2xxx.h | 4 ++--
14
1 file changed, 5 insertions(+)
11
hw/input/tsc2005.c | 2 +-
12
hw/input/tsc210x.c | 3 +--
13
3 files changed, 4 insertions(+), 5 deletions(-)
15
14
16
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
15
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/char/cadence_uart.c
17
--- a/include/hw/input/tsc2xxx.h
19
+++ b/hw/char/cadence_uart.c
18
+++ b/include/hw/input/tsc2xxx.h
20
@@ -XXX,XX +XXX,XX @@ static gboolean cadence_uart_xmit(void *do_not_use, GIOCondition cond,
19
@@ -XXX,XX +XXX,XX @@ uWireSlave *tsc2102_init(qemu_irq pint);
21
static void uart_write_tx_fifo(CadenceUARTState *s, const uint8_t *buf,
20
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
22
int size)
21
I2SCodec *tsc210x_codec(uWireSlave *chip);
22
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
23
-void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
24
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info);
25
void tsc210x_key_event(uWireSlave *chip, int key, int down);
26
27
/* tsc2005.c */
28
void *tsc2005_init(qemu_irq pintdav);
29
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
30
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
31
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info);
32
33
#endif
34
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/input/tsc2005.c
37
+++ b/hw/input/tsc2005.c
38
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav)
39
* from the touchscreen. Assuming 12-bit precision was used during
40
* tslib calibration.
41
*/
42
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info)
43
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info)
23
{
44
{
24
+ /* ignore characters when unclocked or in reset */
45
TSC2005State *s = (TSC2005State *) opaque;
25
+ if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
46
26
+ return;
47
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
27
+ }
48
index XXXXXXX..XXXXXXX 100644
28
+
49
--- a/hw/input/tsc210x.c
29
if ((s->r[R_CR] & UART_CR_TX_DIS) || !(s->r[R_CR] & UART_CR_TX_EN)) {
50
+++ b/hw/input/tsc210x.c
30
return;
51
@@ -XXX,XX +XXX,XX @@ I2SCodec *tsc210x_codec(uWireSlave *chip)
31
}
52
* from the touchscreen. Assuming 12-bit precision was used during
53
* tslib calibration.
54
*/
55
-void tsc210x_set_transform(uWireSlave *chip,
56
- MouseTransformInfo *info)
57
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info)
58
{
59
TSC210xState *s = (TSC210xState *) chip->opaque;
60
#if 0
32
--
61
--
33
2.20.1
62
2.25.1
34
63
35
64
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Added properties to enable ITS feature and define qemu system
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
address space memory in gicv3 common,setup distributor and
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
redistributor registers to indicate LPI support.
5
Message-id: 20221220142520.24094-3-philmd@linaro.org
6
7
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
10
Message-id: 20210910143951.92242-6-shashi.mallela@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
hw/intc/gicv3_internal.h | 2 ++
8
hw/arm/nseries.c | 18 +++++++++---------
14
include/hw/intc/arm_gicv3_common.h | 1 +
9
1 file changed, 9 insertions(+), 9 deletions(-)
15
hw/intc/arm_gicv3_common.c | 12 ++++++++++++
16
hw/intc/arm_gicv3_dist.c | 5 ++++-
17
hw/intc/arm_gicv3_redist.c | 12 +++++++++---
18
5 files changed, 28 insertions(+), 4 deletions(-)
19
10
20
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
11
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/intc/gicv3_internal.h
13
--- a/hw/arm/nseries.c
23
+++ b/hw/intc/gicv3_internal.h
14
+++ b/hw/arm/nseries.c
24
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
25
#define GICD_CTLR_E1NWF (1U << 7)
26
#define GICD_CTLR_RWP (1U << 31)
27
28
+#define GICD_TYPER_LPIS_SHIFT 17
29
+
30
/* 16 bits EventId */
31
#define GICD_TYPER_IDBITS 0xf
32
33
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/include/hw/intc/arm_gicv3_common.h
36
+++ b/include/hw/intc/arm_gicv3_common.h
37
@@ -XXX,XX +XXX,XX @@ struct GICv3State {
38
uint32_t num_cpu;
39
uint32_t num_irq;
40
uint32_t revision;
41
+ bool lpi_enable;
42
bool security_extn;
43
bool irq_reset_nonsecure;
44
bool gicd_no_migration_shift_bug;
45
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/intc/arm_gicv3_common.c
48
+++ b/hw/intc/arm_gicv3_common.c
49
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
50
return;
51
}
52
53
+ if (s->lpi_enable && !s->dma) {
54
+ error_setg(errp, "Redist-ITS: Guest 'sysmem' reference link not set");
55
+ return;
56
+ }
57
+
58
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
59
60
for (i = 0; i < s->num_cpu; i++) {
61
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
62
(1 << 24) |
63
(i << 8) |
64
(last << 4);
65
+
66
+ if (s->lpi_enable) {
67
+ s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
68
+ }
69
}
70
}
16
}
71
17
72
@@ -XXX,XX +XXX,XX @@ static Property arm_gicv3_common_properties[] = {
18
/* Touchscreen and keypad controller */
73
DEFINE_PROP_UINT32("num-cpu", GICv3State, num_cpu, 1),
19
-static MouseTransformInfo n800_pointercal = {
74
DEFINE_PROP_UINT32("num-irq", GICv3State, num_irq, 32),
20
+static const MouseTransformInfo n800_pointercal = {
75
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
21
.x = 800,
76
+ DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
22
.y = 480,
77
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
23
.a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
78
DEFINE_PROP_ARRAY("redist-region-count", GICv3State, nb_redist_regions,
79
redist_region_count, qdev_prop_uint32, uint32_t),
80
+ DEFINE_PROP_LINK("sysmem", GICv3State, dma, TYPE_MEMORY_REGION,
81
+ MemoryRegion *),
82
DEFINE_PROP_END_OF_LIST(),
83
};
24
};
84
25
85
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
26
-static MouseTransformInfo n810_pointercal = {
86
index XXXXXXX..XXXXXXX 100644
27
+static const MouseTransformInfo n810_pointercal = {
87
--- a/hw/intc/arm_gicv3_dist.c
28
.x = 800,
88
+++ b/hw/intc/arm_gicv3_dist.c
29
.y = 480,
89
@@ -XXX,XX +XXX,XX @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
30
.a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
90
* A3V == 1 (non-zero values of Affinity level 3 supported)
31
@@ -XXX,XX +XXX,XX @@ static void n810_key_event(void *opaque, int keycode)
91
* IDbits == 0xf (we support 16-bit interrupt identifiers)
32
92
* DVIS == 0 (Direct virtual LPI injection not supported)
33
#define M    0
93
- * LPIS == 0 (LPIs not supported)
34
94
+ * LPIS == 1 (LPIs are supported if affinity routing is enabled)
35
-static int n810_keys[0x80] = {
95
+ * num_LPIs == 0b00000 (bits [15:11],Number of LPIs as indicated
36
+static const int n810_keys[0x80] = {
96
+ * by GICD_TYPER.IDbits)
37
[0x01] = 16,    /* Q */
97
* MBIS == 0 (message-based SPIs not supported)
38
[0x02] = 37,    /* K */
98
* SecurityExtn == 1 if security extns supported
39
[0x03] = 24,    /* O */
99
* CPUNumber == 0 since for us ARE is always 1
40
@@ -XXX,XX +XXX,XX @@ static void n8x0_usb_setup(struct n800_s *s)
100
@@ -XXX,XX +XXX,XX @@ static bool gicd_readl(GICv3State *s, hwaddr offset,
41
/* Setup done before the main bootloader starts by some early setup code
101
bool sec_extn = !(s->gicd_ctlr & GICD_CTLR_DS);
42
* - used when we want to run the main bootloader in emulation. This
102
43
* isn't documented. */
103
*data = (1 << 25) | (1 << 24) | (sec_extn << 10) |
44
-static uint32_t n800_pinout[104] = {
104
+ (s->lpi_enable << GICD_TYPER_LPIS_SHIFT) |
45
+static const uint32_t n800_pinout[104] = {
105
(0xf << 19) | itlinesnumber;
46
0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
106
return true;
47
0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
107
}
48
0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
108
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
49
@@ -XXX,XX +XXX,XX @@ static void n8x0_boot_init(void *opaque)
109
index XXXXXXX..XXXXXXX 100644
50
#define OMAP_TAG_CBUS        0x4e03
110
--- a/hw/intc/arm_gicv3_redist.c
51
#define OMAP_TAG_EM_ASIC_BB5    0x4e04
111
+++ b/hw/intc/arm_gicv3_redist.c
52
112
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
53
-static struct omap_gpiosw_info_s {
113
case GICR_CTLR:
54
+static const struct omap_gpiosw_info_s {
114
/* For our implementation, GICR_TYPER.DPGS is 0 and so all
55
const char *name;
115
* the DPG bits are RAZ/WI. We don't do anything asynchronously,
56
int line;
116
- * so UWP and RWP are RAZ/WI. And GICR_TYPER.LPIS is 0 (we don't
57
int type;
117
- * implement LPIs) so Enable_LPIs is RES0. So there are no writable
58
@@ -XXX,XX +XXX,XX @@ static struct omap_gpiosw_info_s {
118
- * bits for us.
59
{ NULL }
119
+ * so UWP and RWP are RAZ/WI. GICR_TYPER.LPIS is 1 (we
60
};
120
+ * implement LPIs) so Enable_LPIs is programmable.
61
121
*/
62
-static struct omap_partition_info_s {
122
+ if (cs->gicr_typer & GICR_TYPER_PLPIS) {
63
+static const struct omap_partition_info_s {
123
+ if (value & GICR_CTLR_ENABLE_LPIS) {
64
uint32_t offset;
124
+ cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
65
uint32_t size;
125
+ } else {
66
int mask;
126
+ cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
67
@@ -XXX,XX +XXX,XX @@ static struct omap_partition_info_s {
127
+ }
68
{ 0, 0, 0, NULL }
128
+ }
69
};
129
return MEMTX_OK;
70
130
case GICR_STATUSR:
71
-static uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
131
/* RAZ/WI for our implementation */
72
+static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
73
74
static int n8x0_atag_setup(void *p, int model)
75
{
76
uint8_t *b;
77
uint16_t *w;
78
uint32_t *l;
79
- struct omap_gpiosw_info_s *gpiosw;
80
- struct omap_partition_info_s *partition;
81
+ const struct omap_gpiosw_info_s *gpiosw;
82
+ const struct omap_partition_info_s *partition;
83
const char *tag;
84
85
w = p;
132
--
86
--
133
2.20.1
87
2.25.1
134
88
135
89
diff view generated by jsdifflib
1
From: Shashi Mallela <shashi.mallela@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Added register definitions relevant to ITS,implemented overall
3
Silent when compiling with -Wextra:
4
ITS device framework with stubs for ITS control and translater
5
regions read/write,extended ITS common to handle mmio init between
6
existing kvm device and newer qemu device.
7
4
8
Signed-off-by: Shashi Mallela <shashi.mallela@linaro.org>
5
../hw/arm/nseries.c:1081:12: warning: missing field 'line' initializer [-Wmissing-field-initializers]
6
{ NULL }
7
^
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20221220142520.24094-4-philmd@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Neil Armstrong <narmstrong@baylibre.com>
12
Message-id: 20210910143951.92242-2-shashi.mallela@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
hw/intc/gicv3_internal.h | 96 +++++++++-
14
hw/arm/nseries.c | 10 ++++------
16
include/hw/intc/arm_gicv3_its_common.h | 9 +-
15
1 file changed, 4 insertions(+), 6 deletions(-)
17
hw/intc/arm_gicv3_its.c | 241 +++++++++++++++++++++++++
18
hw/intc/arm_gicv3_its_common.c | 7 +-
19
hw/intc/arm_gicv3_its_kvm.c | 2 +-
20
hw/intc/meson.build | 1 +
21
6 files changed, 342 insertions(+), 14 deletions(-)
22
create mode 100644 hw/intc/arm_gicv3_its.c
23
16
24
diff --git a/hw/intc/gicv3_internal.h b/hw/intc/gicv3_internal.h
17
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/intc/gicv3_internal.h
19
--- a/hw/arm/nseries.c
27
+++ b/hw/intc/gicv3_internal.h
20
+++ b/hw/arm/nseries.c
28
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
29
#ifndef QEMU_ARM_GICV3_INTERNAL_H
22
"headphone", N8X0_HEADPHONE_GPIO,
30
#define QEMU_ARM_GICV3_INTERNAL_H
23
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
31
24
},
32
+#include "hw/registerfields.h"
25
- { NULL }
33
#include "hw/intc/arm_gicv3_common.h"
26
+ { /* end of list */ }
34
27
}, n810_gpiosw_info[] = {
35
/* Distributor registers, as offsets from the distributor base address */
28
{
36
@@ -XXX,XX +XXX,XX @@
29
"gps_reset", N810_GPS_RESET_GPIO,
37
#define GICD_CTLR_E1NWF (1U << 7)
30
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
38
#define GICD_CTLR_RWP (1U << 31)
31
"slide", N810_SLIDE_GPIO,
39
32
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
40
+/* 16 bits EventId */
33
},
41
+#define GICD_TYPER_IDBITS 0xf
34
- { NULL }
42
+
35
+ { /* end of list */ }
43
/*
44
* Redistributor frame offsets from RD_base
45
*/
46
@@ -XXX,XX +XXX,XX @@
47
#define GICR_WAKER_ProcessorSleep (1U << 1)
48
#define GICR_WAKER_ChildrenAsleep (1U << 2)
49
50
-#define GICR_PROPBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
51
-#define GICR_PROPBASER_ADDR_MASK (0xfffffffffULL << 12)
52
-#define GICR_PROPBASER_SHAREABILITY_MASK (3U << 10)
53
-#define GICR_PROPBASER_CACHEABILITY_MASK (7U << 7)
54
-#define GICR_PROPBASER_IDBITS_MASK (0x1f)
55
+FIELD(GICR_PROPBASER, IDBITS, 0, 5)
56
+FIELD(GICR_PROPBASER, INNERCACHE, 7, 3)
57
+FIELD(GICR_PROPBASER, SHAREABILITY, 10, 2)
58
+FIELD(GICR_PROPBASER, PHYADDR, 12, 40)
59
+FIELD(GICR_PROPBASER, OUTERCACHE, 56, 3)
60
61
-#define GICR_PENDBASER_PTZ (1ULL << 62)
62
-#define GICR_PENDBASER_OUTER_CACHEABILITY_MASK (7ULL << 56)
63
-#define GICR_PENDBASER_ADDR_MASK (0xffffffffULL << 16)
64
-#define GICR_PENDBASER_SHAREABILITY_MASK (3U << 10)
65
-#define GICR_PENDBASER_CACHEABILITY_MASK (7U << 7)
66
+FIELD(GICR_PENDBASER, INNERCACHE, 7, 3)
67
+FIELD(GICR_PENDBASER, SHAREABILITY, 10, 2)
68
+FIELD(GICR_PENDBASER, PHYADDR, 16, 36)
69
+FIELD(GICR_PENDBASER, OUTERCACHE, 56, 3)
70
+FIELD(GICR_PENDBASER, PTZ, 62, 1)
71
72
#define ICC_CTLR_EL1_CBPR (1U << 0)
73
#define ICC_CTLR_EL1_EOIMODE (1U << 1)
74
@@ -XXX,XX +XXX,XX @@
75
#define ICH_VTR_EL2_PREBITS_SHIFT 26
76
#define ICH_VTR_EL2_PRIBITS_SHIFT 29
77
78
+/* ITS Registers */
79
+
80
+FIELD(GITS_BASER, SIZE, 0, 8)
81
+FIELD(GITS_BASER, PAGESIZE, 8, 2)
82
+FIELD(GITS_BASER, SHAREABILITY, 10, 2)
83
+FIELD(GITS_BASER, PHYADDR, 12, 36)
84
+FIELD(GITS_BASER, PHYADDRL_64K, 16, 32)
85
+FIELD(GITS_BASER, PHYADDRH_64K, 12, 4)
86
+FIELD(GITS_BASER, ENTRYSIZE, 48, 5)
87
+FIELD(GITS_BASER, OUTERCACHE, 53, 3)
88
+FIELD(GITS_BASER, TYPE, 56, 3)
89
+FIELD(GITS_BASER, INNERCACHE, 59, 3)
90
+FIELD(GITS_BASER, INDIRECT, 62, 1)
91
+FIELD(GITS_BASER, VALID, 63, 1)
92
+
93
+FIELD(GITS_CTLR, QUIESCENT, 31, 1)
94
+
95
+FIELD(GITS_TYPER, PHYSICAL, 0, 1)
96
+FIELD(GITS_TYPER, ITT_ENTRY_SIZE, 4, 4)
97
+FIELD(GITS_TYPER, IDBITS, 8, 5)
98
+FIELD(GITS_TYPER, DEVBITS, 13, 5)
99
+FIELD(GITS_TYPER, SEIS, 18, 1)
100
+FIELD(GITS_TYPER, PTA, 19, 1)
101
+FIELD(GITS_TYPER, CIDBITS, 32, 4)
102
+FIELD(GITS_TYPER, CIL, 36, 1)
103
+
104
+#define GITS_BASER_PAGESIZE_4K 0
105
+#define GITS_BASER_PAGESIZE_16K 1
106
+#define GITS_BASER_PAGESIZE_64K 2
107
+
108
+#define GITS_BASER_TYPE_DEVICE 1ULL
109
+#define GITS_BASER_TYPE_COLLECTION 4ULL
110
+
111
+/**
112
+ * Default features advertised by this version of ITS
113
+ */
114
+/* Physical LPIs supported */
115
+#define GITS_TYPE_PHYSICAL (1U << 0)
116
+
117
+/*
118
+ * 12 bytes Interrupt translation Table Entry size
119
+ * as per Table 5.3 in GICv3 spec
120
+ * ITE Lower 8 Bytes
121
+ * Bits: | 49 ... 26 | 25 ... 2 | 1 | 0 |
122
+ * Values: | 1023 | IntNum | IntType | Valid |
123
+ * ITE Higher 4 Bytes
124
+ * Bits: | 31 ... 16 | 15 ...0 |
125
+ * Values: | vPEID | ICID |
126
+ */
127
+#define ITS_ITT_ENTRY_SIZE 0xC
128
+
129
+/* 16 bits EventId */
130
+#define ITS_IDBITS GICD_TYPER_IDBITS
131
+
132
+/* 16 bits DeviceId */
133
+#define ITS_DEVBITS 0xF
134
+
135
+/* 16 bits CollectionId */
136
+#define ITS_CIDBITS 0xF
137
+
138
+/*
139
+ * 8 bytes Device Table Entry size
140
+ * Valid = 1 bit,ITTAddr = 44 bits,Size = 5 bits
141
+ */
142
+#define GITS_DTE_SIZE (0x8ULL)
143
+
144
+/*
145
+ * 8 bytes Collection Table Entry size
146
+ * Valid = 1 bit,RDBase = 36 bits(considering max RDBASE)
147
+ */
148
+#define GITS_CTE_SIZE (0x8ULL)
149
+
150
/* Special interrupt IDs */
151
#define INTID_SECURE 1020
152
#define INTID_NONSECURE 1021
153
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
154
index XXXXXXX..XXXXXXX 100644
155
--- a/include/hw/intc/arm_gicv3_its_common.h
156
+++ b/include/hw/intc/arm_gicv3_its_common.h
157
@@ -XXX,XX +XXX,XX @@
158
#include "hw/intc/arm_gicv3_common.h"
159
#include "qom/object.h"
160
161
+#define TYPE_ARM_GICV3_ITS "arm-gicv3-its"
162
+
163
#define ITS_CONTROL_SIZE 0x10000
164
#define ITS_TRANS_SIZE 0x10000
165
#define ITS_SIZE (ITS_CONTROL_SIZE + ITS_TRANS_SIZE)
166
167
#define GITS_CTLR 0x0
168
#define GITS_IIDR 0x4
169
+#define GITS_TYPER 0x8
170
#define GITS_CBASER 0x80
171
#define GITS_CWRITER 0x88
172
#define GITS_CREADR 0x90
173
#define GITS_BASER 0x100
174
175
+#define GITS_TRANSLATER 0x0040
176
+
177
struct GICv3ITSState {
178
SysBusDevice parent_obj;
179
180
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
181
/* Registers */
182
uint32_t ctlr;
183
uint32_t iidr;
184
+ uint64_t typer;
185
uint64_t cbaser;
186
uint64_t cwriter;
187
uint64_t creadr;
188
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
189
190
typedef struct GICv3ITSState GICv3ITSState;
191
192
-void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops);
193
+void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
194
+ const MemoryRegionOps *tops);
195
196
#define TYPE_ARM_GICV3_ITS_COMMON "arm-gicv3-its-common"
197
typedef struct GICv3ITSCommonClass GICv3ITSCommonClass;
198
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
199
new file mode 100644
200
index XXXXXXX..XXXXXXX
201
--- /dev/null
202
+++ b/hw/intc/arm_gicv3_its.c
203
@@ -XXX,XX +XXX,XX @@
204
+/*
205
+ * ITS emulation for a GICv3-based system
206
+ *
207
+ * Copyright Linaro.org 2021
208
+ *
209
+ * Authors:
210
+ * Shashi Mallela <shashi.mallela@linaro.org>
211
+ *
212
+ * This work is licensed under the terms of the GNU GPL, version 2 or (at your
213
+ * option) any later version. See the COPYING file in the top-level directory.
214
+ *
215
+ */
216
+
217
+#include "qemu/osdep.h"
218
+#include "qemu/log.h"
219
+#include "hw/qdev-properties.h"
220
+#include "hw/intc/arm_gicv3_its_common.h"
221
+#include "gicv3_internal.h"
222
+#include "qom/object.h"
223
+#include "qapi/error.h"
224
+
225
+typedef struct GICv3ITSClass GICv3ITSClass;
226
+/* This is reusing the GICv3ITSState typedef from ARM_GICV3_ITS_COMMON */
227
+DECLARE_OBJ_CHECKERS(GICv3ITSState, GICv3ITSClass,
228
+ ARM_GICV3_ITS, TYPE_ARM_GICV3_ITS)
229
+
230
+struct GICv3ITSClass {
231
+ GICv3ITSCommonClass parent_class;
232
+ void (*parent_reset)(DeviceState *dev);
233
+};
234
+
235
+static MemTxResult gicv3_its_translation_write(void *opaque, hwaddr offset,
236
+ uint64_t data, unsigned size,
237
+ MemTxAttrs attrs)
238
+{
239
+ return MEMTX_OK;
240
+}
241
+
242
+static bool its_writel(GICv3ITSState *s, hwaddr offset,
243
+ uint64_t value, MemTxAttrs attrs)
244
+{
245
+ bool result = true;
246
+
247
+ return result;
248
+}
249
+
250
+static bool its_readl(GICv3ITSState *s, hwaddr offset,
251
+ uint64_t *data, MemTxAttrs attrs)
252
+{
253
+ bool result = true;
254
+
255
+ return result;
256
+}
257
+
258
+static bool its_writell(GICv3ITSState *s, hwaddr offset,
259
+ uint64_t value, MemTxAttrs attrs)
260
+{
261
+ bool result = true;
262
+
263
+ return result;
264
+}
265
+
266
+static bool its_readll(GICv3ITSState *s, hwaddr offset,
267
+ uint64_t *data, MemTxAttrs attrs)
268
+{
269
+ bool result = true;
270
+
271
+ return result;
272
+}
273
+
274
+static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
275
+ unsigned size, MemTxAttrs attrs)
276
+{
277
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
278
+ bool result;
279
+
280
+ switch (size) {
281
+ case 4:
282
+ result = its_readl(s, offset, data, attrs);
283
+ break;
284
+ case 8:
285
+ result = its_readll(s, offset, data, attrs);
286
+ break;
287
+ default:
288
+ result = false;
289
+ break;
290
+ }
291
+
292
+ if (!result) {
293
+ qemu_log_mask(LOG_GUEST_ERROR,
294
+ "%s: invalid guest read at offset " TARGET_FMT_plx
295
+ "size %u\n", __func__, offset, size);
296
+ /*
297
+ * The spec requires that reserved registers are RAZ/WI;
298
+ * so use false returns from leaf functions as a way to
299
+ * trigger the guest-error logging but don't return it to
300
+ * the caller, or we'll cause a spurious guest data abort.
301
+ */
302
+ *data = 0;
303
+ }
304
+ return MEMTX_OK;
305
+}
306
+
307
+static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
308
+ unsigned size, MemTxAttrs attrs)
309
+{
310
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
311
+ bool result;
312
+
313
+ switch (size) {
314
+ case 4:
315
+ result = its_writel(s, offset, data, attrs);
316
+ break;
317
+ case 8:
318
+ result = its_writell(s, offset, data, attrs);
319
+ break;
320
+ default:
321
+ result = false;
322
+ break;
323
+ }
324
+
325
+ if (!result) {
326
+ qemu_log_mask(LOG_GUEST_ERROR,
327
+ "%s: invalid guest write at offset " TARGET_FMT_plx
328
+ "size %u\n", __func__, offset, size);
329
+ /*
330
+ * The spec requires that reserved registers are RAZ/WI;
331
+ * so use false returns from leaf functions as a way to
332
+ * trigger the guest-error logging but don't return it to
333
+ * the caller, or we'll cause a spurious guest data abort.
334
+ */
335
+ }
336
+ return MEMTX_OK;
337
+}
338
+
339
+static const MemoryRegionOps gicv3_its_control_ops = {
340
+ .read_with_attrs = gicv3_its_read,
341
+ .write_with_attrs = gicv3_its_write,
342
+ .valid.min_access_size = 4,
343
+ .valid.max_access_size = 8,
344
+ .impl.min_access_size = 4,
345
+ .impl.max_access_size = 8,
346
+ .endianness = DEVICE_NATIVE_ENDIAN,
347
+};
348
+
349
+static const MemoryRegionOps gicv3_its_translation_ops = {
350
+ .write_with_attrs = gicv3_its_translation_write,
351
+ .valid.min_access_size = 2,
352
+ .valid.max_access_size = 4,
353
+ .impl.min_access_size = 2,
354
+ .impl.max_access_size = 4,
355
+ .endianness = DEVICE_NATIVE_ENDIAN,
356
+};
357
+
358
+static void gicv3_arm_its_realize(DeviceState *dev, Error **errp)
359
+{
360
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
361
+ int i;
362
+
363
+ for (i = 0; i < s->gicv3->num_cpu; i++) {
364
+ if (!(s->gicv3->cpu[i].gicr_typer & GICR_TYPER_PLPIS)) {
365
+ error_setg(errp, "Physical LPI not supported by CPU %d", i);
366
+ return;
367
+ }
368
+ }
369
+
370
+ gicv3_its_init_mmio(s, &gicv3_its_control_ops, &gicv3_its_translation_ops);
371
+
372
+ /* set the ITS default features supported */
373
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, PHYSICAL,
374
+ GITS_TYPE_PHYSICAL);
375
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, ITT_ENTRY_SIZE,
376
+ ITS_ITT_ENTRY_SIZE - 1);
377
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, IDBITS, ITS_IDBITS);
378
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, DEVBITS, ITS_DEVBITS);
379
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIL, 1);
380
+ s->typer = FIELD_DP64(s->typer, GITS_TYPER, CIDBITS, ITS_CIDBITS);
381
+}
382
+
383
+static void gicv3_its_reset(DeviceState *dev)
384
+{
385
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
386
+ GICv3ITSClass *c = ARM_GICV3_ITS_GET_CLASS(s);
387
+
388
+ c->parent_reset(dev);
389
+
390
+ /* Quiescent bit reset to 1 */
391
+ s->ctlr = FIELD_DP32(s->ctlr, GITS_CTLR, QUIESCENT, 1);
392
+
393
+ /*
394
+ * setting GITS_BASER0.Type = 0b001 (Device)
395
+ * GITS_BASER1.Type = 0b100 (Collection Table)
396
+ * GITS_BASER<n>.Type,where n = 3 to 7 are 0b00 (Unimplemented)
397
+ * GITS_BASER<0,1>.Page_Size = 64KB
398
+ * and default translation table entry size to 16 bytes
399
+ */
400
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, TYPE,
401
+ GITS_BASER_TYPE_DEVICE);
402
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, PAGESIZE,
403
+ GITS_BASER_PAGESIZE_64K);
404
+ s->baser[0] = FIELD_DP64(s->baser[0], GITS_BASER, ENTRYSIZE,
405
+ GITS_DTE_SIZE - 1);
406
+
407
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, TYPE,
408
+ GITS_BASER_TYPE_COLLECTION);
409
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, PAGESIZE,
410
+ GITS_BASER_PAGESIZE_64K);
411
+ s->baser[1] = FIELD_DP64(s->baser[1], GITS_BASER, ENTRYSIZE,
412
+ GITS_CTE_SIZE - 1);
413
+}
414
+
415
+static Property gicv3_its_props[] = {
416
+ DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "arm-gicv3",
417
+ GICv3State *),
418
+ DEFINE_PROP_END_OF_LIST(),
419
+};
420
+
421
+static void gicv3_its_class_init(ObjectClass *klass, void *data)
422
+{
423
+ DeviceClass *dc = DEVICE_CLASS(klass);
424
+ GICv3ITSClass *ic = ARM_GICV3_ITS_CLASS(klass);
425
+
426
+ dc->realize = gicv3_arm_its_realize;
427
+ device_class_set_props(dc, gicv3_its_props);
428
+ device_class_set_parent_reset(dc, gicv3_its_reset, &ic->parent_reset);
429
+}
430
+
431
+static const TypeInfo gicv3_its_info = {
432
+ .name = TYPE_ARM_GICV3_ITS,
433
+ .parent = TYPE_ARM_GICV3_ITS_COMMON,
434
+ .instance_size = sizeof(GICv3ITSState),
435
+ .class_init = gicv3_its_class_init,
436
+ .class_size = sizeof(GICv3ITSClass),
437
+};
438
+
439
+static void gicv3_its_register_types(void)
440
+{
441
+ type_register_static(&gicv3_its_info);
442
+}
443
+
444
+type_init(gicv3_its_register_types)
445
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
446
index XXXXXXX..XXXXXXX 100644
447
--- a/hw/intc/arm_gicv3_its_common.c
448
+++ b/hw/intc/arm_gicv3_its_common.c
449
@@ -XXX,XX +XXX,XX @@ static int gicv3_its_post_load(void *opaque, int version_id)
450
451
static const VMStateDescription vmstate_its = {
452
.name = "arm_gicv3_its",
453
+ .version_id = 1,
454
+ .minimum_version_id = 1,
455
.pre_save = gicv3_its_pre_save,
456
.post_load = gicv3_its_post_load,
457
.priority = MIG_PRI_GICV3_ITS,
458
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gicv3_its_trans_ops = {
459
.endianness = DEVICE_NATIVE_ENDIAN,
460
};
36
};
461
37
462
-void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops)
38
static const struct omap_partition_info_s {
463
+void gicv3_its_init_mmio(GICv3ITSState *s, const MemoryRegionOps *ops,
39
@@ -XXX,XX +XXX,XX @@ static const struct omap_partition_info_s {
464
+ const MemoryRegionOps *tops)
40
{ 0x00080000, 0x00200000, 0x0, "kernel" },
465
{
41
{ 0x00280000, 0x00200000, 0x3, "initfs" },
466
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
42
{ 0x00480000, 0x0fb80000, 0x3, "rootfs" },
467
43
-
468
memory_region_init_io(&s->iomem_its_cntrl, OBJECT(s), ops, s,
44
- { 0, 0, 0, NULL }
469
"control", ITS_CONTROL_SIZE);
45
+ { /* end of list */ }
470
memory_region_init_io(&s->iomem_its_translation, OBJECT(s),
46
}, n810_part_info[] = {
471
- &gicv3_its_trans_ops, s,
47
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
472
+ tops ? tops : &gicv3_its_trans_ops, s,
48
{ 0x00020000, 0x00060000, 0x0, "config" },
473
"translation", ITS_TRANS_SIZE);
49
{ 0x00080000, 0x00220000, 0x0, "kernel" },
474
50
{ 0x002a0000, 0x00400000, 0x0, "initfs" },
475
/* Our two regions are always adjacent, therefore we now combine them
51
{ 0x006a0000, 0x0f960000, 0x0, "rootfs" },
476
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
52
-
477
index XXXXXXX..XXXXXXX 100644
53
- { 0, 0, 0, NULL }
478
--- a/hw/intc/arm_gicv3_its_kvm.c
54
+ { /* end of list */ }
479
+++ b/hw/intc/arm_gicv3_its_kvm.c
55
};
480
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
56
481
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
57
static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
482
KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd, 0);
483
484
- gicv3_its_init_mmio(s, NULL);
485
+ gicv3_its_init_mmio(s, NULL, NULL);
486
487
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
488
GITS_CTLR)) {
489
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
490
index XXXXXXX..XXXXXXX 100644
491
--- a/hw/intc/meson.build
492
+++ b/hw/intc/meson.build
493
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_ARM_GIC', if_true: files(
494
'arm_gicv3_dist.c',
495
'arm_gicv3_its_common.c',
496
'arm_gicv3_redist.c',
497
+ 'arm_gicv3_its.c',
498
))
499
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_pic.c'))
500
softmmu_ss.add(when: 'CONFIG_HEATHROW_PIC', if_true: files('heathrow_pic.c'))
501
--
58
--
502
2.20.1
59
2.25.1
503
60
504
61
diff view generated by jsdifflib
New patch
1
1
From: Zhuojia Shen <chaosdefinition@hotmail.com>
2
3
In CPUID registers exposed to userspace, some registers were missing
4
and some fields were not exposed. This patch aligns exposed ID
5
registers and their fields with what the upstream kernel currently
6
exposes.
7
8
Specifically, the following new ID registers/fields are exposed to
9
userspace:
10
11
ID_AA64PFR1_EL1.BT: bits 3-0
12
ID_AA64PFR1_EL1.MTE: bits 11-8
13
ID_AA64PFR1_EL1.SME: bits 27-24
14
15
ID_AA64ZFR0_EL1.SVEver: bits 3-0
16
ID_AA64ZFR0_EL1.AES: bits 7-4
17
ID_AA64ZFR0_EL1.BitPerm: bits 19-16
18
ID_AA64ZFR0_EL1.BF16: bits 23-20
19
ID_AA64ZFR0_EL1.SHA3: bits 35-32
20
ID_AA64ZFR0_EL1.SM4: bits 43-40
21
ID_AA64ZFR0_EL1.I8MM: bits 47-44
22
ID_AA64ZFR0_EL1.F32MM: bits 55-52
23
ID_AA64ZFR0_EL1.F64MM: bits 59-56
24
25
ID_AA64SMFR0_EL1.F32F32: bit 32
26
ID_AA64SMFR0_EL1.B16F32: bit 34
27
ID_AA64SMFR0_EL1.F16F32: bit 35
28
ID_AA64SMFR0_EL1.I8I32: bits 39-36
29
ID_AA64SMFR0_EL1.F64F64: bit 48
30
ID_AA64SMFR0_EL1.I16I64: bits 55-52
31
ID_AA64SMFR0_EL1.FA64: bit 63
32
33
ID_AA64MMFR0_EL1.ECV: bits 63-60
34
35
ID_AA64MMFR1_EL1.AFP: bits 47-44
36
37
ID_AA64MMFR2_EL1.AT: bits 35-32
38
39
ID_AA64ISAR0_EL1.RNDR: bits 63-60
40
41
ID_AA64ISAR1_EL1.FRINTTS: bits 35-32
42
ID_AA64ISAR1_EL1.BF16: bits 47-44
43
ID_AA64ISAR1_EL1.DGH: bits 51-48
44
ID_AA64ISAR1_EL1.I8MM: bits 55-52
45
46
ID_AA64ISAR2_EL1.WFxT: bits 3-0
47
ID_AA64ISAR2_EL1.RPRES: bits 7-4
48
ID_AA64ISAR2_EL1.GPA3: bits 11-8
49
ID_AA64ISAR2_EL1.APA3: bits 15-12
50
51
The code is also refactored to use symbolic names for ID register fields
52
for better readability and maintainability.
53
54
The test case in tests/tcg/aarch64/sysregs.c is also updated to match
55
the intended behavior.
56
57
Signed-off-by: Zhuojia Shen <chaosdefinition@hotmail.com>
58
Message-id: DS7PR12MB6309FB585E10772928F14271ACE79@DS7PR12MB6309.namprd12.prod.outlook.com
59
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
60
[PMM: use Sn_n_Cn_Cn_n syntax to work with older assemblers
61
that don't recognize id_aa64isar2_el1 and id_aa64mmfr2_el1]
62
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
63
---
64
target/arm/helper.c | 96 +++++++++++++++++++++++++------
65
tests/tcg/aarch64/sysregs.c | 24 ++++++--
66
tests/tcg/aarch64/Makefile.target | 7 ++-
67
3 files changed, 103 insertions(+), 24 deletions(-)
68
69
diff --git a/target/arm/helper.c b/target/arm/helper.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/helper.c
72
+++ b/target/arm/helper.c
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
74
#ifdef CONFIG_USER_ONLY
75
static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
76
{ .name = "ID_AA64PFR0_EL1",
77
- .exported_bits = 0x000f000f00ff0000,
78
- .fixed_bits = 0x0000000000000011 },
79
+ .exported_bits = R_ID_AA64PFR0_FP_MASK |
80
+ R_ID_AA64PFR0_ADVSIMD_MASK |
81
+ R_ID_AA64PFR0_SVE_MASK |
82
+ R_ID_AA64PFR0_DIT_MASK,
83
+ .fixed_bits = (0x1u << R_ID_AA64PFR0_EL0_SHIFT) |
84
+ (0x1u << R_ID_AA64PFR0_EL1_SHIFT) },
85
{ .name = "ID_AA64PFR1_EL1",
86
- .exported_bits = 0x00000000000000f0 },
87
+ .exported_bits = R_ID_AA64PFR1_BT_MASK |
88
+ R_ID_AA64PFR1_SSBS_MASK |
89
+ R_ID_AA64PFR1_MTE_MASK |
90
+ R_ID_AA64PFR1_SME_MASK },
91
{ .name = "ID_AA64PFR*_EL1_RESERVED",
92
- .is_glob = true },
93
- { .name = "ID_AA64ZFR0_EL1" },
94
+ .is_glob = true },
95
+ { .name = "ID_AA64ZFR0_EL1",
96
+ .exported_bits = R_ID_AA64ZFR0_SVEVER_MASK |
97
+ R_ID_AA64ZFR0_AES_MASK |
98
+ R_ID_AA64ZFR0_BITPERM_MASK |
99
+ R_ID_AA64ZFR0_BFLOAT16_MASK |
100
+ R_ID_AA64ZFR0_SHA3_MASK |
101
+ R_ID_AA64ZFR0_SM4_MASK |
102
+ R_ID_AA64ZFR0_I8MM_MASK |
103
+ R_ID_AA64ZFR0_F32MM_MASK |
104
+ R_ID_AA64ZFR0_F64MM_MASK },
105
+ { .name = "ID_AA64SMFR0_EL1",
106
+ .exported_bits = R_ID_AA64SMFR0_F32F32_MASK |
107
+ R_ID_AA64SMFR0_B16F32_MASK |
108
+ R_ID_AA64SMFR0_F16F32_MASK |
109
+ R_ID_AA64SMFR0_I8I32_MASK |
110
+ R_ID_AA64SMFR0_F64F64_MASK |
111
+ R_ID_AA64SMFR0_I16I64_MASK |
112
+ R_ID_AA64SMFR0_FA64_MASK },
113
{ .name = "ID_AA64MMFR0_EL1",
114
- .fixed_bits = 0x00000000ff000000 },
115
- { .name = "ID_AA64MMFR1_EL1" },
116
+ .exported_bits = R_ID_AA64MMFR0_ECV_MASK,
117
+ .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
118
+ (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) },
119
+ { .name = "ID_AA64MMFR1_EL1",
120
+ .exported_bits = R_ID_AA64MMFR1_AFP_MASK },
121
+ { .name = "ID_AA64MMFR2_EL1",
122
+ .exported_bits = R_ID_AA64MMFR2_AT_MASK },
123
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
124
- .is_glob = true },
125
+ .is_glob = true },
126
{ .name = "ID_AA64DFR0_EL1",
127
- .fixed_bits = 0x0000000000000006 },
128
- { .name = "ID_AA64DFR1_EL1" },
129
+ .fixed_bits = (0x6u << R_ID_AA64DFR0_DEBUGVER_SHIFT) },
130
+ { .name = "ID_AA64DFR1_EL1" },
131
{ .name = "ID_AA64DFR*_EL1_RESERVED",
132
- .is_glob = true },
133
+ .is_glob = true },
134
{ .name = "ID_AA64AFR*",
135
- .is_glob = true },
136
+ .is_glob = true },
137
{ .name = "ID_AA64ISAR0_EL1",
138
- .exported_bits = 0x00fffffff0fffff0 },
139
+ .exported_bits = R_ID_AA64ISAR0_AES_MASK |
140
+ R_ID_AA64ISAR0_SHA1_MASK |
141
+ R_ID_AA64ISAR0_SHA2_MASK |
142
+ R_ID_AA64ISAR0_CRC32_MASK |
143
+ R_ID_AA64ISAR0_ATOMIC_MASK |
144
+ R_ID_AA64ISAR0_RDM_MASK |
145
+ R_ID_AA64ISAR0_SHA3_MASK |
146
+ R_ID_AA64ISAR0_SM3_MASK |
147
+ R_ID_AA64ISAR0_SM4_MASK |
148
+ R_ID_AA64ISAR0_DP_MASK |
149
+ R_ID_AA64ISAR0_FHM_MASK |
150
+ R_ID_AA64ISAR0_TS_MASK |
151
+ R_ID_AA64ISAR0_RNDR_MASK },
152
{ .name = "ID_AA64ISAR1_EL1",
153
- .exported_bits = 0x000000f0ffffffff },
154
+ .exported_bits = R_ID_AA64ISAR1_DPB_MASK |
155
+ R_ID_AA64ISAR1_APA_MASK |
156
+ R_ID_AA64ISAR1_API_MASK |
157
+ R_ID_AA64ISAR1_JSCVT_MASK |
158
+ R_ID_AA64ISAR1_FCMA_MASK |
159
+ R_ID_AA64ISAR1_LRCPC_MASK |
160
+ R_ID_AA64ISAR1_GPA_MASK |
161
+ R_ID_AA64ISAR1_GPI_MASK |
162
+ R_ID_AA64ISAR1_FRINTTS_MASK |
163
+ R_ID_AA64ISAR1_SB_MASK |
164
+ R_ID_AA64ISAR1_BF16_MASK |
165
+ R_ID_AA64ISAR1_DGH_MASK |
166
+ R_ID_AA64ISAR1_I8MM_MASK },
167
+ { .name = "ID_AA64ISAR2_EL1",
168
+ .exported_bits = R_ID_AA64ISAR2_WFXT_MASK |
169
+ R_ID_AA64ISAR2_RPRES_MASK |
170
+ R_ID_AA64ISAR2_GPA3_MASK |
171
+ R_ID_AA64ISAR2_APA3_MASK },
172
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
173
- .is_glob = true },
174
+ .is_glob = true },
175
};
176
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
177
#endif
178
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
179
#ifdef CONFIG_USER_ONLY
180
static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
181
{ .name = "MIDR_EL1",
182
- .exported_bits = 0x00000000ffffffff },
183
- { .name = "REVIDR_EL1" },
184
+ .exported_bits = R_MIDR_EL1_REVISION_MASK |
185
+ R_MIDR_EL1_PARTNUM_MASK |
186
+ R_MIDR_EL1_ARCHITECTURE_MASK |
187
+ R_MIDR_EL1_VARIANT_MASK |
188
+ R_MIDR_EL1_IMPLEMENTER_MASK },
189
+ { .name = "REVIDR_EL1" },
190
};
191
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
192
#endif
193
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/tcg/aarch64/sysregs.c
196
+++ b/tests/tcg/aarch64/sysregs.c
197
@@ -XXX,XX +XXX,XX @@
198
#define HWCAP_CPUID (1 << 11)
199
#endif
200
201
+/*
202
+ * Older assemblers don't recognize newer system register names,
203
+ * but we can still access them by the Sn_n_Cn_Cn_n syntax.
204
+ */
205
+#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
206
+#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
207
+
208
int failed_bit_count;
209
210
/* Read and print system register `id' value */
211
@@ -XXX,XX +XXX,XX @@ int main(void)
212
* minimum valid fields - for the purposes of this check allowed
213
* to have non-zero values.
214
*/
215
- get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,ffff,f0ff,fff0));
216
- get_cpu_reg_check_mask(id_aa64isar1_el1, _m(0000,00f0,ffff,ffff));
217
+ get_cpu_reg_check_mask(id_aa64isar0_el1, _m(f0ff,ffff,f0ff,fff0));
218
+ get_cpu_reg_check_mask(id_aa64isar1_el1, _m(00ff,f0ff,ffff,ffff));
219
+ get_cpu_reg_check_mask(SYS_ID_AA64ISAR2_EL1, _m(0000,0000,0000,ffff));
220
/* TGran4 & TGran64 as pegged to -1 */
221
- get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(0000,0000,ff00,0000));
222
- get_cpu_reg_check_zero(id_aa64mmfr1_el1);
223
+ get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(f000,0000,ff00,0000));
224
+ get_cpu_reg_check_mask(id_aa64mmfr1_el1, _m(0000,f000,0000,0000));
225
+ get_cpu_reg_check_mask(SYS_ID_AA64MMFR2_EL1, _m(0000,000f,0000,0000));
226
/* EL1/EL0 reported as AA64 only */
227
get_cpu_reg_check_mask(id_aa64pfr0_el1, _m(000f,000f,00ff,0011));
228
- get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0000,00f0));
229
+ get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0f00,0fff));
230
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
231
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
232
get_cpu_reg_check_zero(id_aa64dfr1_el1);
233
- get_cpu_reg_check_zero(id_aa64zfr0_el1);
234
+ get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff));
235
+#ifdef HAS_ARMV9_SME
236
+ get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000));
237
+#endif
238
239
get_cpu_reg_check_zero(id_aa64afr0_el1);
240
get_cpu_reg_check_zero(id_aa64afr1_el1);
241
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
242
index XXXXXXX..XXXXXXX 100644
243
--- a/tests/tcg/aarch64/Makefile.target
244
+++ b/tests/tcg/aarch64/Makefile.target
245
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
246
     $(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \
247
     $(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
248
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
249
-     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
250
+     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
251
+     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
252
-include config-cc.mak
253
254
# Pauth Tests
255
@@ -XXX,XX +XXX,XX @@ endif
256
ifneq ($(CROSS_CC_HAS_SVE),)
257
# System Registers Tests
258
AARCH64_TESTS += sysregs
259
+ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
260
+sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
261
+else
262
sysregs: CFLAGS+=-march=armv8.1-a+sve
263
+endif
264
265
# SVE ioctl test
266
AARCH64_TESTS += sve-ioctls
267
--
268
2.25.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This converts uart_read() and uart_write() to memop_with_attrs() ops.
3
This function is not used anywhere outside this file,
4
so we can make the function "static void".
4
5
5
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
8
Message-id: 20210901124521.30599-5-bmeng.cn@gmail.com
9
Message-id: 20221216214924.4711-2-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
hw/char/cadence_uart.c | 26 +++++++++++++++-----------
12
include/hw/arm/smmu-common.h | 3 ---
12
1 file changed, 15 insertions(+), 11 deletions(-)
13
hw/arm/smmu-common.c | 2 +-
14
2 files changed, 1 insertion(+), 4 deletions(-)
13
15
14
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/cadence_uart.c
18
--- a/include/hw/arm/smmu-common.h
17
+++ b/hw/char/cadence_uart.c
19
+++ b/include/hw/arm/smmu-common.h
18
@@ -XXX,XX +XXX,XX @@ static void uart_read_rx_fifo(CadenceUARTState *s, uint32_t *c)
20
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
19
uart_update_status(s);
21
/* Unmap the range of all the notifiers registered to any IOMMU mr */
22
void smmu_inv_notifiers_all(SMMUState *s);
23
24
-/* Unmap the range of all the notifiers registered to @mr */
25
-void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr);
26
-
27
#endif /* HW_ARM_SMMU_COMMON_H */
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/smmu-common.c
31
+++ b/hw/arm/smmu-common.c
32
@@ -XXX,XX +XXX,XX @@ static void smmu_unmap_notifier_range(IOMMUNotifier *n)
20
}
33
}
21
34
22
-static void uart_write(void *opaque, hwaddr offset,
35
/* Unmap all notifiers attached to @mr */
23
- uint64_t value, unsigned size)
36
-inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
24
+static MemTxResult uart_write(void *opaque, hwaddr offset,
37
+static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
25
+ uint64_t value, unsigned size, MemTxAttrs attrs)
26
{
38
{
27
CadenceUARTState *s = opaque;
39
IOMMUNotifier *n;
28
29
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
30
offset >>= 2;
31
if (offset >= CADENCE_UART_R_MAX) {
32
- return;
33
+ return MEMTX_DECODE_ERROR;
34
}
35
switch (offset) {
36
case R_IER: /* ier (wts imr) */
37
@@ -XXX,XX +XXX,XX @@ static void uart_write(void *opaque, hwaddr offset,
38
break;
39
}
40
uart_update_status(s);
41
+
42
+ return MEMTX_OK;
43
}
44
45
-static uint64_t uart_read(void *opaque, hwaddr offset,
46
- unsigned size)
47
+static MemTxResult uart_read(void *opaque, hwaddr offset,
48
+ uint64_t *value, unsigned size, MemTxAttrs attrs)
49
{
50
CadenceUARTState *s = opaque;
51
uint32_t c = 0;
52
53
offset >>= 2;
54
if (offset >= CADENCE_UART_R_MAX) {
55
- c = 0;
56
- } else if (offset == R_TX_RX) {
57
+ return MEMTX_DECODE_ERROR;
58
+ }
59
+ if (offset == R_TX_RX) {
60
uart_read_rx_fifo(s, &c);
61
} else {
62
- c = s->r[offset];
63
+ c = s->r[offset];
64
}
65
66
DB_PRINT(" offset:%x data:%08x\n", (unsigned)(offset << 2), (unsigned)c);
67
- return c;
68
+ *value = c;
69
+ return MEMTX_OK;
70
}
71
72
static const MemoryRegionOps uart_ops = {
73
- .read = uart_read,
74
- .write = uart_write,
75
+ .read_with_attrs = uart_read,
76
+ .write_with_attrs = uart_write,
77
.endianness = DEVICE_NATIVE_ENDIAN,
78
};
79
40
80
--
41
--
81
2.20.1
42
2.25.1
82
43
83
44
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
As of today, when booting upstream U-Boot for Xilinx Zynq, the UART
3
When using Clang ("Apple clang version 14.0.0 (clang-1400.0.29.202)")
4
does not receive anything. Debugging shows that the UART input clock
4
and building with -Wall we get:
5
frequency is zero which prevents the UART from receiving anything as
6
per the logic in uart_receive().
7
5
8
From zynq_slcr_reset_exit() comment, it intends to compute output
6
hw/arm/smmu-common.c:173:33: warning: static function 'smmu_hash_remove_by_asid_iova' is used in an inline function with external linkage [-Wstatic-in-inline]
9
clocks according to ps_clk and registers. zynq_slcr_compute_clocks()
7
hw/arm/smmu-common.h:170:1: note: use 'static' to give inline function 'smmu_iotlb_inv_iova' internal linkage
10
is called to accomplish the task, inside which device_is_in_reset()
8
void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
11
is called to actually make the attempt in vain.
9
^
10
static
12
11
13
Rework reset_hold() and reset_exit() so that in the reset exit phase,
12
None of our code base require / use inlined functions with external
14
the logic can really compute output clocks in reset_exit().
13
linkage. Some places use internal inlining in the hot path. These
14
two functions are certainly not in any hot path and don't justify
15
any inlining, so these are likely oversights rather than intentional.
15
16
16
With this change, upstream U-Boot boots properly again with:
17
Reported-by: Stefan Weil <sw@weilnetz.de>
17
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
$ qemu-system-arm -M xilinx-zynq-a9 -m 1G -display none -serial null -serial stdio \
19
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
19
-device loader,file=u-boot-dtb.bin,addr=0x4000000,cpu-num=0
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
21
Fixes: 38867cb7ec90 ("hw/misc/zynq_slcr: add clock generation for uarts")
22
Message-id: 20221216214924.4711-3-philmd@linaro.org
22
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
23
Acked-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Message-id: 20210901124521.30599-2-bmeng.cn@gmail.com
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
24
---
28
hw/misc/zynq_slcr.c | 31 ++++++++++++++++++-------------
25
hw/arm/smmu-common.c | 13 ++++++-------
29
1 file changed, 18 insertions(+), 13 deletions(-)
26
1 file changed, 6 insertions(+), 7 deletions(-)
30
27
31
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
32
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/misc/zynq_slcr.c
30
--- a/hw/arm/smmu-common.c
34
+++ b/hw/misc/zynq_slcr.c
31
+++ b/hw/arm/smmu-common.c
35
@@ -XXX,XX +XXX,XX @@ static uint64_t zynq_slcr_compute_clock(const uint64_t periods[],
32
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
36
zynq_slcr_compute_clock((plls), (state)->regs[reg], \
33
g_hash_table_insert(bs->iotlb, key, new);
37
reg ## _ ## enable_field ## _SHIFT)
38
39
+static void zynq_slcr_compute_clocks_internal(ZynqSLCRState *s, uint64_t ps_clk)
40
+{
41
+ uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
42
+ uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
43
+ uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
44
+
45
+ uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
46
+
47
+ /* compute uartX reference clocks */
48
+ clock_set(s->uart0_ref_clk,
49
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
50
+ clock_set(s->uart1_ref_clk,
51
+ ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
52
+}
53
+
54
/**
55
* Compute and set the ouputs clocks periods.
56
* But do not propagate them further. Connected clocks
57
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_compute_clocks(ZynqSLCRState *s)
58
ps_clk = 0;
59
}
60
61
- uint64_t io_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_IO_PLL_CTRL]);
62
- uint64_t arm_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_ARM_PLL_CTRL]);
63
- uint64_t ddr_pll = zynq_slcr_compute_pll(ps_clk, s->regs[R_DDR_PLL_CTRL]);
64
-
65
- uint64_t uart_mux[4] = {io_pll, io_pll, arm_pll, ddr_pll};
66
-
67
- /* compute uartX reference clocks */
68
- clock_set(s->uart0_ref_clk,
69
- ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT0));
70
- clock_set(s->uart1_ref_clk,
71
- ZYNQ_COMPUTE_CLK(s, uart_mux, R_UART_CLK_CTRL, CLKACT1));
72
+ zynq_slcr_compute_clocks_internal(s, ps_clk);
73
}
34
}
74
35
75
/**
36
-inline void smmu_iotlb_inv_all(SMMUState *s)
76
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset_hold(Object *obj)
37
+void smmu_iotlb_inv_all(SMMUState *s)
77
ZynqSLCRState *s = ZYNQ_SLCR(obj);
38
{
78
39
trace_smmu_iotlb_inv_all();
79
/* will disable all output clocks */
40
g_hash_table_remove_all(s->iotlb);
80
- zynq_slcr_compute_clocks(s);
41
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
81
+ zynq_slcr_compute_clocks_internal(s, 0);
42
((entry->iova & ~info->mask) == info->iova);
82
zynq_slcr_propagate_clocks(s);
83
}
43
}
84
44
85
@@ -XXX,XX +XXX,XX @@ static void zynq_slcr_reset_exit(Object *obj)
45
-inline void
86
ZynqSLCRState *s = ZYNQ_SLCR(obj);
46
-smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
87
47
- uint8_t tg, uint64_t num_pages, uint8_t ttl)
88
/* will compute output clocks according to ps_clk and registers */
48
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
89
- zynq_slcr_compute_clocks(s);
49
+ uint8_t tg, uint64_t num_pages, uint8_t ttl)
90
+ zynq_slcr_compute_clocks_internal(s, clock_get(s->ps_clk));
50
{
91
zynq_slcr_propagate_clocks(s);
51
/* if tg is not set we use 4KB range invalidation */
52
uint8_t granule = tg ? tg * 2 + 10 : 12;
53
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
54
&info);
92
}
55
}
93
56
57
-inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
58
+void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
59
{
60
trace_smmu_iotlb_inv_asid(asid);
61
g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
62
@@ -XXX,XX +XXX,XX @@ error:
63
*
64
* return 0 on success
65
*/
66
-inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
67
- SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
68
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
69
+ SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
70
{
71
if (!cfg->aa64) {
72
/*
94
--
73
--
95
2.20.1
74
2.25.1
96
75
97
76
diff view generated by jsdifflib
New patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
2
3
So far the GPT timers were unable to raise IRQs to the processor.
4
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/hw/arm/fsl-imx7.h | 5 +++++
10
hw/arm/fsl-imx7.c | 10 ++++++++++
11
2 files changed, 15 insertions(+)
12
13
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/arm/fsl-imx7.h
16
+++ b/include/hw/arm/fsl-imx7.h
17
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
18
FSL_IMX7_USB2_IRQ = 42,
19
FSL_IMX7_USB3_IRQ = 40,
20
21
+ FSL_IMX7_GPT1_IRQ = 55,
22
+ FSL_IMX7_GPT2_IRQ = 54,
23
+ FSL_IMX7_GPT3_IRQ = 53,
24
+ FSL_IMX7_GPT4_IRQ = 52,
25
+
26
FSL_IMX7_WDOG1_IRQ = 78,
27
FSL_IMX7_WDOG2_IRQ = 79,
28
FSL_IMX7_WDOG3_IRQ = 10,
29
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/fsl-imx7.c
32
+++ b/hw/arm/fsl-imx7.c
33
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
34
FSL_IMX7_GPT4_ADDR,
35
};
36
37
+ static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
38
+ FSL_IMX7_GPT1_IRQ,
39
+ FSL_IMX7_GPT2_IRQ,
40
+ FSL_IMX7_GPT3_IRQ,
41
+ FSL_IMX7_GPT4_IRQ,
42
+ };
43
+
44
s->gpt[i].ccm = IMX_CCM(&s->ccm);
45
sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
46
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
48
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
49
+ FSL_IMX7_GPTn_IRQ[i]));
50
}
51
52
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
53
--
54
2.25.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
It is confusing to have different exits from translation
3
CCM derived clocks will have to be added later.
4
for various conditions in separate functions.
5
4
6
Merge disas_a64_insn into its only caller. Standardize
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
on the "s" name for the DisasContext, as the code from
8
disas_a64_insn had more instances.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210821195958.41312-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
8
---
15
target/arm/translate-a64.c | 224 ++++++++++++++++++-------------------
9
hw/misc/imx7_ccm.c | 49 +++++++++++++++++++++++++++++++++++++---------
16
1 file changed, 109 insertions(+), 115 deletions(-)
10
1 file changed, 40 insertions(+), 9 deletions(-)
17
11
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
14
--- a/hw/misc/imx7_ccm.c
21
+++ b/target/arm/translate-a64.c
15
+++ b/hw/misc/imx7_ccm.c
22
@@ -XXX,XX +XXX,XX @@ static bool btype_destination_ok(uint32_t insn, bool bt, int btype)
16
@@ -XXX,XX +XXX,XX @@
23
return false;
17
#include "hw/misc/imx7_ccm.h"
24
}
18
#include "migration/vmstate.h"
25
19
26
-/* C3.1 A64 instruction index by encoding */
20
+#include "trace.h"
27
-static void disas_a64_insn(CPUARMState *env, DisasContext *s)
21
+
28
-{
22
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
29
- uint32_t insn;
23
+
30
-
24
static void imx7_analog_reset(DeviceState *dev)
31
- s->pc_curr = s->base.pc_next;
32
- insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
33
- s->insn = insn;
34
- s->base.pc_next += 4;
35
-
36
- s->fp_access_checked = false;
37
- s->sve_access_checked = false;
38
-
39
- if (s->pstate_il) {
40
- /*
41
- * Illegal execution state. This has priority over BTI
42
- * exceptions, but comes after instruction abort exceptions.
43
- */
44
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
45
- syn_illegalstate(), default_exception_el(s));
46
- return;
47
- }
48
-
49
- if (dc_isar_feature(aa64_bti, s)) {
50
- if (s->base.num_insns == 1) {
51
- /*
52
- * At the first insn of the TB, compute s->guarded_page.
53
- * We delayed computing this until successfully reading
54
- * the first insn of the TB, above. This (mostly) ensures
55
- * that the softmmu tlb entry has been populated, and the
56
- * page table GP bit is available.
57
- *
58
- * Note that we need to compute this even if btype == 0,
59
- * because this value is used for BR instructions later
60
- * where ENV is not available.
61
- */
62
- s->guarded_page = is_guarded_page(env, s);
63
-
64
- /* First insn can have btype set to non-zero. */
65
- tcg_debug_assert(s->btype >= 0);
66
-
67
- /*
68
- * Note that the Branch Target Exception has fairly high
69
- * priority -- below debugging exceptions but above most
70
- * everything else. This allows us to handle this now
71
- * instead of waiting until the insn is otherwise decoded.
72
- */
73
- if (s->btype != 0
74
- && s->guarded_page
75
- && !btype_destination_ok(insn, s->bt, s->btype)) {
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
77
- syn_btitrap(s->btype),
78
- default_exception_el(s));
79
- return;
80
- }
81
- } else {
82
- /* Not the first insn: btype must be 0. */
83
- tcg_debug_assert(s->btype == 0);
84
- }
85
- }
86
-
87
- switch (extract32(insn, 25, 4)) {
88
- case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
89
- unallocated_encoding(s);
90
- break;
91
- case 0x2:
92
- if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
93
- unallocated_encoding(s);
94
- }
95
- break;
96
- case 0x8: case 0x9: /* Data processing - immediate */
97
- disas_data_proc_imm(s, insn);
98
- break;
99
- case 0xa: case 0xb: /* Branch, exception generation and system insns */
100
- disas_b_exc_sys(s, insn);
101
- break;
102
- case 0x4:
103
- case 0x6:
104
- case 0xc:
105
- case 0xe: /* Loads and stores */
106
- disas_ldst(s, insn);
107
- break;
108
- case 0x5:
109
- case 0xd: /* Data processing - register */
110
- disas_data_proc_reg(s, insn);
111
- break;
112
- case 0x7:
113
- case 0xf: /* Data processing - SIMD and floating point */
114
- disas_data_proc_simd_fp(s, insn);
115
- break;
116
- default:
117
- assert(FALSE); /* all 15 cases should be handled above */
118
- break;
119
- }
120
-
121
- /* if we allocated any temporaries, free them here */
122
- free_tmp_a64(s);
123
-
124
- /*
125
- * After execution of most insns, btype is reset to 0.
126
- * Note that we set btype == -1 when the insn sets btype.
127
- */
128
- if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
129
- reset_btype(s);
130
- }
131
-}
132
-
133
static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
134
CPUState *cpu)
135
{
25
{
136
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
26
IMX7AnalogState *s = IMX7_ANALOG(dev);
137
27
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx7_ccm = {
138
static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
28
static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
139
{
29
{
140
- DisasContext *dc = container_of(dcbase, DisasContext, base);
30
/*
141
+ DisasContext *s = container_of(dcbase, DisasContext, base);
31
- * This function is "consumed" by GPT emulation code, however on
142
CPUARMState *env = cpu->env_ptr;
32
- * i.MX7 each GPT block can have their own clock root. This means
143
+ uint32_t insn;
33
- * that this functions needs somehow to know requester's identity
144
34
- * and the way to pass it: be it via additional IMXClk constants
145
- if (dc->ss_active && !dc->pstate_ss) {
35
- * or by adding another argument to this method needs to be
146
+ if (s->ss_active && !s->pstate_ss) {
36
- * figured out
147
/* Singlestep state is Active-pending.
37
+ * This function is "consumed" by GPT emulation code. Some clocks
148
* If we're in this state at the start of a TB then either
38
+ * have fixed frequencies and we can provide requested frequency
149
* a) we just took an exception to an EL which is being debugged
39
+ * easily. However for CCM provided clocks (like IPG) each GPT
150
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
40
+ * timer can have its own clock root.
151
* "did not step an insn" case, and so the syndrome ISV and EX
41
+ * This means we need additionnal information when calling this
152
* bits should be zero.
42
+ * function to know the requester's identity.
153
*/
43
*/
154
- assert(dc->base.num_insns == 1);
44
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
155
- gen_swstep_exception(dc, 0, 0);
45
- TYPE_IMX7_CCM, __func__);
156
- dc->base.is_jmp = DISAS_NORETURN;
46
- return 0;
157
- } else {
47
+ uint32_t freq = 0;
158
- disas_a64_insn(env, dc);
159
+ assert(s->base.num_insns == 1);
160
+ gen_swstep_exception(s, 0, 0);
161
+ s->base.is_jmp = DISAS_NORETURN;
162
+ return;
163
}
164
165
- translator_loop_temp_check(&dc->base);
166
+ s->pc_curr = s->base.pc_next;
167
+ insn = arm_ldl_code(env, s->base.pc_next, s->sctlr_b);
168
+ s->insn = insn;
169
+ s->base.pc_next += 4;
170
+
48
+
171
+ s->fp_access_checked = false;
49
+ switch (clock) {
172
+ s->sve_access_checked = false;
50
+ case CLK_NONE:
173
+
51
+ break;
174
+ if (s->pstate_il) {
52
+ case CLK_32k:
53
+ freq = CKIL_FREQ;
54
+ break;
55
+ case CLK_HIGH:
56
+ freq = CKIH_FREQ;
57
+ break;
58
+ case CLK_IPG:
59
+ case CLK_IPG_HIGH:
175
+ /*
60
+ /*
176
+ * Illegal execution state. This has priority over BTI
61
+ * For now we don't have a way to figure out the device this
177
+ * exceptions, but comes after instruction abort exceptions.
62
+ * function is called for. Until then the IPG derived clocks
63
+ * are left unimplemented.
178
+ */
64
+ */
179
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
65
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
180
+ syn_illegalstate(), default_exception_el(s));
66
+ TYPE_IMX7_CCM, __func__, clock);
181
+ return;
182
+ }
183
+
184
+ if (dc_isar_feature(aa64_bti, s)) {
185
+ if (s->base.num_insns == 1) {
186
+ /*
187
+ * At the first insn of the TB, compute s->guarded_page.
188
+ * We delayed computing this until successfully reading
189
+ * the first insn of the TB, above. This (mostly) ensures
190
+ * that the softmmu tlb entry has been populated, and the
191
+ * page table GP bit is available.
192
+ *
193
+ * Note that we need to compute this even if btype == 0,
194
+ * because this value is used for BR instructions later
195
+ * where ENV is not available.
196
+ */
197
+ s->guarded_page = is_guarded_page(env, s);
198
+
199
+ /* First insn can have btype set to non-zero. */
200
+ tcg_debug_assert(s->btype >= 0);
201
+
202
+ /*
203
+ * Note that the Branch Target Exception has fairly high
204
+ * priority -- below debugging exceptions but above most
205
+ * everything else. This allows us to handle this now
206
+ * instead of waiting until the insn is otherwise decoded.
207
+ */
208
+ if (s->btype != 0
209
+ && s->guarded_page
210
+ && !btype_destination_ok(insn, s->bt, s->btype)) {
211
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
212
+ syn_btitrap(s->btype),
213
+ default_exception_el(s));
214
+ return;
215
+ }
216
+ } else {
217
+ /* Not the first insn: btype must be 0. */
218
+ tcg_debug_assert(s->btype == 0);
219
+ }
220
+ }
221
+
222
+ switch (extract32(insn, 25, 4)) {
223
+ case 0x0: case 0x1: case 0x3: /* UNALLOCATED */
224
+ unallocated_encoding(s);
225
+ break;
226
+ case 0x2:
227
+ if (!dc_isar_feature(aa64_sve, s) || !disas_sve(s, insn)) {
228
+ unallocated_encoding(s);
229
+ }
230
+ break;
231
+ case 0x8: case 0x9: /* Data processing - immediate */
232
+ disas_data_proc_imm(s, insn);
233
+ break;
234
+ case 0xa: case 0xb: /* Branch, exception generation and system insns */
235
+ disas_b_exc_sys(s, insn);
236
+ break;
237
+ case 0x4:
238
+ case 0x6:
239
+ case 0xc:
240
+ case 0xe: /* Loads and stores */
241
+ disas_ldst(s, insn);
242
+ break;
243
+ case 0x5:
244
+ case 0xd: /* Data processing - register */
245
+ disas_data_proc_reg(s, insn);
246
+ break;
247
+ case 0x7:
248
+ case 0xf: /* Data processing - SIMD and floating point */
249
+ disas_data_proc_simd_fp(s, insn);
250
+ break;
67
+ break;
251
+ default:
68
+ default:
252
+ assert(FALSE); /* all 15 cases should be handled above */
69
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
70
+ TYPE_IMX7_CCM, __func__, clock);
253
+ break;
71
+ break;
254
+ }
72
+ }
255
+
73
+
256
+ /* if we allocated any temporaries, free them here */
74
+ trace_ccm_clock_freq(clock, freq);
257
+ free_tmp_a64(s);
258
+
75
+
259
+ /*
76
+ return freq;
260
+ * After execution of most insns, btype is reset to 0.
261
+ * Note that we set btype == -1 when the insn sets btype.
262
+ */
263
+ if (s->btype > 0 && s->base.is_jmp != DISAS_NORETURN) {
264
+ reset_btype(s);
265
+ }
266
+
267
+ translator_loop_temp_check(&s->base);
268
}
77
}
269
78
270
static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
79
static void imx7_ccm_class_init(ObjectClass *klass, void *data)
271
--
80
--
272
2.20.1
81
2.25.1
273
274
diff view generated by jsdifflib
1
By default, QEMU will allow devices to be plugged into a bus up to
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
the bus class's device count limit. If the user creates a device on
3
the command line or via the monitor and doesn't explicitly specify
4
the bus to plug it in, QEMU will plug it into the first non-full bus
5
that it finds.
6
2
7
This is fine in most cases, but some machines have multiple buses of
3
The i.MX6UL doesn't support CLK_HIGH ou CLK_HIGH_DIV clock source.
8
a given type, some of which are dedicated to on-board devices and
9
some of which have an externally exposed connector for user-pluggable
10
devices. One example is I2C buses.
11
4
12
Provide a new function qbus_mark_full() so that a machine model can
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
13
mark this kind of "internal only" bus as 'full' after it has created
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
all the devices that should be plugged into that bus. The "find a
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
non-full bus" algorithm will then skip the internal-only bus when
8
---
16
looking for a place to plug in user-created devices.
9
include/hw/timer/imx_gpt.h | 1 +
10
hw/arm/fsl-imx6ul.c | 2 +-
11
hw/misc/imx6ul_ccm.c | 6 ------
12
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
13
4 files changed, 27 insertions(+), 7 deletions(-)
17
14
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Message-id: 20210903151435.22379-2-peter.maydell@linaro.org
21
---
22
include/hw/qdev-core.h | 24 ++++++++++++++++++++++++
23
softmmu/qdev-monitor.c | 7 ++++++-
24
2 files changed, 30 insertions(+), 1 deletion(-)
25
26
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
27
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/qdev-core.h
17
--- a/include/hw/timer/imx_gpt.h
29
+++ b/include/hw/qdev-core.h
18
+++ b/include/hw/timer/imx_gpt.h
30
@@ -XXX,XX +XXX,XX @@ struct BusState {
19
@@ -XXX,XX +XXX,XX @@
31
HotplugHandler *hotplug_handler;
20
#define TYPE_IMX25_GPT "imx25.gpt"
32
int max_index;
21
#define TYPE_IMX31_GPT "imx31.gpt"
33
bool realized;
22
#define TYPE_IMX6_GPT "imx6.gpt"
34
+ bool full;
23
+#define TYPE_IMX6UL_GPT "imx6ul.gpt"
35
int num_children;
24
#define TYPE_IMX7_GPT "imx7.gpt"
25
26
#define TYPE_IMX_GPT TYPE_IMX25_GPT
27
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/fsl-imx6ul.c
30
+++ b/hw/arm/fsl-imx6ul.c
31
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
32
*/
33
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
34
snprintf(name, NAME_SIZE, "gpt%d", i);
35
- object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX7_GPT);
36
+ object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX6UL_GPT);
37
}
36
38
37
/*
39
/*
38
@@ -XXX,XX +XXX,XX @@ static inline bool qbus_is_hotpluggable(BusState *bus)
40
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
39
return bus->hotplug_handler;
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/imx6ul_ccm.c
43
+++ b/hw/misc/imx6ul_ccm.c
44
@@ -XXX,XX +XXX,XX @@ static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
45
case CLK_32k:
46
freq = CKIL_FREQ;
47
break;
48
- case CLK_HIGH:
49
- freq = CKIH_FREQ;
50
- break;
51
- case CLK_HIGH_DIV:
52
- freq = CKIH_FREQ / 8;
53
- break;
54
default:
55
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
56
TYPE_IMX6UL_CCM, __func__, clock);
57
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/timer/imx_gpt.c
60
+++ b/hw/timer/imx_gpt.c
61
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
62
CLK_HIGH, /* 111 reference clock */
63
};
64
65
+static const IMXClk imx6ul_gpt_clocks[] = {
66
+ CLK_NONE, /* 000 No clock source */
67
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
68
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
69
+ CLK_EXT, /* 011 External clock */
70
+ CLK_32k, /* 100 ipg_clk_32k */
71
+ CLK_NONE, /* 101 not defined */
72
+ CLK_NONE, /* 110 not defined */
73
+ CLK_NONE, /* 111 not defined */
74
+};
75
+
76
static const IMXClk imx7_gpt_clocks[] = {
77
CLK_NONE, /* 000 No clock source */
78
CLK_IPG, /* 001 ipg_clk, 532MHz*/
79
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
80
s->clocks = imx6_gpt_clocks;
40
}
81
}
41
82
42
+/**
83
+static void imx6ul_gpt_init(Object *obj)
43
+ * qbus_mark_full: Mark this bus as full, so no more devices can be attached
44
+ * @bus: Bus to mark as full
45
+ *
46
+ * By default, QEMU will allow devices to be plugged into a bus up
47
+ * to the bus class's device count limit. Calling this function
48
+ * marks a particular bus as full, so that no more devices can be
49
+ * plugged into it. In particular this means that the bus will not
50
+ * be considered as a candidate for plugging in devices created by
51
+ * the user on the commandline or via the monitor.
52
+ * If a machine has multiple buses of a given type, such as I2C,
53
+ * where some of those buses in the real hardware are used only for
54
+ * internal devices and some are exposed via expansion ports, you
55
+ * can use this function to mark the internal-only buses as full
56
+ * after you have created all their internal devices. Then user
57
+ * created devices will appear on the expansion-port bus where
58
+ * guest software expects them.
59
+ */
60
+static inline void qbus_mark_full(BusState *bus)
61
+{
84
+{
62
+ bus->full = true;
85
+ IMXGPTState *s = IMX_GPT(obj);
86
+
87
+ s->clocks = imx6ul_gpt_clocks;
63
+}
88
+}
64
+
89
+
65
void device_listener_register(DeviceListener *listener);
90
static void imx7_gpt_init(Object *obj)
66
void device_listener_unregister(DeviceListener *listener);
67
68
diff --git a/softmmu/qdev-monitor.c b/softmmu/qdev-monitor.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/softmmu/qdev-monitor.c
71
+++ b/softmmu/qdev-monitor.c
72
@@ -XXX,XX +XXX,XX @@ static DeviceState *qbus_find_dev(BusState *bus, char *elem)
73
74
static inline bool qbus_is_full(BusState *bus)
75
{
91
{
76
- BusClass *bus_class = BUS_GET_CLASS(bus);
92
IMXGPTState *s = IMX_GPT(obj);
77
+ BusClass *bus_class;
93
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
94
.instance_init = imx6_gpt_init,
95
};
96
97
+static const TypeInfo imx6ul_gpt_info = {
98
+ .name = TYPE_IMX6UL_GPT,
99
+ .parent = TYPE_IMX25_GPT,
100
+ .instance_init = imx6ul_gpt_init,
101
+};
78
+
102
+
79
+ if (bus->full) {
103
static const TypeInfo imx7_gpt_info = {
80
+ return true;
104
.name = TYPE_IMX7_GPT,
81
+ }
105
.parent = TYPE_IMX25_GPT,
82
+ bus_class = BUS_GET_CLASS(bus);
106
@@ -XXX,XX +XXX,XX @@ static void imx_gpt_register_types(void)
83
return bus_class->max_dev && bus->num_children >= bus_class->max_dev;
107
type_register_static(&imx25_gpt_info);
108
type_register_static(&imx31_gpt_info);
109
type_register_static(&imx6_gpt_info);
110
+ type_register_static(&imx6ul_gpt_info);
111
type_register_static(&imx7_gpt_info);
84
}
112
}
85
113
86
--
114
--
87
2.20.1
115
2.25.1
88
89
diff view generated by jsdifflib
New patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
2
3
IRQs were not associated to the various GPIO devices inside i.MX7D.
4
This patch brings the i.MX7D on par with i.MX6.
5
6
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
Message-id: 20221226101418.415170-1-jcd@tribudubois.net
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx7.h | 15 +++++++++++++++
12
hw/arm/fsl-imx7.c | 31 ++++++++++++++++++++++++++++++-
13
2 files changed, 45 insertions(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx7.h
18
+++ b/include/hw/arm/fsl-imx7.h
19
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
20
FSL_IMX7_GPT3_IRQ = 53,
21
FSL_IMX7_GPT4_IRQ = 52,
22
23
+ FSL_IMX7_GPIO1_LOW_IRQ = 64,
24
+ FSL_IMX7_GPIO1_HIGH_IRQ = 65,
25
+ FSL_IMX7_GPIO2_LOW_IRQ = 66,
26
+ FSL_IMX7_GPIO2_HIGH_IRQ = 67,
27
+ FSL_IMX7_GPIO3_LOW_IRQ = 68,
28
+ FSL_IMX7_GPIO3_HIGH_IRQ = 69,
29
+ FSL_IMX7_GPIO4_LOW_IRQ = 70,
30
+ FSL_IMX7_GPIO4_HIGH_IRQ = 71,
31
+ FSL_IMX7_GPIO5_LOW_IRQ = 72,
32
+ FSL_IMX7_GPIO5_HIGH_IRQ = 73,
33
+ FSL_IMX7_GPIO6_LOW_IRQ = 74,
34
+ FSL_IMX7_GPIO6_HIGH_IRQ = 75,
35
+ FSL_IMX7_GPIO7_LOW_IRQ = 76,
36
+ FSL_IMX7_GPIO7_HIGH_IRQ = 77,
37
+
38
FSL_IMX7_WDOG1_IRQ = 78,
39
FSL_IMX7_WDOG2_IRQ = 79,
40
FSL_IMX7_WDOG3_IRQ = 10,
41
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/fsl-imx7.c
44
+++ b/hw/arm/fsl-imx7.c
45
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
46
FSL_IMX7_GPIO7_ADDR,
47
};
48
49
+ static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
50
+ FSL_IMX7_GPIO1_LOW_IRQ,
51
+ FSL_IMX7_GPIO2_LOW_IRQ,
52
+ FSL_IMX7_GPIO3_LOW_IRQ,
53
+ FSL_IMX7_GPIO4_LOW_IRQ,
54
+ FSL_IMX7_GPIO5_LOW_IRQ,
55
+ FSL_IMX7_GPIO6_LOW_IRQ,
56
+ FSL_IMX7_GPIO7_LOW_IRQ,
57
+ };
58
+
59
+ static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
60
+ FSL_IMX7_GPIO1_HIGH_IRQ,
61
+ FSL_IMX7_GPIO2_HIGH_IRQ,
62
+ FSL_IMX7_GPIO3_HIGH_IRQ,
63
+ FSL_IMX7_GPIO4_HIGH_IRQ,
64
+ FSL_IMX7_GPIO5_HIGH_IRQ,
65
+ FSL_IMX7_GPIO6_HIGH_IRQ,
66
+ FSL_IMX7_GPIO7_HIGH_IRQ,
67
+ };
68
+
69
sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
70
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
72
+ FSL_IMX7_GPIOn_ADDR[i]);
73
+
74
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
75
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
76
+ FSL_IMX7_GPIOn_LOW_IRQ[i]));
77
+
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
79
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
80
+ FSL_IMX7_GPIOn_HIGH_IRQ[i]));
81
}
82
83
/*
84
--
85
2.25.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Stephen Longfield <slongfield@google.com>
2
2
3
We've got SW that expects FSBL (Bootlooader) to setup clocks and
3
Size is used at lines 1088/1188 for the loop, which reads the last 4
4
resets. It's quite common that users run that SW on QEMU without
4
bytes from the crc_ptr so it does need to get increased, however it
5
FSBL (FSBL typically requires the Xilinx tools installed). That's
5
shouldn't be increased before the buffer is passed to CRC computation,
6
fine, since users can stil use -device loader to enable clocks etc.
6
or the crc32 function will access uninitialized memory.
7
7
8
To help folks understand what's going, a log (guest-error) message
8
This was pointed out to me by clg@kaod.org during the code review of
9
would be helpful here. In particular with the serial port since
9
a similar patch to hw/net/ftgmac100.c
10
things will go very quiet if they get things wrong.
11
10
12
Suggested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Change-Id: Ib0464303b191af1e28abeb2f5105eb25aadb5e9b
13
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
12
Signed-off-by: Stephen Longfield <slongfield@google.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Patrick Venture <venture@google.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20221221183202.3788132-1-slongfield@google.com
16
Message-id: 20210901124521.30599-7-bmeng.cn@gmail.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
17
---
19
hw/char/cadence_uart.c | 8 ++++++++
18
hw/net/imx_fec.c | 8 ++++----
20
1 file changed, 8 insertions(+)
19
1 file changed, 4 insertions(+), 4 deletions(-)
21
20
22
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
21
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/char/cadence_uart.c
23
--- a/hw/net/imx_fec.c
25
+++ b/hw/char/cadence_uart.c
24
+++ b/hw/net/imx_fec.c
26
@@ -XXX,XX +XXX,XX @@ static int uart_can_receive(void *opaque)
25
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
27
28
/* ignore characters when unclocked or in reset */
29
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
30
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
31
+ __func__);
32
return 0;
26
return 0;
33
}
27
}
34
28
35
@@ -XXX,XX +XXX,XX @@ static void uart_event(void *opaque, QEMUChrEvent event)
29
- /* 4 bytes for the CRC. */
36
30
- size += 4;
37
/* ignore characters when unclocked or in reset */
31
crc = cpu_to_be32(crc32(~0, buf, size));
38
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
32
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
39
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
33
+ size += 4;
40
+ __func__);
34
crc_ptr = (uint8_t *) &crc;
41
return;
35
36
/* Huge frames are truncated. */
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
38
return 0;
42
}
39
}
43
40
44
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_write(void *opaque, hwaddr offset,
41
- /* 4 bytes for the CRC. */
45
42
- size += 4;
46
/* ignore access when unclocked or in reset */
43
crc = cpu_to_be32(crc32(~0, buf, size));
47
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
44
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
48
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
45
+ size += 4;
49
+ __func__);
46
crc_ptr = (uint8_t *) &crc;
50
return MEMTX_ERROR;
47
51
}
48
if (shift16) {
52
53
@@ -XXX,XX +XXX,XX @@ static MemTxResult uart_read(void *opaque, hwaddr offset,
54
55
/* ignore access when unclocked or in reset */
56
if (!clock_is_enabled(s->refclk) || device_is_in_reset(DEVICE(s))) {
57
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: uart is unclocked or in reset\n",
58
+ __func__);
59
return MEMTX_ERROR;
60
}
61
62
--
49
--
63
2.20.1
50
2.25.1
64
65
diff view generated by jsdifflib