1
A largish pull request: the big things are Richard's PAuth work
1
First arm pullreq for 7.1. The bulk of this is the qemu_split_irq
2
and Aaron's PMU emulation improvements.
2
removal.
3
4
I have enough stuff in my to-review queue that I expect to do another
5
pullreq early next week, but 31 patches is enough to not hang on to.
3
6
4
thanks
7
thanks
5
-- PMM
8
-- PMM
6
9
10
The following changes since commit 9c125d17e9402c232c46610802e5931b3639d77b:
7
11
8
The following changes since commit 681d61362d3f766a00806b89d6581869041f73cb:
12
Merge tag 'pull-tcg-20220420' of https://gitlab.com/rth7680/qemu into staging (2022-04-20 16:43:11 -0700)
9
10
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-01-17 12:48:42 +0000)
11
13
12
are available in the Git repository at:
14
are available in the Git repository at:
13
15
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190118
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220421
15
17
16
for you to fetch changes up to 2a0ed2804e2c77a1c4e255f05ab739618e05c85d:
18
for you to fetch changes up to 5b415dd61bdbf61fb4be0e9f1a7172b8bce682c6:
17
19
18
tests/libqtest: Introduce qtest_init_with_serial() (2019-01-18 14:17:38 +0000)
20
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs (2022-04-21 11:37:05 +0100)
19
21
20
----------------------------------------------------------------
22
----------------------------------------------------------------
21
target-arm queue:
23
target-arm queue:
22
* hw/char/stm32f2xx_usart: Do not update data register when device is disabled
24
* hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
23
* hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
25
* versal: Add the Cortex-R5s in the Real-Time Processing Unit (RPU) subsystem
24
* target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
26
* versal: model enough of the Clock/Reset Low-power domain (CRL) to allow control of the Cortex-R5s
25
* ftgmac100: implement the new MDIO interface on Aspeed SoC
27
* xlnx-zynqmp: Connect 4 TTC timers
26
* implement the ARMv8.3-PAuth extension
28
* exynos4210: Refactor GIC/combiner code to stop using qemu_split_irq
27
* improve emulation of the ARM PMU
29
* realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
30
* stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
31
* hw/core/irq: remove unused 'qemu_irq_split' function
32
* npcm7xx: use symbolic constants for PWRON STRAP bit fields
33
* virt: document impact of gic-version on max CPUs
28
34
29
----------------------------------------------------------------
35
----------------------------------------------------------------
30
Aaron Lindsay (13):
36
Edgar E. Iglesias (6):
31
migration: Add post_save function to VMStateDescription
37
timer: cadence_ttc: Break out header file to allow embedding
32
target/arm: Reorganize PMCCNTR accesses
38
hw/arm/xlnx-zynqmp: Connect 4 TTC timers
33
target/arm: Swap PMU values before/after migrations
39
hw/arm: versal: Create an APU CPU Cluster
34
target/arm: Filter cycle counter based on PMCCFILTR_EL0
40
hw/arm: versal: Add the Cortex-R5Fs
35
target/arm: Allow AArch32 access for PMCCFILTR
41
hw/misc: Add a model of the Xilinx Versal CRL
36
target/arm: Implement PMOVSSET
42
hw/arm: versal: Connect the CRL
37
target/arm: Define FIELDs for ID_DFR0
38
target/arm: Make PMCEID[01]_EL0 64 bit registers, add PMCEID[23]
39
target/arm: Add array for supported PMU events, generate PMCEID[01]_EL0
40
target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
41
target/arm: PMU: Add instruction and cycle events
42
target/arm: PMU: Set PMCR.N to 4
43
target/arm: Implement PMSWINC
44
43
45
Alexander Graf (1):
44
Hao Wu (2):
46
target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
45
hw/misc: Add PWRON STRAP bit fields in GCR module
46
hw/arm: Use bit fields for NPCM7XX PWRON STRAPs
47
47
48
Cédric Le Goater (1):
48
Heinrich Schuchardt (1):
49
ftgmac100: implement the new MDIO interface on Aspeed SoC
49
hw/arm/virt: impact of gic-version on max CPUs
50
50
51
Eric Auger (1):
51
Peter Maydell (19):
52
hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
52
hw/arm/virt: Check for attempt to use TrustZone with KVM or HVF
53
hw/arm/exynos4210: Use TYPE_OR_IRQ instead of custom OR-gate device
54
hw/intc/exynos4210_gic: Remove unused TYPE_EXYNOS4210_IRQ_GATE
55
hw/arm/exynos4210: Put a9mpcore device into state struct
56
hw/arm/exynos4210: Drop int_gic_irq[] from Exynos4210Irq struct
57
hw/arm/exynos4210: Coalesce board_irqs and irq_table
58
hw/arm/exynos4210: Fix code style nit in combiner_grp_to_gic_id[]
59
hw/arm/exynos4210: Move exynos4210_init_board_irqs() into exynos4210.c
60
hw/arm/exynos4210: Put external GIC into state struct
61
hw/arm/exynos4210: Drop ext_gic_irq[] from Exynos4210Irq struct
62
hw/arm/exynos4210: Move exynos4210_combiner_get_gpioin() into exynos4210.c
63
hw/arm/exynos4210: Delete unused macro definitions
64
hw/arm/exynos4210: Use TYPE_SPLIT_IRQ in exynos4210_init_board_irqs()
65
hw/arm/exynos4210: Fill in irq_table[] for internal-combiner-only IRQ lines
66
hw/arm/exynos4210: Connect MCT_G0 and MCT_G1 to both combiners
67
hw/arm/exynos4210: Don't connect multiple lines to external GIC inputs
68
hw/arm/exynos4210: Fold combiner splits into exynos4210_init_board_irqs()
69
hw/arm/exynos4210: Put combiners into state struct
70
hw/arm/exynos4210: Drop Exynos4210Irq struct
53
71
54
Julia Suvorova (1):
72
Zongyuan Li (3):
55
tests/libqtest: Introduce qtest_init_with_serial()
73
hw/arm/realview: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
74
hw/arm/stellaris: replace 'qemu_split_irq' with 'TYPE_SPLIT_IRQ'
75
hw/core/irq: remove unused 'qemu_irq_split' function
56
76
57
Philippe Mathieu-Daudé (1):
77
docs/system/arm/virt.rst | 4 +-
58
hw/char/stm32f2xx_usart: Do not update data register when device is disabled
78
include/hw/arm/exynos4210.h | 50 ++--
59
79
include/hw/arm/xlnx-versal.h | 16 ++
60
Richard Henderson (31):
80
include/hw/arm/xlnx-zynqmp.h | 4 +
61
target/arm: Add state for the ARMv8.3-PAuth extension
81
include/hw/intc/exynos4210_combiner.h | 57 +++++
62
target/arm: Add SCTLR bits through ARMv8.5
82
include/hw/intc/exynos4210_gic.h | 43 ++++
63
target/arm: Add PAuth active bit to tbflags
83
include/hw/irq.h | 5 -
64
target/arm: Introduce raise_exception_ra
84
include/hw/misc/npcm7xx_gcr.h | 30 +++
65
target/arm: Add PAuth helpers
85
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++++
66
target/arm: Decode PAuth within system hint space
86
include/hw/timer/cadence_ttc.h | 54 +++++
67
target/arm: Rearrange decode in disas_data_proc_1src
87
hw/arm/exynos4210.c | 430 ++++++++++++++++++++++++++++++----
68
target/arm: Decode PAuth within disas_data_proc_1src
88
hw/arm/npcm7xx_boards.c | 24 +-
69
target/arm: Decode PAuth within disas_data_proc_2src
89
hw/arm/realview.c | 33 ++-
70
target/arm: Move helper_exception_return to helper-a64.c
90
hw/arm/stellaris.c | 15 +-
71
target/arm: Add new_pc argument to helper_exception_return
91
hw/arm/virt.c | 7 +
72
target/arm: Rearrange decode in disas_uncond_b_reg
92
hw/arm/xlnx-versal-virt.c | 6 +-
73
target/arm: Decode PAuth within disas_uncond_b_reg
93
hw/arm/xlnx-versal.c | 99 +++++++-
74
target/arm: Decode Load/store register (pac)
94
hw/arm/xlnx-zynqmp.c | 22 ++
75
target/arm: Move cpu_mmu_index out of line
95
hw/core/irq.c | 15 --
76
target/arm: Introduce arm_mmu_idx
96
hw/intc/exynos4210_combiner.c | 108 +--------
77
target/arm: Introduce arm_stage1_mmu_idx
97
hw/intc/exynos4210_gic.c | 344 +--------------------------
78
target/arm: Create ARMVAParameters and helpers
98
hw/misc/xlnx-versal-crl.c | 421 +++++++++++++++++++++++++++++++++
79
target/arm: Merge TBFLAG_AA_TB{0, 1} to TBII
99
hw/timer/cadence_ttc.c | 32 +--
80
target/arm: Export aa64_va_parameters to internals.h
100
MAINTAINERS | 2 +-
81
target/arm: Add aa64_va_parameters_both
101
hw/misc/meson.build | 1 +
82
target/arm: Decode TBID from TCR
102
25 files changed, 1457 insertions(+), 600 deletions(-)
83
target/arm: Reuse aa64_va_parameters for setting tbflags
103
create mode 100644 include/hw/intc/exynos4210_combiner.h
84
target/arm: Implement pauth_strip
104
create mode 100644 include/hw/intc/exynos4210_gic.h
85
target/arm: Implement pauth_auth
105
create mode 100644 include/hw/misc/xlnx-versal-crl.h
86
target/arm: Implement pauth_addpac
106
create mode 100644 include/hw/timer/cadence_ttc.h
87
target/arm: Implement pauth_computepac
107
create mode 100644 hw/misc/xlnx-versal-crl.c
88
target/arm: Add PAuth system registers
89
target/arm: Enable PAuth for -cpu max
90
target/arm: Enable PAuth for user-only
91
target/arm: Tidy TBI handling in gen_a64_set_pc
92
93
target/arm/Makefile.objs | 1 +
94
include/hw/acpi/acpi-defs.h | 2 +
95
include/migration/vmstate.h | 1 +
96
target/arm/cpu.h | 244 +++++----
97
target/arm/helper-a64.h | 14 +
98
target/arm/helper.h | 1 -
99
target/arm/internals.h | 77 +++
100
target/arm/translate.h | 5 +-
101
tests/libqtest.h | 11 +
102
hw/arm/virt-acpi-build.c | 1 +
103
hw/char/stm32f2xx_usart.c | 3 +-
104
hw/net/ftgmac100.c | 80 ++-
105
migration/vmstate.c | 13 +-
106
target/arm/cpu.c | 19 +-
107
target/arm/cpu64.c | 68 ++-
108
target/arm/helper-a64.c | 155 ++++++
109
target/arm/helper.c | 1222 +++++++++++++++++++++++++++++++++----------
110
target/arm/machine.c | 24 +
111
target/arm/op_helper.c | 174 +-----
112
target/arm/pauth_helper.c | 497 ++++++++++++++++++
113
target/arm/translate-a64.c | 537 ++++++++++++++++---
114
tests/libqtest.c | 26 +
115
docs/devel/migration.rst | 9 +-
116
23 files changed, 2552 insertions(+), 632 deletions(-)
117
create mode 100644 target/arm/pauth_helper.c
118
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
When the device is disabled, the internal circuitry keeps the data
4
register loaded and doesn't update it.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20190104182057.8778-1-philmd@redhat.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/char/stm32f2xx_usart.c | 3 +--
12
1 file changed, 1 insertion(+), 2 deletions(-)
13
14
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/stm32f2xx_usart.c
17
+++ b/hw/char/stm32f2xx_usart.c
18
@@ -XXX,XX +XXX,XX @@ static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
19
{
20
STM32F2XXUsartState *s = opaque;
21
22
- s->usart_dr = *buf;
23
-
24
if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
25
/* USART not enabled - drop the chars */
26
DB_PRINT("Dropping the chars\n");
27
return;
28
}
29
30
+ s->usart_dr = *buf;
31
s->usart_sr |= USART_SR_RXNE;
32
33
if (s->usart_cr1 & USART_CR1_RXNEIE) {
34
--
35
2.20.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Let's report IO-coherent access is supported for translation
4
table walks, descriptor fetches and queues by setting the COHACC
5
override flag. Without that, we observe wrong command opcodes.
6
The DT description also advertises the dma coherency.
7
8
Fixes a703b4f6c1ee ("hw/arm/virt-acpi-build: Add smmuv3 node in IORT table")
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reported-by: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
12
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
14
Message-id: 20190107101041.765-1-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/acpi/acpi-defs.h | 2 ++
18
hw/arm/virt-acpi-build.c | 1 +
19
2 files changed, 3 insertions(+)
20
21
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/acpi/acpi-defs.h
24
+++ b/include/hw/acpi/acpi-defs.h
25
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
26
} QEMU_PACKED;
27
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
28
29
+#define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE 1
30
+
31
struct AcpiIortSmmu3 {
32
ACPI_IORT_NODE_HEADER_DEF
33
uint64_t base_address;
34
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/virt-acpi-build.c
37
+++ b/hw/arm/virt-acpi-build.c
38
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
39
smmu->mapping_count = cpu_to_le32(1);
40
smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
41
smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
42
+ smmu->flags = cpu_to_le32(ACPI_IORT_SMMU_V3_COHACC_OVERRIDE);
43
smmu->event_gsiv = cpu_to_le32(irq);
44
smmu->pri_gsiv = cpu_to_le32(irq + 1);
45
smmu->gerr_gsiv = cpu_to_le32(irq + 2);
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
It's not possible to provide the guest with the Security extensions
2
(TrustZone) when using KVM or HVF, because the hardware
3
virtualization extensions don't permit running EL3 guest code.
4
However, we weren't checking for this combination, with the result
5
that QEMU would assert if you tried it:
2
6
3
Add arrays to hold the registers, the definitions themselves, access
7
$ qemu-system-aarch64 -enable-kvm -machine virt,secure=on -cpu host -display none
4
functions, and logic to reset counters when PMCR.P is set. Update
8
Unexpected error in object_property_find_err() at ../../qom/object.c:1304:
5
filtering code to support counters other than PMCCNTR. Support migration
9
qemu-system-aarch64: Property 'host-arm-cpu.secure-memory' not found
6
with raw read/write functions.
10
Aborted
7
11
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
12
Check for this combination of options and report an error, in the
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
13
same way we already do for attempts to give a KVM or HVF guest the
14
Virtualization or MTE extensions. Now we will report:
15
16
qemu-system-aarch64: mach-virt: KVM does not support providing Security extensions (TrustZone) to the guest CPU
17
18
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/961
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181211151945.29137-11-aaron@os.amperecomputing.com
21
Message-id: 20220404155301.566542-1-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
22
---
14
target/arm/cpu.h | 3 +
23
hw/arm/virt.c | 7 +++++++
15
target/arm/helper.c | 296 +++++++++++++++++++++++++++++++++++++++++---
24
1 file changed, 7 insertions(+)
16
2 files changed, 282 insertions(+), 17 deletions(-)
17
25
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
28
--- a/hw/arm/virt.c
21
+++ b/target/arm/cpu.h
29
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
23
* pmccntr_op_finish.
31
exit(1);
24
*/
25
uint64_t c15_ccnt_delta;
26
+ uint64_t c14_pmevcntr[31];
27
+ uint64_t c14_pmevcntr_delta[31];
28
+ uint64_t c14_pmevtyper[31];
29
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
30
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
31
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
37
#define PMCRDP 0x10
38
#define PMCRD 0x8
39
#define PMCRC 0x4
40
+#define PMCRP 0x2
41
#define PMCRE 0x1
42
43
#define PMXEVTYPER_P 0x80000000
44
@@ -XXX,XX +XXX,XX @@ uint64_t get_pmceid(CPUARMState *env, unsigned which)
45
return pmceid;
46
}
47
48
+/*
49
+ * Check at runtime whether a PMU event is supported for the current machine
50
+ */
51
+static bool event_supported(uint16_t number)
52
+{
53
+ if (number > MAX_EVENT_ID) {
54
+ return false;
55
+ }
56
+ return supported_event_map[number] != UNSUPPORTED_EVENT;
57
+}
58
+
59
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
60
bool isread)
61
{
62
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
63
prohibited = env->cp15.c9_pmcr & PMCRDP;
64
}
32
}
65
33
66
- /* TODO Remove assert, set filter to correct PMEVTYPER */
34
+ if (vms->secure && (kvm_enabled() || hvf_enabled())) {
67
- assert(counter == 31);
35
+ error_report("mach-virt: %s does not support providing "
68
- filter = env->cp15.pmccfiltr_el0;
36
+ "Security extensions (TrustZone) to the guest CPU",
69
+ if (counter == 31) {
37
+ kvm_enabled() ? "KVM" : "HVF");
70
+ filter = env->cp15.pmccfiltr_el0;
38
+ exit(1);
71
+ } else {
72
+ filter = env->cp15.c14_pmevtyper[counter];
73
+ }
74
75
p = filter & PMXEVTYPER_P;
76
u = filter & PMXEVTYPER_U;
77
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
78
filtered = m != p;
79
}
80
81
+ if (counter != 31) {
82
+ /*
83
+ * If not checking PMCCNTR, ensure the counter is setup to an event we
84
+ * support
85
+ */
86
+ uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
87
+ if (!event_supported(event)) {
88
+ return false;
89
+ }
90
+ }
39
+ }
91
+
40
+
92
return enabled && !prohibited && !filtered;
41
if (vms->virt && (kvm_enabled() || hvf_enabled())) {
93
}
42
error_report("mach-virt: %s does not support providing "
94
43
"Virtualization extensions to the guest CPU",
95
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
96
}
97
}
98
99
+static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
100
+{
101
+
102
+ uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
103
+ uint64_t count = 0;
104
+ if (event_supported(event)) {
105
+ uint16_t event_idx = supported_event_map[event];
106
+ count = pm_events[event_idx].get_count(env);
107
+ }
108
+
109
+ if (pmu_counter_enabled(env, counter)) {
110
+ env->cp15.c14_pmevcntr[counter] =
111
+ count - env->cp15.c14_pmevcntr_delta[counter];
112
+ }
113
+ env->cp15.c14_pmevcntr_delta[counter] = count;
114
+}
115
+
116
+static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
117
+{
118
+ if (pmu_counter_enabled(env, counter)) {
119
+ env->cp15.c14_pmevcntr_delta[counter] -=
120
+ env->cp15.c14_pmevcntr[counter];
121
+ }
122
+}
123
+
124
void pmu_op_start(CPUARMState *env)
125
{
126
+ unsigned int i;
127
pmccntr_op_start(env);
128
+ for (i = 0; i < pmu_num_counters(env); i++) {
129
+ pmevcntr_op_start(env, i);
130
+ }
131
}
132
133
void pmu_op_finish(CPUARMState *env)
134
{
135
+ unsigned int i;
136
pmccntr_op_finish(env);
137
+ for (i = 0; i < pmu_num_counters(env); i++) {
138
+ pmevcntr_op_finish(env, i);
139
+ }
140
}
141
142
void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
143
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
env->cp15.c15_ccnt = 0;
145
}
146
147
+ if (value & PMCRP) {
148
+ unsigned int i;
149
+ for (i = 0; i < pmu_num_counters(env); i++) {
150
+ env->cp15.c14_pmevcntr[i] = 0;
151
+ }
152
+ }
153
+
154
/* only the DP, X, D and E bits are writable */
155
env->cp15.c9_pmcr &= ~0x39;
156
env->cp15.c9_pmcr |= (value & 0x39);
157
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
158
{
159
}
160
161
+void pmevcntr_op_start(CPUARMState *env, uint8_t i)
162
+{
163
+}
164
+
165
+void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
166
+{
167
+}
168
+
169
void pmu_op_start(CPUARMState *env)
170
{
171
}
172
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
173
env->cp15.c9_pmovsr |= value;
174
}
175
176
-static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
177
- uint64_t value)
178
+static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
179
+ uint64_t value, const uint8_t counter)
180
{
181
+ if (counter == 31) {
182
+ pmccfiltr_write(env, ri, value);
183
+ } else if (counter < pmu_num_counters(env)) {
184
+ pmevcntr_op_start(env, counter);
185
+
186
+ /*
187
+ * If this counter's event type is changing, store the current
188
+ * underlying count for the new type in c14_pmevcntr_delta[counter] so
189
+ * pmevcntr_op_finish has the correct baseline when it converts back to
190
+ * a delta.
191
+ */
192
+ uint16_t old_event = env->cp15.c14_pmevtyper[counter] &
193
+ PMXEVTYPER_EVTCOUNT;
194
+ uint16_t new_event = value & PMXEVTYPER_EVTCOUNT;
195
+ if (old_event != new_event) {
196
+ uint64_t count = 0;
197
+ if (event_supported(new_event)) {
198
+ uint16_t event_idx = supported_event_map[new_event];
199
+ count = pm_events[event_idx].get_count(env);
200
+ }
201
+ env->cp15.c14_pmevcntr_delta[counter] = count;
202
+ }
203
+
204
+ env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
205
+ pmevcntr_op_finish(env, counter);
206
+ }
207
/* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
208
* PMSELR value is equal to or greater than the number of implemented
209
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
210
*/
211
- if (env->cp15.c9_pmselr == 0x1f) {
212
- pmccfiltr_write(env, ri, value);
213
+}
214
+
215
+static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri,
216
+ const uint8_t counter)
217
+{
218
+ if (counter == 31) {
219
+ return env->cp15.pmccfiltr_el0;
220
+ } else if (counter < pmu_num_counters(env)) {
221
+ return env->cp15.c14_pmevtyper[counter];
222
+ } else {
223
+ /*
224
+ * We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
225
+ * are CONSTRAINED UNPREDICTABLE. See comments in pmevtyper_write().
226
+ */
227
+ return 0;
228
}
229
}
230
231
+static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
232
+ uint64_t value)
233
+{
234
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
235
+ pmevtyper_write(env, ri, value, counter);
236
+}
237
+
238
+static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
239
+ uint64_t value)
240
+{
241
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
242
+ env->cp15.c14_pmevtyper[counter] = value;
243
+
244
+ /*
245
+ * pmevtyper_rawwrite is called between a pair of pmu_op_start and
246
+ * pmu_op_finish calls when loading saved state for a migration. Because
247
+ * we're potentially updating the type of event here, the value written to
248
+ * c14_pmevcntr_delta by the preceeding pmu_op_start call may be for a
249
+ * different counter type. Therefore, we need to set this value to the
250
+ * current count for the counter type we're writing so that pmu_op_finish
251
+ * has the correct count for its calculation.
252
+ */
253
+ uint16_t event = value & PMXEVTYPER_EVTCOUNT;
254
+ if (event_supported(event)) {
255
+ uint16_t event_idx = supported_event_map[event];
256
+ env->cp15.c14_pmevcntr_delta[counter] =
257
+ pm_events[event_idx].get_count(env);
258
+ }
259
+}
260
+
261
+static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
262
+{
263
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
264
+ return pmevtyper_read(env, ri, counter);
265
+}
266
+
267
+static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
268
+ uint64_t value)
269
+{
270
+ pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31);
271
+}
272
+
273
static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri)
274
{
275
- /* We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
276
- * are CONSTRAINED UNPREDICTABLE. See comments in pmxevtyper_write().
277
+ return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31);
278
+}
279
+
280
+static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
281
+ uint64_t value, uint8_t counter)
282
+{
283
+ if (counter < pmu_num_counters(env)) {
284
+ pmevcntr_op_start(env, counter);
285
+ env->cp15.c14_pmevcntr[counter] = value;
286
+ pmevcntr_op_finish(env, counter);
287
+ }
288
+ /*
289
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
290
+ * are CONSTRAINED UNPREDICTABLE.
291
*/
292
- if (env->cp15.c9_pmselr == 0x1f) {
293
- return env->cp15.pmccfiltr_el0;
294
+}
295
+
296
+static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
297
+ uint8_t counter)
298
+{
299
+ if (counter < pmu_num_counters(env)) {
300
+ uint64_t ret;
301
+ pmevcntr_op_start(env, counter);
302
+ ret = env->cp15.c14_pmevcntr[counter];
303
+ pmevcntr_op_finish(env, counter);
304
+ return ret;
305
} else {
306
+ /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
307
+ * are CONSTRAINED UNPREDICTABLE. */
308
return 0;
309
}
310
}
311
312
+static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
313
+ uint64_t value)
314
+{
315
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
316
+ pmevcntr_write(env, ri, value, counter);
317
+}
318
+
319
+static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
320
+{
321
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
322
+ return pmevcntr_read(env, ri, counter);
323
+}
324
+
325
+static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
326
+ uint64_t value)
327
+{
328
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
329
+ assert(counter < pmu_num_counters(env));
330
+ env->cp15.c14_pmevcntr[counter] = value;
331
+ pmevcntr_write(env, ri, value, counter);
332
+}
333
+
334
+static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri)
335
+{
336
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
337
+ assert(counter < pmu_num_counters(env));
338
+ return env->cp15.c14_pmevcntr[counter];
339
+}
340
+
341
+static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
342
+ uint64_t value)
343
+{
344
+ pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31);
345
+}
346
+
347
+static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
348
+{
349
+ return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31);
350
+}
351
+
352
static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
353
uint64_t value)
354
{
355
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
356
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
357
.resetvalue = 0, },
358
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
359
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
360
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
361
+ .accessfn = pmreg_access,
362
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
363
{ .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
364
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
365
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
366
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
367
+ .accessfn = pmreg_access,
368
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
369
- /* Unimplemented, RAZ/WI. */
370
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
371
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
372
- .accessfn = pmreg_access_xevcntr },
373
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
374
+ .accessfn = pmreg_access_xevcntr,
375
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
376
+ { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
377
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
378
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
379
+ .accessfn = pmreg_access_xevcntr,
380
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
381
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
382
.access = PL0_R | PL1_RW, .accessfn = access_tpm,
383
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr),
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
385
#endif
386
/* The only field of MDCR_EL2 that has a defined architectural reset value
387
* is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we
388
- * don't impelment any PMU event counters, so using zero as a reset
389
+ * don't implement any PMU event counters, so using zero as a reset
390
* value for MDCR_EL2 is okay
391
*/
392
{ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
393
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
394
* field as main ID register, and we implement only the cycle
395
* count register.
396
*/
397
+ unsigned int i, pmcrn = 0;
398
#ifndef CONFIG_USER_ONLY
399
ARMCPRegInfo pmcr = {
400
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
401
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
402
};
403
define_one_arm_cp_reg(cpu, &pmcr);
404
define_one_arm_cp_reg(cpu, &pmcr64);
405
+ for (i = 0; i < pmcrn; i++) {
406
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
407
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
408
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
409
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
410
+ ARMCPRegInfo pmev_regs[] = {
411
+ { .name = pmevcntr_name, .cp = 15, .crn = 15,
412
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
413
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
414
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
415
+ .accessfn = pmreg_access },
416
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
417
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)),
418
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
419
+ .type = ARM_CP_IO,
420
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
421
+ .raw_readfn = pmevcntr_rawread,
422
+ .raw_writefn = pmevcntr_rawwrite },
423
+ { .name = pmevtyper_name, .cp = 15, .crn = 15,
424
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
425
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
426
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
427
+ .accessfn = pmreg_access },
428
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
429
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)),
430
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
431
+ .type = ARM_CP_IO,
432
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
433
+ .raw_writefn = pmevtyper_rawwrite },
434
+ REGINFO_SENTINEL
435
+ };
436
+ define_arm_cp_regs(cpu, pmev_regs);
437
+ g_free(pmevcntr_name);
438
+ g_free(pmevcntr_el0_name);
439
+ g_free(pmevtyper_name);
440
+ g_free(pmevtyper_el0_name);
441
+ }
442
#endif
443
ARMCPRegInfo clidr = {
444
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
445
--
44
--
446
2.20.1
45
2.25.1
447
448
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
This commit doesn't add any supported events, but provides the framework
3
Break out header file to allow embedding of the the TTC.
4
for adding them. We store the pm_event structs in a simple array, and
5
provide the mapping from the event numbers to array indexes in the
6
supported_event_map array. Because the value of PMCEID[01] depends upon
7
which events are supported at runtime, generate it dynamically.
8
4
9
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 20181211151945.29137-10-aaron@os.amperecomputing.com
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-2-edgar.iglesias@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
target/arm/cpu.h | 10 ++++++++
12
include/hw/timer/cadence_ttc.h | 54 ++++++++++++++++++++++++++++++++++
15
target/arm/cpu.c | 19 +++++++++------
13
hw/timer/cadence_ttc.c | 32 ++------------------
16
target/arm/cpu64.c | 4 ----
14
2 files changed, 56 insertions(+), 30 deletions(-)
17
target/arm/helper.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
15
create mode 100644 include/hw/timer/cadence_ttc.h
18
4 files changed, 79 insertions(+), 11 deletions(-)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/include/hw/timer/cadence_ttc.h b/include/hw/timer/cadence_ttc.h
21
index XXXXXXX..XXXXXXX 100644
18
new file mode 100644
22
--- a/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX
23
+++ b/target/arm/cpu.h
20
--- /dev/null
24
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
21
+++ b/include/hw/timer/cadence_ttc.h
25
void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
22
@@ -XXX,XX +XXX,XX @@
26
void pmu_post_el_change(ARMCPU *cpu, void *ignored);
27
28
+/*
23
+/*
29
+ * get_pmceid
24
+ * Xilinx Zynq cadence TTC model
30
+ * @env: CPUARMState
31
+ * @which: which PMCEID register to return (0 or 1)
32
+ *
25
+ *
33
+ * Return the PMCEID[01]_EL0 register values corresponding to the counters
26
+ * Copyright (c) 2011 Xilinx Inc.
34
+ * which are supported given the current configuration
27
+ * Copyright (c) 2012 Peter A.G. Crosthwaite (peter.crosthwaite@petalogix.com)
28
+ * Copyright (c) 2012 PetaLogix Pty Ltd.
29
+ * Written By Haibing Ma
30
+ * M. Habib
31
+ *
32
+ * This program is free software; you can redistribute it and/or
33
+ * modify it under the terms of the GNU General Public License
34
+ * as published by the Free Software Foundation; either version
35
+ * 2 of the License, or (at your option) any later version.
36
+ *
37
+ * You should have received a copy of the GNU General Public License along
38
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
35
+ */
39
+ */
36
+uint64_t get_pmceid(CPUARMState *env, unsigned which);
40
+#ifndef HW_TIMER_CADENCE_TTC_H
41
+#define HW_TIMER_CADENCE_TTC_H
37
+
42
+
38
/* SCTLR bit meanings. Several bits have been reused in newer
43
+#include "hw/sysbus.h"
39
* versions of the architecture; in that case we define constants
44
+#include "qemu/timer.h"
40
* for both old and new bit meanings. Code which tests against those
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/cpu.c
44
+++ b/target/arm/cpu.c
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
46
47
if (!cpu->has_pmu) {
48
unset_feature(env, ARM_FEATURE_PMU);
49
+ }
50
+ if (arm_feature(env, ARM_FEATURE_PMU)) {
51
+ cpu->pmceid0 = get_pmceid(&cpu->env, 0);
52
+ cpu->pmceid1 = get_pmceid(&cpu->env, 1);
53
+
45
+
54
+ if (!kvm_enabled()) {
46
+typedef struct {
55
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
47
+ QEMUTimer *timer;
56
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
48
+ int freq;
57
+ }
58
+ } else {
59
cpu->id_aa64dfr0 &= ~0xf00;
60
- } else if (!kvm_enabled()) {
61
- arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
62
- arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
63
+ cpu->pmceid0 = 0;
64
+ cpu->pmceid1 = 0;
65
}
66
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
68
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
69
cpu->id_pfr0 = 0x00001131;
70
cpu->id_pfr1 = 0x00011011;
71
cpu->id_dfr0 = 0x02010555;
72
- cpu->pmceid0 = 0x00000000;
73
- cpu->pmceid1 = 0x00000000;
74
cpu->id_afr0 = 0x00000000;
75
cpu->id_mmfr0 = 0x10101105;
76
cpu->id_mmfr1 = 0x40000000;
77
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
78
cpu->id_pfr0 = 0x00001131;
79
cpu->id_pfr1 = 0x00011011;
80
cpu->id_dfr0 = 0x02010555;
81
- cpu->pmceid0 = 0x0000000;
82
- cpu->pmceid1 = 0x00000000;
83
cpu->id_afr0 = 0x00000000;
84
cpu->id_mmfr0 = 0x10201105;
85
cpu->id_mmfr1 = 0x20000000;
86
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/cpu64.c
89
+++ b/target/arm/cpu64.c
90
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
91
cpu->isar.id_isar6 = 0;
92
cpu->isar.id_aa64pfr0 = 0x00002222;
93
cpu->id_aa64dfr0 = 0x10305106;
94
- cpu->pmceid0 = 0x00000000;
95
- cpu->pmceid1 = 0x00000000;
96
cpu->isar.id_aa64isar0 = 0x00011120;
97
cpu->isar.id_aa64mmfr0 = 0x00001124;
98
cpu->dbgdidr = 0x3516d000;
99
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
100
cpu->isar.id_isar5 = 0x00011121;
101
cpu->isar.id_aa64pfr0 = 0x00002222;
102
cpu->id_aa64dfr0 = 0x10305106;
103
- cpu->pmceid0 = 0x00000000;
104
- cpu->pmceid1 = 0x00000000;
105
cpu->isar.id_aa64isar0 = 0x00011120;
106
cpu->isar.id_aa64mmfr0 = 0x00001124;
107
cpu->dbgdidr = 0x3516d000;
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/helper.c
111
+++ b/target/arm/helper.c
112
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
113
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
114
}
115
116
+typedef struct pm_event {
117
+ uint16_t number; /* PMEVTYPER.evtCount is 16 bits wide */
118
+ /* If the event is supported on this CPU (used to generate PMCEID[01]) */
119
+ bool (*supported)(CPUARMState *);
120
+ /*
121
+ * Retrieve the current count of the underlying event. The programmed
122
+ * counters hold a difference from the return value from this function
123
+ */
124
+ uint64_t (*get_count)(CPUARMState *);
125
+} pm_event;
126
+
49
+
127
+static const pm_event pm_events[] = {
50
+ uint32_t reg_clock;
51
+ uint32_t reg_count;
52
+ uint32_t reg_value;
53
+ uint16_t reg_interval;
54
+ uint16_t reg_match[3];
55
+ uint32_t reg_intr;
56
+ uint32_t reg_intr_en;
57
+ uint32_t reg_event_ctrl;
58
+ uint32_t reg_event;
59
+
60
+ uint64_t cpu_time;
61
+ unsigned int cpu_time_valid;
62
+
63
+ qemu_irq irq;
64
+} CadenceTimerState;
65
+
66
+#define TYPE_CADENCE_TTC "cadence_ttc"
67
+OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
68
+
69
+struct CadenceTTCState {
70
+ SysBusDevice parent_obj;
71
+
72
+ MemoryRegion iomem;
73
+ CadenceTimerState timer[3];
128
+};
74
+};
129
+
75
+
130
+/*
76
+#endif
131
+ * Note: Before increasing MAX_EVENT_ID beyond 0x3f into the 0x40xx range of
77
diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c
132
+ * events (i.e. the statistical profiling extension), this implementation
78
index XXXXXXX..XXXXXXX 100644
133
+ * should first be updated to something sparse instead of the current
79
--- a/hw/timer/cadence_ttc.c
134
+ * supported_event_map[] array.
80
+++ b/hw/timer/cadence_ttc.c
135
+ */
81
@@ -XXX,XX +XXX,XX @@
136
+#define MAX_EVENT_ID 0x0
82
#include "qemu/timer.h"
137
+#define UNSUPPORTED_EVENT UINT16_MAX
83
#include "qom/object.h"
138
+static uint16_t supported_event_map[MAX_EVENT_ID + 1];
84
85
+#include "hw/timer/cadence_ttc.h"
139
+
86
+
140
+/*
87
#ifdef CADENCE_TTC_ERR_DEBUG
141
+ * Called upon initialization to build PMCEID0_EL0 or PMCEID1_EL0 (indicated by
88
#define DB_PRINT(...) do { \
142
+ * 'which'). We also use it to build a map of ARM event numbers to indices in
89
fprintf(stderr, ": %s: ", __func__); \
143
+ * our pm_events array.
90
@@ -XXX,XX +XXX,XX @@
144
+ *
91
#define CLOCK_CTRL_PS_EN 0x00000001
145
+ * Note: Events in the 0x40XX range are not currently supported.
92
#define CLOCK_CTRL_PS_V 0x0000001e
146
+ */
93
147
+uint64_t get_pmceid(CPUARMState *env, unsigned which)
94
-typedef struct {
148
+{
95
- QEMUTimer *timer;
149
+ uint64_t pmceid = 0;
96
- int freq;
150
+ unsigned int i;
97
-
151
+
98
- uint32_t reg_clock;
152
+ assert(which <= 1);
99
- uint32_t reg_count;
153
+
100
- uint32_t reg_value;
154
+ for (i = 0; i < ARRAY_SIZE(supported_event_map); i++) {
101
- uint16_t reg_interval;
155
+ supported_event_map[i] = UNSUPPORTED_EVENT;
102
- uint16_t reg_match[3];
156
+ }
103
- uint32_t reg_intr;
157
+
104
- uint32_t reg_intr_en;
158
+ for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
105
- uint32_t reg_event_ctrl;
159
+ const pm_event *cnt = &pm_events[i];
106
- uint32_t reg_event;
160
+ assert(cnt->number <= MAX_EVENT_ID);
107
-
161
+ /* We do not currently support events in the 0x40xx range */
108
- uint64_t cpu_time;
162
+ assert(cnt->number <= 0x3f);
109
- unsigned int cpu_time_valid;
163
+
110
-
164
+ if ((cnt->number & 0x20) == (which << 6) &&
111
- qemu_irq irq;
165
+ cnt->supported(env)) {
112
-} CadenceTimerState;
166
+ pmceid |= (1 << (cnt->number & 0x1f));
113
-
167
+ supported_event_map[cnt->number] = i;
114
-#define TYPE_CADENCE_TTC "cadence_ttc"
168
+ }
115
-OBJECT_DECLARE_SIMPLE_TYPE(CadenceTTCState, CADENCE_TTC)
169
+ }
116
-
170
+ return pmceid;
117
-struct CadenceTTCState {
171
+}
118
- SysBusDevice parent_obj;
172
+
119
-
173
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
120
- MemoryRegion iomem;
174
bool isread)
121
- CadenceTimerState timer[3];
122
-};
123
-
124
static void cadence_timer_update(CadenceTimerState *s)
175
{
125
{
126
qemu_set_irq(s->irq, !!(s->reg_intr & s->reg_intr_en));
176
--
127
--
177
2.20.1
128
2.25.1
178
179
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
Connect the 4 TTC timers on the ZynqMP.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20181211151945.29137-14-aaron@os.amperecomputing.com
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Luc Michel <luc@lmichel.fr>
8
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Message-id: 20220331222017.2914409-3-edgar.iglesias@gmail.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/helper.c | 39 +++++++++++++++++++++++++++++++++++++--
12
include/hw/arm/xlnx-zynqmp.h | 4 ++++
9
1 file changed, 37 insertions(+), 2 deletions(-)
13
hw/arm/xlnx-zynqmp.c | 22 ++++++++++++++++++++++
14
2 files changed, 26 insertions(+)
10
15
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
18
--- a/include/hw/arm/xlnx-zynqmp.h
14
+++ b/target/arm/helper.c
19
+++ b/include/hw/arm/xlnx-zynqmp.h
15
@@ -XXX,XX +XXX,XX @@ static bool event_always_supported(CPUARMState *env)
20
@@ -XXX,XX +XXX,XX @@
16
return true;
21
#include "hw/or-irq.h"
17
}
22
#include "hw/misc/xlnx-zynqmp-apu-ctrl.h"
18
23
#include "hw/misc/xlnx-zynqmp-crf.h"
19
+static uint64_t swinc_get_count(CPUARMState *env)
24
+#include "hw/timer/cadence_ttc.h"
20
+{
25
21
+ /*
26
#define TYPE_XLNX_ZYNQMP "xlnx-zynqmp"
22
+ * SW_INCR events are written directly to the pmevcntr's by writes to
27
OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
23
+ * PMSWINC, so there is no underlying count maintained by the PMU itself
28
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(XlnxZynqMPState, XLNX_ZYNQMP)
24
+ */
29
#define XLNX_ZYNQMP_MAX_RAM_SIZE (XLNX_ZYNQMP_MAX_LOW_RAM_SIZE + \
25
+ return 0;
30
XLNX_ZYNQMP_MAX_HIGH_RAM_SIZE)
26
+}
31
32
+#define XLNX_ZYNQMP_NUM_TTC 4
27
+
33
+
28
/*
34
/*
29
* Return the underlying cycle count for the PMU cycle counters. If we're in
35
* Unimplemented mmio regions needed to boot some images.
30
* usermode, simply return 0.
36
*/
31
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
37
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
32
#endif
38
qemu_or_irq qspi_irq_orgate;
33
39
XlnxZynqMPAPUCtrl apu_ctrl;
34
static const pm_event pm_events[] = {
40
XlnxZynqMPCRF crf;
35
+ { .number = 0x000, /* SW_INCR */
41
+ CadenceTTCState ttc[XLNX_ZYNQMP_NUM_TTC];
36
+ .supported = event_always_supported,
42
37
+ .get_count = swinc_get_count,
43
char *boot_cpu;
38
+ },
44
ARMCPU *boot_cpu_ptr;
39
#ifndef CONFIG_USER_ONLY
45
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
40
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
46
index XXXXXXX..XXXXXXX 100644
41
.supported = instructions_supported,
47
--- a/hw/arm/xlnx-zynqmp.c
42
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
48
+++ b/hw/arm/xlnx-zynqmp.c
43
pmu_op_finish(env);
49
@@ -XXX,XX +XXX,XX @@
50
#define APU_ADDR 0xfd5c0000
51
#define APU_IRQ 153
52
53
+#define TTC0_ADDR 0xFF110000
54
+#define TTC0_IRQ 36
55
+
56
#define IPI_ADDR 0xFF300000
57
#define IPI_IRQ 64
58
59
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_crf(XlnxZynqMPState *s, qemu_irq *gic)
60
sysbus_connect_irq(sbd, 0, gic[CRF_IRQ]);
44
}
61
}
45
62
46
+static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
63
+static void xlnx_zynqmp_create_ttc(XlnxZynqMPState *s, qemu_irq *gic)
47
+ uint64_t value)
48
+{
64
+{
49
+ unsigned int i;
65
+ SysBusDevice *sbd;
50
+ for (i = 0; i < pmu_num_counters(env); i++) {
66
+ int i, irq;
51
+ /* Increment a counter's count iff: */
67
+
52
+ if ((value & (1 << i)) && /* counter's bit is set */
68
+ for (i = 0; i < XLNX_ZYNQMP_NUM_TTC; i++) {
53
+ /* counter is enabled and not filtered */
69
+ object_initialize_child(OBJECT(s), "ttc[*]", &s->ttc[i],
54
+ pmu_counter_enabled(env, i) &&
70
+ TYPE_CADENCE_TTC);
55
+ /* counter is SW_INCR */
71
+ sbd = SYS_BUS_DEVICE(&s->ttc[i]);
56
+ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
72
+
57
+ pmevcntr_op_start(env, i);
73
+ sysbus_realize(sbd, &error_fatal);
58
+ env->cp15.c14_pmevcntr[i]++;
74
+ sysbus_mmio_map(sbd, 0, TTC0_ADDR + i * 0x10000);
59
+ pmevcntr_op_finish(env, i);
75
+ for (irq = 0; irq < 3; irq++) {
76
+ sysbus_connect_irq(sbd, irq, gic[TTC0_IRQ + i * 3 + irq]);
60
+ }
77
+ }
61
+ }
78
+ }
62
+}
79
+}
63
+
80
+
64
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
81
static void xlnx_zynqmp_create_unimp_mmio(XlnxZynqMPState *s)
65
{
82
{
66
uint64_t ret;
83
static const struct UnimpInfo {
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
84
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
68
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
85
xlnx_zynqmp_create_efuse(s, gic_spi);
69
.writefn = pmovsr_write,
86
xlnx_zynqmp_create_apu_ctrl(s, gic_spi);
70
.raw_writefn = raw_write },
87
xlnx_zynqmp_create_crf(s, gic_spi);
71
- /* Unimplemented so WI. */
88
+ xlnx_zynqmp_create_ttc(s, gic_spi);
72
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
89
xlnx_zynqmp_create_unimp_mmio(s);
73
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
90
74
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
91
for (i = 0; i < XLNX_ZYNQMP_NUM_GDMA_CH; i++) {
75
+ .writefn = pmswinc_write },
76
+ { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
77
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
78
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
79
+ .writefn = pmswinc_write },
80
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
81
.access = PL0_RW, .type = ARM_CP_ALIAS,
82
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
83
--
92
--
84
2.20.1
93
2.25.1
85
86
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Run qtest with a socket that connects QEMU chardev and test code.
3
Create an APU CPU Cluster. This is in preparation to add the RPU.
4
4
5
Signed-off-by: Julia Suvorova <jusual@mail.ru>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
7
Message-id: 20190117161640.5496-2-jusual@mail.ru
7
Message-id: 20220406174303.2022038-2-edgar.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
tests/libqtest.h | 11 +++++++++++
10
include/hw/arm/xlnx-versal.h | 2 ++
11
tests/libqtest.c | 26 ++++++++++++++++++++++++++
11
hw/arm/xlnx-versal.c | 9 ++++++++-
12
2 files changed, 37 insertions(+)
12
2 files changed, 10 insertions(+), 1 deletion(-)
13
13
14
diff --git a/tests/libqtest.h b/tests/libqtest.h
14
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/libqtest.h
16
--- a/include/hw/arm/xlnx-versal.h
17
+++ b/tests/libqtest.h
17
+++ b/include/hw/arm/xlnx-versal.h
18
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_init(const char *extra_args);
18
@@ -XXX,XX +XXX,XX @@
19
*/
19
20
QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
20
#include "hw/sysbus.h"
21
21
#include "hw/arm/boot.h"
22
+/**
22
+#include "hw/cpu/cluster.h"
23
+ * qtest_init_with_serial:
23
#include "hw/or-irq.h"
24
+ * @extra_args: other arguments to pass to QEMU. CAUTION: these
24
#include "hw/sd/sdhci.h"
25
+ * arguments are subject to word splitting and shell evaluation.
25
#include "hw/intc/arm_gicv3.h"
26
+ * @sock_fd: pointer to store the socket file descriptor for
26
@@ -XXX,XX +XXX,XX @@ struct Versal {
27
+ * connection with serial.
27
struct {
28
+ *
28
struct {
29
+ * Returns: #QTestState instance.
29
MemoryRegion mr;
30
+ */
30
+ CPUClusterState cluster;
31
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd);
31
ARMCPU cpu[XLNX_VERSAL_NR_ACPUS];
32
GICv3State gic;
33
} apu;
34
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/xlnx-versal.c
37
+++ b/hw/arm/xlnx-versal.c
38
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
39
{
40
int i;
41
42
+ object_initialize_child(OBJECT(s), "apu-cluster", &s->fpd.apu.cluster,
43
+ TYPE_CPU_CLUSTER);
44
+ qdev_prop_set_uint32(DEVICE(&s->fpd.apu.cluster), "cluster-id", 0);
32
+
45
+
33
/**
46
for (i = 0; i < ARRAY_SIZE(s->fpd.apu.cpu); i++) {
34
* qtest_quit:
47
Object *obj;
35
* @s: #QTestState instance to operate on.
48
36
diff --git a/tests/libqtest.c b/tests/libqtest.c
49
- object_initialize_child(OBJECT(s), "apu-cpu[*]", &s->fpd.apu.cpu[i],
37
index XXXXXXX..XXXXXXX 100644
50
+ object_initialize_child(OBJECT(&s->fpd.apu.cluster),
38
--- a/tests/libqtest.c
51
+ "apu-cpu[*]", &s->fpd.apu.cpu[i],
39
+++ b/tests/libqtest.c
52
XLNX_VERSAL_ACPU_TYPE);
40
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_initf(const char *fmt, ...)
53
obj = OBJECT(&s->fpd.apu.cpu[i]);
41
return s;
54
if (i) {
55
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_cpus(Versal *s)
56
&error_abort);
57
qdev_realize(DEVICE(obj), NULL, &error_fatal);
58
}
59
+
60
+ qdev_realize(DEVICE(&s->fpd.apu.cluster), NULL, &error_fatal);
42
}
61
}
43
62
44
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
63
static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
45
+{
46
+ int sock_fd_init;
47
+ char *sock_path, sock_dir[] = "/tmp/qtest-serial-XXXXXX";
48
+ QTestState *qts;
49
+
50
+ g_assert(mkdtemp(sock_dir));
51
+ sock_path = g_strdup_printf("%s/sock", sock_dir);
52
+
53
+ sock_fd_init = init_socket(sock_path);
54
+
55
+ qts = qtest_initf("-chardev socket,id=s0,path=%s,nowait "
56
+ "-serial chardev:s0 %s",
57
+ sock_path, extra_args);
58
+
59
+ *sock_fd = socket_accept(sock_fd_init);
60
+
61
+ unlink(sock_path);
62
+ g_free(sock_path);
63
+ rmdir(sock_dir);
64
+
65
+ g_assert(*sock_fd >= 0);
66
+
67
+ return qts;
68
+}
69
+
70
void qtest_quit(QTestState *s)
71
{
72
g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
73
--
64
--
74
2.20.1
65
2.25.1
75
76
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
Because of the PMU's design, many register accesses have side effects
3
Add the Cortex-R5Fs of the Versal RPU (Real-time Processing Unit)
4
which are inter-related, meaning that the normal method of saving CP
4
subsystem.
5
registers can result in inconsistent state. These side-effects are
6
largely handled in pmu_op_start/finish functions which can be called
7
before and after the state is saved/restored. By doing this and adding
8
raw read/write functions for the affected registers, we avoid
9
migration-related inconsistencies.
10
5
11
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
6
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
12
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20220406174303.2022038-3-edgar.iglesias@xilinx.com
14
Message-id: 20181211151945.29137-4-aaron@os.amperecomputing.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
10
---
17
target/arm/helper.c | 6 ++++--
11
include/hw/arm/xlnx-versal.h | 10 ++++++++++
18
target/arm/machine.c | 24 ++++++++++++++++++++++++
12
hw/arm/xlnx-versal-virt.c | 6 +++---
19
2 files changed, 28 insertions(+), 2 deletions(-)
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++++++++++
14
3 files changed, 49 insertions(+), 3 deletions(-)
20
15
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
22
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
18
--- a/include/hw/arm/xlnx-versal.h
24
+++ b/target/arm/helper.c
19
+++ b/include/hw/arm/xlnx-versal.h
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
20
@@ -XXX,XX +XXX,XX @@
26
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
21
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
27
.access = PL0_RW, .accessfn = pmreg_access_ccntr,
22
28
.type = ARM_CP_IO,
23
#define XLNX_VERSAL_NR_ACPUS 2
29
- .readfn = pmccntr_read, .writefn = pmccntr_write, },
24
+#define XLNX_VERSAL_NR_RCPUS 2
30
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
25
#define XLNX_VERSAL_NR_UARTS 2
31
+ .readfn = pmccntr_read, .writefn = pmccntr_write,
26
#define XLNX_VERSAL_NR_GEMS 2
32
+ .raw_readfn = raw_read, .raw_writefn = raw_write, },
27
#define XLNX_VERSAL_NR_ADMAS 8
33
#endif
28
@@ -XXX,XX +XXX,XX @@ struct Versal {
34
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
29
VersalUsb2 usb;
35
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
30
} iou;
36
- .writefn = pmccfiltr_write,
31
37
+ .writefn = pmccfiltr_write, .raw_writefn = raw_write,
32
+ /* Real-time Processing Unit. */
38
.access = PL0_RW, .accessfn = pmreg_access,
33
+ struct {
39
.type = ARM_CP_IO,
34
+ MemoryRegion mr;
40
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
35
+ MemoryRegion mr_ps_alias;
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
36
+
37
+ CPUClusterState cluster;
38
+ ARMCPU cpu[XLNX_VERSAL_NR_RCPUS];
39
+ } rpu;
40
+
41
struct {
42
qemu_or_irq irq_orgate;
43
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
44
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
42
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/machine.c
46
--- a/hw/arm/xlnx-versal-virt.c
44
+++ b/target/arm/machine.c
47
+++ b/hw/arm/xlnx-versal-virt.c
45
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
48
@@ -XXX,XX +XXX,XX @@ static void versal_virt_machine_class_init(ObjectClass *oc, void *data)
46
{
49
47
ARMCPU *cpu = opaque;
50
mc->desc = "Xilinx Versal Virtual development board";
48
51
mc->init = versal_virt_init;
49
+ if (!kvm_enabled()) {
52
- mc->min_cpus = XLNX_VERSAL_NR_ACPUS;
50
+ pmu_op_start(&cpu->env);
53
- mc->max_cpus = XLNX_VERSAL_NR_ACPUS;
54
- mc->default_cpus = XLNX_VERSAL_NR_ACPUS;
55
+ mc->min_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
56
+ mc->max_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
57
+ mc->default_cpus = XLNX_VERSAL_NR_ACPUS + XLNX_VERSAL_NR_RCPUS;
58
mc->no_cdrom = true;
59
mc->default_ram_id = "ddr";
60
}
61
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/xlnx-versal.c
64
+++ b/hw/arm/xlnx-versal.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/sysbus.h"
67
68
#define XLNX_VERSAL_ACPU_TYPE ARM_CPU_TYPE_NAME("cortex-a72")
69
+#define XLNX_VERSAL_RCPU_TYPE ARM_CPU_TYPE_NAME("cortex-r5f")
70
#define GEM_REVISION 0x40070106
71
72
#define VERSAL_NUM_PMC_APB_IRQS 3
73
@@ -XXX,XX +XXX,XX @@ static void versal_create_apu_gic(Versal *s, qemu_irq *pic)
74
}
75
}
76
77
+static void versal_create_rpu_cpus(Versal *s)
78
+{
79
+ int i;
80
+
81
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->lpd.rpu.cluster,
82
+ TYPE_CPU_CLUSTER);
83
+ qdev_prop_set_uint32(DEVICE(&s->lpd.rpu.cluster), "cluster-id", 1);
84
+
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
86
+ Object *obj;
87
+
88
+ object_initialize_child(OBJECT(&s->lpd.rpu.cluster),
89
+ "rpu-cpu[*]", &s->lpd.rpu.cpu[i],
90
+ XLNX_VERSAL_RCPU_TYPE);
91
+ obj = OBJECT(&s->lpd.rpu.cpu[i]);
92
+ object_property_set_bool(obj, "start-powered-off", true,
93
+ &error_abort);
94
+
95
+ object_property_set_int(obj, "mp-affinity", 0x100 | i, &error_abort);
96
+ object_property_set_int(obj, "core-count", ARRAY_SIZE(s->lpd.rpu.cpu),
97
+ &error_abort);
98
+ object_property_set_link(obj, "memory", OBJECT(&s->lpd.rpu.mr),
99
+ &error_abort);
100
+ qdev_realize(DEVICE(obj), NULL, &error_fatal);
51
+ }
101
+ }
52
+
102
+
53
if (kvm_enabled()) {
103
+ qdev_realize(DEVICE(&s->lpd.rpu.cluster), NULL, &error_fatal);
54
if (!write_kvmstate_to_list(cpu)) {
55
/* This should never fail */
56
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
57
return 0;
58
}
59
60
+static int cpu_post_save(void *opaque)
61
+{
62
+ ARMCPU *cpu = opaque;
63
+
64
+ if (!kvm_enabled()) {
65
+ pmu_op_finish(&cpu->env);
66
+ }
67
+
68
+ return 0;
69
+}
104
+}
70
+
105
+
71
static int cpu_pre_load(void *opaque)
106
static void versal_create_uarts(Versal *s, qemu_irq *pic)
72
{
107
{
73
ARMCPU *cpu = opaque;
108
int i;
74
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_load(void *opaque)
109
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
75
*/
110
76
env->irq_line_state = UINT32_MAX;
111
versal_create_apu_cpus(s);
77
112
versal_create_apu_gic(s, pic);
78
+ if (!kvm_enabled()) {
113
+ versal_create_rpu_cpus(s);
79
+ pmu_op_start(&cpu->env);
114
versal_create_uarts(s, pic);
80
+ }
115
versal_create_usbs(s, pic);
81
+
116
versal_create_gems(s, pic);
82
return 0;
117
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
118
119
memory_region_add_subregion_overlap(&s->mr_ps, MM_OCM, &s->lpd.mr_ocm, 0);
120
memory_region_add_subregion_overlap(&s->fpd.apu.mr, 0, &s->mr_ps, 0);
121
+ memory_region_add_subregion_overlap(&s->lpd.rpu.mr, 0,
122
+ &s->lpd.rpu.mr_ps_alias, 0);
83
}
123
}
84
124
85
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
125
static void versal_init(Object *obj)
86
hw_breakpoint_update_all(cpu);
126
@@ -XXX,XX +XXX,XX @@ static void versal_init(Object *obj)
87
hw_watchpoint_update_all(cpu);
127
Versal *s = XLNX_VERSAL(obj);
88
128
89
+ if (!kvm_enabled()) {
129
memory_region_init(&s->fpd.apu.mr, obj, "mr-apu", UINT64_MAX);
90
+ pmu_op_finish(&cpu->env);
130
+ memory_region_init(&s->lpd.rpu.mr, obj, "mr-rpu", UINT64_MAX);
91
+ }
131
memory_region_init(&s->mr_ps, obj, "mr-ps-switch", UINT64_MAX);
92
+
132
+ memory_region_init_alias(&s->lpd.rpu.mr_ps_alias, OBJECT(s),
93
return 0;
133
+ "mr-rpu-ps-alias", &s->mr_ps, 0, UINT64_MAX);
94
}
134
}
95
135
96
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
136
static Property versal_properties[] = {
97
.version_id = 22,
98
.minimum_version_id = 22,
99
.pre_save = cpu_pre_save,
100
+ .post_save = cpu_post_save,
101
.pre_load = cpu_pre_load,
102
.post_load = cpu_post_load,
103
.fields = (VMStateField[]) {
104
--
137
--
105
2.20.1
138
2.25.1
106
107
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
The cryptographic internals are stubbed out for now,
3
Add a model of the Xilinx Versal CRL.
4
but the enable and trap bits are checked.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
8
Message-id: 20190108223129.5570-6-richard.henderson@linaro.org
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-4-edgar.iglesias@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/Makefile.objs | 1 +
11
include/hw/misc/xlnx-versal-crl.h | 235 +++++++++++++++++
12
target/arm/helper-a64.h | 12 +++
12
hw/misc/xlnx-versal-crl.c | 421 ++++++++++++++++++++++++++++++
13
target/arm/internals.h | 6 ++
13
hw/misc/meson.build | 1 +
14
target/arm/pauth_helper.c | 186 ++++++++++++++++++++++++++++++++++++++
14
3 files changed, 657 insertions(+)
15
4 files changed, 205 insertions(+)
15
create mode 100644 include/hw/misc/xlnx-versal-crl.h
16
create mode 100644 target/arm/pauth_helper.c
16
create mode 100644 hw/misc/xlnx-versal-crl.c
17
17
18
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
18
diff --git a/include/hw/misc/xlnx-versal-crl.h b/include/hw/misc/xlnx-versal-crl.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/Makefile.objs
21
+++ b/target/arm/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@ obj-y += translate.o op_helper.o helper.o cpu.o
23
obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o
24
obj-y += gdbstub.o
25
obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
26
+obj-$(TARGET_AARCH64) += pauth_helper.o
27
obj-y += crypto_helper.o
28
obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
29
30
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper-a64.h
33
+++ b/target/arm/helper-a64.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
35
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
36
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
37
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
38
+
39
+DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
40
+DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
41
+DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
42
+DEF_HELPER_FLAGS_3(pacdb, TCG_CALL_NO_WG, i64, env, i64, i64)
43
+DEF_HELPER_FLAGS_3(pacga, TCG_CALL_NO_WG, i64, env, i64, i64)
44
+DEF_HELPER_FLAGS_3(autia, TCG_CALL_NO_WG, i64, env, i64, i64)
45
+DEF_HELPER_FLAGS_3(autib, TCG_CALL_NO_WG, i64, env, i64, i64)
46
+DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, i64)
47
+DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
48
+DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
49
+DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
50
diff --git a/target/arm/internals.h b/target/arm/internals.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/internals.h
53
+++ b/target/arm/internals.h
54
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
55
EC_CP14DTTRAP = 0x06,
56
EC_ADVSIMDFPACCESSTRAP = 0x07,
57
EC_FPIDTRAP = 0x08,
58
+ EC_PACTRAP = 0x09,
59
EC_CP14RRTTRAP = 0x0c,
60
EC_ILLEGALSTATE = 0x0e,
61
EC_AA32_SVC = 0x11,
62
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
63
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
64
}
65
66
+static inline uint32_t syn_pactrap(void)
67
+{
68
+ return EC_PACTRAP << ARM_EL_EC_SHIFT;
69
+}
70
+
71
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
72
{
73
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
74
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
75
new file mode 100644
19
new file mode 100644
76
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
77
--- /dev/null
21
--- /dev/null
78
+++ b/target/arm/pauth_helper.c
22
+++ b/include/hw/misc/xlnx-versal-crl.h
79
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
80
+/*
24
+/*
81
+ * ARM v8.3-PAuth Operations
25
+ * QEMU model of the Clock-Reset-LPD (CRL).
82
+ *
26
+ *
83
+ * Copyright (c) 2019 Linaro, Ltd.
27
+ * Copyright (c) 2022 Xilinx Inc.
28
+ * SPDX-License-Identifier: GPL-2.0-or-later
84
+ *
29
+ *
85
+ * This library is free software; you can redistribute it and/or
30
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
86
+ * modify it under the terms of the GNU Lesser General Public
31
+ */
87
+ * License as published by the Free Software Foundation; either
32
+#ifndef HW_MISC_XLNX_VERSAL_CRL_H
88
+ * version 2 of the License, or (at your option) any later version.
33
+#define HW_MISC_XLNX_VERSAL_CRL_H
34
+
35
+#include "hw/sysbus.h"
36
+#include "hw/register.h"
37
+#include "target/arm/cpu.h"
38
+
39
+#define TYPE_XLNX_VERSAL_CRL "xlnx,versal-crl"
40
+OBJECT_DECLARE_SIMPLE_TYPE(XlnxVersalCRL, XLNX_VERSAL_CRL)
41
+
42
+REG32(ERR_CTRL, 0x0)
43
+ FIELD(ERR_CTRL, SLVERR_ENABLE, 0, 1)
44
+REG32(IR_STATUS, 0x4)
45
+ FIELD(IR_STATUS, ADDR_DECODE_ERR, 0, 1)
46
+REG32(IR_MASK, 0x8)
47
+ FIELD(IR_MASK, ADDR_DECODE_ERR, 0, 1)
48
+REG32(IR_ENABLE, 0xc)
49
+ FIELD(IR_ENABLE, ADDR_DECODE_ERR, 0, 1)
50
+REG32(IR_DISABLE, 0x10)
51
+ FIELD(IR_DISABLE, ADDR_DECODE_ERR, 0, 1)
52
+REG32(WPROT, 0x1c)
53
+ FIELD(WPROT, ACTIVE, 0, 1)
54
+REG32(PLL_CLK_OTHER_DMN, 0x20)
55
+ FIELD(PLL_CLK_OTHER_DMN, APLL_BYPASS, 0, 1)
56
+REG32(RPLL_CTRL, 0x40)
57
+ FIELD(RPLL_CTRL, POST_SRC, 24, 3)
58
+ FIELD(RPLL_CTRL, PRE_SRC, 20, 3)
59
+ FIELD(RPLL_CTRL, CLKOUTDIV, 16, 2)
60
+ FIELD(RPLL_CTRL, FBDIV, 8, 8)
61
+ FIELD(RPLL_CTRL, BYPASS, 3, 1)
62
+ FIELD(RPLL_CTRL, RESET, 0, 1)
63
+REG32(RPLL_CFG, 0x44)
64
+ FIELD(RPLL_CFG, LOCK_DLY, 25, 7)
65
+ FIELD(RPLL_CFG, LOCK_CNT, 13, 10)
66
+ FIELD(RPLL_CFG, LFHF, 10, 2)
67
+ FIELD(RPLL_CFG, CP, 5, 4)
68
+ FIELD(RPLL_CFG, RES, 0, 4)
69
+REG32(RPLL_FRAC_CFG, 0x48)
70
+ FIELD(RPLL_FRAC_CFG, ENABLED, 31, 1)
71
+ FIELD(RPLL_FRAC_CFG, SEED, 22, 3)
72
+ FIELD(RPLL_FRAC_CFG, ALGRTHM, 19, 1)
73
+ FIELD(RPLL_FRAC_CFG, ORDER, 18, 1)
74
+ FIELD(RPLL_FRAC_CFG, DATA, 0, 16)
75
+REG32(PLL_STATUS, 0x50)
76
+ FIELD(PLL_STATUS, RPLL_STABLE, 2, 1)
77
+ FIELD(PLL_STATUS, RPLL_LOCK, 0, 1)
78
+REG32(RPLL_TO_XPD_CTRL, 0x100)
79
+ FIELD(RPLL_TO_XPD_CTRL, CLKACT, 25, 1)
80
+ FIELD(RPLL_TO_XPD_CTRL, DIVISOR0, 8, 10)
81
+REG32(LPD_TOP_SWITCH_CTRL, 0x104)
82
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT_ADMA, 26, 1)
83
+ FIELD(LPD_TOP_SWITCH_CTRL, CLKACT, 25, 1)
84
+ FIELD(LPD_TOP_SWITCH_CTRL, DIVISOR0, 8, 10)
85
+ FIELD(LPD_TOP_SWITCH_CTRL, SRCSEL, 0, 3)
86
+REG32(LPD_LSBUS_CTRL, 0x108)
87
+ FIELD(LPD_LSBUS_CTRL, CLKACT, 25, 1)
88
+ FIELD(LPD_LSBUS_CTRL, DIVISOR0, 8, 10)
89
+ FIELD(LPD_LSBUS_CTRL, SRCSEL, 0, 3)
90
+REG32(CPU_R5_CTRL, 0x10c)
91
+ FIELD(CPU_R5_CTRL, CLKACT_OCM2, 28, 1)
92
+ FIELD(CPU_R5_CTRL, CLKACT_OCM, 27, 1)
93
+ FIELD(CPU_R5_CTRL, CLKACT_CORE, 26, 1)
94
+ FIELD(CPU_R5_CTRL, CLKACT, 25, 1)
95
+ FIELD(CPU_R5_CTRL, DIVISOR0, 8, 10)
96
+ FIELD(CPU_R5_CTRL, SRCSEL, 0, 3)
97
+REG32(IOU_SWITCH_CTRL, 0x114)
98
+ FIELD(IOU_SWITCH_CTRL, CLKACT, 25, 1)
99
+ FIELD(IOU_SWITCH_CTRL, DIVISOR0, 8, 10)
100
+ FIELD(IOU_SWITCH_CTRL, SRCSEL, 0, 3)
101
+REG32(GEM0_REF_CTRL, 0x118)
102
+ FIELD(GEM0_REF_CTRL, CLKACT_RX, 27, 1)
103
+ FIELD(GEM0_REF_CTRL, CLKACT_TX, 26, 1)
104
+ FIELD(GEM0_REF_CTRL, CLKACT, 25, 1)
105
+ FIELD(GEM0_REF_CTRL, DIVISOR0, 8, 10)
106
+ FIELD(GEM0_REF_CTRL, SRCSEL, 0, 3)
107
+REG32(GEM1_REF_CTRL, 0x11c)
108
+ FIELD(GEM1_REF_CTRL, CLKACT_RX, 27, 1)
109
+ FIELD(GEM1_REF_CTRL, CLKACT_TX, 26, 1)
110
+ FIELD(GEM1_REF_CTRL, CLKACT, 25, 1)
111
+ FIELD(GEM1_REF_CTRL, DIVISOR0, 8, 10)
112
+ FIELD(GEM1_REF_CTRL, SRCSEL, 0, 3)
113
+REG32(GEM_TSU_REF_CTRL, 0x120)
114
+ FIELD(GEM_TSU_REF_CTRL, CLKACT, 25, 1)
115
+ FIELD(GEM_TSU_REF_CTRL, DIVISOR0, 8, 10)
116
+ FIELD(GEM_TSU_REF_CTRL, SRCSEL, 0, 3)
117
+REG32(USB0_BUS_REF_CTRL, 0x124)
118
+ FIELD(USB0_BUS_REF_CTRL, CLKACT, 25, 1)
119
+ FIELD(USB0_BUS_REF_CTRL, DIVISOR0, 8, 10)
120
+ FIELD(USB0_BUS_REF_CTRL, SRCSEL, 0, 3)
121
+REG32(UART0_REF_CTRL, 0x128)
122
+ FIELD(UART0_REF_CTRL, CLKACT, 25, 1)
123
+ FIELD(UART0_REF_CTRL, DIVISOR0, 8, 10)
124
+ FIELD(UART0_REF_CTRL, SRCSEL, 0, 3)
125
+REG32(UART1_REF_CTRL, 0x12c)
126
+ FIELD(UART1_REF_CTRL, CLKACT, 25, 1)
127
+ FIELD(UART1_REF_CTRL, DIVISOR0, 8, 10)
128
+ FIELD(UART1_REF_CTRL, SRCSEL, 0, 3)
129
+REG32(SPI0_REF_CTRL, 0x130)
130
+ FIELD(SPI0_REF_CTRL, CLKACT, 25, 1)
131
+ FIELD(SPI0_REF_CTRL, DIVISOR0, 8, 10)
132
+ FIELD(SPI0_REF_CTRL, SRCSEL, 0, 3)
133
+REG32(SPI1_REF_CTRL, 0x134)
134
+ FIELD(SPI1_REF_CTRL, CLKACT, 25, 1)
135
+ FIELD(SPI1_REF_CTRL, DIVISOR0, 8, 10)
136
+ FIELD(SPI1_REF_CTRL, SRCSEL, 0, 3)
137
+REG32(CAN0_REF_CTRL, 0x138)
138
+ FIELD(CAN0_REF_CTRL, CLKACT, 25, 1)
139
+ FIELD(CAN0_REF_CTRL, DIVISOR0, 8, 10)
140
+ FIELD(CAN0_REF_CTRL, SRCSEL, 0, 3)
141
+REG32(CAN1_REF_CTRL, 0x13c)
142
+ FIELD(CAN1_REF_CTRL, CLKACT, 25, 1)
143
+ FIELD(CAN1_REF_CTRL, DIVISOR0, 8, 10)
144
+ FIELD(CAN1_REF_CTRL, SRCSEL, 0, 3)
145
+REG32(I2C0_REF_CTRL, 0x140)
146
+ FIELD(I2C0_REF_CTRL, CLKACT, 25, 1)
147
+ FIELD(I2C0_REF_CTRL, DIVISOR0, 8, 10)
148
+ FIELD(I2C0_REF_CTRL, SRCSEL, 0, 3)
149
+REG32(I2C1_REF_CTRL, 0x144)
150
+ FIELD(I2C1_REF_CTRL, CLKACT, 25, 1)
151
+ FIELD(I2C1_REF_CTRL, DIVISOR0, 8, 10)
152
+ FIELD(I2C1_REF_CTRL, SRCSEL, 0, 3)
153
+REG32(DBG_LPD_CTRL, 0x148)
154
+ FIELD(DBG_LPD_CTRL, CLKACT, 25, 1)
155
+ FIELD(DBG_LPD_CTRL, DIVISOR0, 8, 10)
156
+ FIELD(DBG_LPD_CTRL, SRCSEL, 0, 3)
157
+REG32(TIMESTAMP_REF_CTRL, 0x14c)
158
+ FIELD(TIMESTAMP_REF_CTRL, CLKACT, 25, 1)
159
+ FIELD(TIMESTAMP_REF_CTRL, DIVISOR0, 8, 10)
160
+ FIELD(TIMESTAMP_REF_CTRL, SRCSEL, 0, 3)
161
+REG32(CRL_SAFETY_CHK, 0x150)
162
+REG32(PSM_REF_CTRL, 0x154)
163
+ FIELD(PSM_REF_CTRL, DIVISOR0, 8, 10)
164
+ FIELD(PSM_REF_CTRL, SRCSEL, 0, 3)
165
+REG32(DBG_TSTMP_CTRL, 0x158)
166
+ FIELD(DBG_TSTMP_CTRL, CLKACT, 25, 1)
167
+ FIELD(DBG_TSTMP_CTRL, DIVISOR0, 8, 10)
168
+ FIELD(DBG_TSTMP_CTRL, SRCSEL, 0, 3)
169
+REG32(CPM_TOPSW_REF_CTRL, 0x15c)
170
+ FIELD(CPM_TOPSW_REF_CTRL, CLKACT, 25, 1)
171
+ FIELD(CPM_TOPSW_REF_CTRL, DIVISOR0, 8, 10)
172
+ FIELD(CPM_TOPSW_REF_CTRL, SRCSEL, 0, 3)
173
+REG32(USB3_DUAL_REF_CTRL, 0x160)
174
+ FIELD(USB3_DUAL_REF_CTRL, CLKACT, 25, 1)
175
+ FIELD(USB3_DUAL_REF_CTRL, DIVISOR0, 8, 10)
176
+ FIELD(USB3_DUAL_REF_CTRL, SRCSEL, 0, 3)
177
+REG32(RST_CPU_R5, 0x300)
178
+ FIELD(RST_CPU_R5, RESET_PGE, 4, 1)
179
+ FIELD(RST_CPU_R5, RESET_AMBA, 2, 1)
180
+ FIELD(RST_CPU_R5, RESET_CPU1, 1, 1)
181
+ FIELD(RST_CPU_R5, RESET_CPU0, 0, 1)
182
+REG32(RST_ADMA, 0x304)
183
+ FIELD(RST_ADMA, RESET, 0, 1)
184
+REG32(RST_GEM0, 0x308)
185
+ FIELD(RST_GEM0, RESET, 0, 1)
186
+REG32(RST_GEM1, 0x30c)
187
+ FIELD(RST_GEM1, RESET, 0, 1)
188
+REG32(RST_SPARE, 0x310)
189
+ FIELD(RST_SPARE, RESET, 0, 1)
190
+REG32(RST_USB0, 0x314)
191
+ FIELD(RST_USB0, RESET, 0, 1)
192
+REG32(RST_UART0, 0x318)
193
+ FIELD(RST_UART0, RESET, 0, 1)
194
+REG32(RST_UART1, 0x31c)
195
+ FIELD(RST_UART1, RESET, 0, 1)
196
+REG32(RST_SPI0, 0x320)
197
+ FIELD(RST_SPI0, RESET, 0, 1)
198
+REG32(RST_SPI1, 0x324)
199
+ FIELD(RST_SPI1, RESET, 0, 1)
200
+REG32(RST_CAN0, 0x328)
201
+ FIELD(RST_CAN0, RESET, 0, 1)
202
+REG32(RST_CAN1, 0x32c)
203
+ FIELD(RST_CAN1, RESET, 0, 1)
204
+REG32(RST_I2C0, 0x330)
205
+ FIELD(RST_I2C0, RESET, 0, 1)
206
+REG32(RST_I2C1, 0x334)
207
+ FIELD(RST_I2C1, RESET, 0, 1)
208
+REG32(RST_DBG_LPD, 0x338)
209
+ FIELD(RST_DBG_LPD, RPU_DBG1_RESET, 5, 1)
210
+ FIELD(RST_DBG_LPD, RPU_DBG0_RESET, 4, 1)
211
+ FIELD(RST_DBG_LPD, RESET_HSDP, 1, 1)
212
+ FIELD(RST_DBG_LPD, RESET, 0, 1)
213
+REG32(RST_GPIO, 0x33c)
214
+ FIELD(RST_GPIO, RESET, 0, 1)
215
+REG32(RST_TTC, 0x344)
216
+ FIELD(RST_TTC, TTC3_RESET, 3, 1)
217
+ FIELD(RST_TTC, TTC2_RESET, 2, 1)
218
+ FIELD(RST_TTC, TTC1_RESET, 1, 1)
219
+ FIELD(RST_TTC, TTC0_RESET, 0, 1)
220
+REG32(RST_TIMESTAMP, 0x348)
221
+ FIELD(RST_TIMESTAMP, RESET, 0, 1)
222
+REG32(RST_SWDT, 0x34c)
223
+ FIELD(RST_SWDT, RESET, 0, 1)
224
+REG32(RST_OCM, 0x350)
225
+ FIELD(RST_OCM, RESET, 0, 1)
226
+REG32(RST_IPI, 0x354)
227
+ FIELD(RST_IPI, RESET, 0, 1)
228
+REG32(RST_SYSMON, 0x358)
229
+ FIELD(RST_SYSMON, SEQ_RST, 1, 1)
230
+ FIELD(RST_SYSMON, CFG_RST, 0, 1)
231
+REG32(RST_FPD, 0x360)
232
+ FIELD(RST_FPD, SRST, 1, 1)
233
+ FIELD(RST_FPD, POR, 0, 1)
234
+REG32(PSM_RST_MODE, 0x370)
235
+ FIELD(PSM_RST_MODE, WAKEUP, 2, 1)
236
+ FIELD(PSM_RST_MODE, RST_MODE, 0, 2)
237
+
238
+#define CRL_R_MAX (R_PSM_RST_MODE + 1)
239
+
240
+#define RPU_MAX_CPU 2
241
+
242
+struct XlnxVersalCRL {
243
+ SysBusDevice parent_obj;
244
+ qemu_irq irq;
245
+
246
+ struct {
247
+ ARMCPU *cpu_r5[RPU_MAX_CPU];
248
+ DeviceState *adma[8];
249
+ DeviceState *uart[2];
250
+ DeviceState *gem[2];
251
+ DeviceState *usb;
252
+ } cfg;
253
+
254
+ RegisterInfoArray *reg_array;
255
+ uint32_t regs[CRL_R_MAX];
256
+ RegisterInfo regs_info[CRL_R_MAX];
257
+};
258
+#endif
259
diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c
260
new file mode 100644
261
index XXXXXXX..XXXXXXX
262
--- /dev/null
263
+++ b/hw/misc/xlnx-versal-crl.c
264
@@ -XXX,XX +XXX,XX @@
265
+/*
266
+ * QEMU model of the Clock-Reset-LPD (CRL).
89
+ *
267
+ *
90
+ * This library is distributed in the hope that it will be useful,
268
+ * Copyright (c) 2022 Advanced Micro Devices, Inc.
91
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
269
+ * SPDX-License-Identifier: GPL-2.0-or-later
92
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
93
+ * Lesser General Public License for more details.
94
+ *
270
+ *
95
+ * You should have received a copy of the GNU Lesser General Public
271
+ * Written by Edgar E. Iglesias <edgar.iglesias@amd.com>
96
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
97
+ */
272
+ */
98
+
273
+
99
+#include "qemu/osdep.h"
274
+#include "qemu/osdep.h"
100
+#include "cpu.h"
275
+#include "qapi/error.h"
101
+#include "internals.h"
276
+#include "qemu/log.h"
102
+#include "exec/exec-all.h"
277
+#include "qemu/bitops.h"
103
+#include "exec/cpu_ldst.h"
278
+#include "migration/vmstate.h"
104
+#include "exec/helper-proto.h"
279
+#include "hw/qdev-properties.h"
105
+#include "tcg/tcg-gvec-desc.h"
280
+#include "hw/sysbus.h"
106
+
281
+#include "hw/irq.h"
107
+
282
+#include "hw/register.h"
108
+static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
283
+#include "hw/resettable.h"
109
+ ARMPACKey key)
284
+
110
+{
285
+#include "target/arm/arm-powerctl.h"
111
+ g_assert_not_reached(); /* FIXME */
286
+#include "hw/misc/xlnx-versal-crl.h"
112
+}
287
+
113
+
288
+#ifndef XLNX_VERSAL_CRL_ERR_DEBUG
114
+static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
289
+#define XLNX_VERSAL_CRL_ERR_DEBUG 0
115
+ ARMPACKey *key, bool data)
290
+#endif
116
+{
291
+
117
+ g_assert_not_reached(); /* FIXME */
292
+static void crl_update_irq(XlnxVersalCRL *s)
118
+}
293
+{
119
+
294
+ bool pending = s->regs[R_IR_STATUS] & ~s->regs[R_IR_MASK];
120
+static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
295
+ qemu_set_irq(s->irq, pending);
121
+ ARMPACKey *key, bool data, int keynumber)
296
+}
122
+{
297
+
123
+ g_assert_not_reached(); /* FIXME */
298
+static void crl_status_postw(RegisterInfo *reg, uint64_t val64)
124
+}
299
+{
125
+
300
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
126
+static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
301
+ crl_update_irq(s);
127
+{
302
+}
128
+ g_assert_not_reached(); /* FIXME */
303
+
129
+}
304
+static uint64_t crl_enable_prew(RegisterInfo *reg, uint64_t val64)
130
+
305
+{
131
+static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
306
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
132
+ uintptr_t ra)
307
+ uint32_t val = val64;
133
+{
308
+
134
+ raise_exception_ra(env, EXCP_UDEF, syn_pactrap(), target_el, ra);
309
+ s->regs[R_IR_MASK] &= ~val;
135
+}
310
+ crl_update_irq(s);
136
+
311
+ return 0;
137
+static void pauth_check_trap(CPUARMState *env, int el, uintptr_t ra)
312
+}
138
+{
313
+
139
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
314
+static uint64_t crl_disable_prew(RegisterInfo *reg, uint64_t val64)
140
+ uint64_t hcr = arm_hcr_el2_eff(env);
315
+{
141
+ bool trap = !(hcr & HCR_API);
316
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
142
+ /* FIXME: ARMv8.1-VHE: trap only applies to EL1&0 regime. */
317
+ uint32_t val = val64;
143
+ /* FIXME: ARMv8.3-NV: HCR_NV trap takes precedence for ERETA[AB]. */
318
+
144
+ if (trap) {
319
+ s->regs[R_IR_MASK] |= val;
145
+ pauth_trap(env, 2, ra);
320
+ crl_update_irq(s);
146
+ }
321
+ return 0;
147
+ }
322
+}
148
+ if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
323
+
149
+ if (!(env->cp15.scr_el3 & SCR_API)) {
324
+static void crl_reset_dev(XlnxVersalCRL *s, DeviceState *dev,
150
+ pauth_trap(env, 3, ra);
325
+ bool rst_old, bool rst_new)
151
+ }
326
+{
152
+ }
327
+ device_cold_reset(dev);
153
+}
328
+}
154
+
329
+
155
+static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
330
+static void crl_reset_cpu(XlnxVersalCRL *s, ARMCPU *armcpu,
156
+{
331
+ bool rst_old, bool rst_new)
157
+ uint32_t sctlr;
332
+{
158
+ if (el == 0) {
333
+ if (rst_new) {
159
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
334
+ arm_set_cpu_off(armcpu->mp_affinity);
160
+ sctlr = env->cp15.sctlr_el[1];
161
+ } else {
335
+ } else {
162
+ sctlr = env->cp15.sctlr_el[el];
336
+ arm_set_cpu_on_and_reset(armcpu->mp_affinity);
163
+ }
337
+ }
164
+ return (sctlr & bit) != 0;
338
+}
165
+}
339
+
166
+
340
+#define REGFIELD_RESET(type, s, reg, f, new_val, dev) { \
167
+uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
341
+ bool old_f = ARRAY_FIELD_EX32((s)->regs, reg, f); \
168
+{
342
+ bool new_f = FIELD_EX32(new_val, reg, f); \
169
+ int el = arm_current_el(env);
343
+ \
170
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
344
+ /* Detect edges. */ \
171
+ return x;
345
+ if (dev && old_f != new_f) { \
172
+ }
346
+ crl_reset_ ## type(s, dev, old_f, new_f); \
173
+ pauth_check_trap(env, el, GETPC());
347
+ } \
174
+ return pauth_addpac(env, x, y, &env->apia_key, false);
348
+}
175
+}
349
+
176
+
350
+static uint64_t crl_rst_r5_prew(RegisterInfo *reg, uint64_t val64)
177
+uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
351
+{
178
+{
352
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
179
+ int el = arm_current_el(env);
353
+
180
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
354
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU0, val64, s->cfg.cpu_r5[0]);
181
+ return x;
355
+ REGFIELD_RESET(cpu, s, RST_CPU_R5, RESET_CPU1, val64, s->cfg.cpu_r5[1]);
182
+ }
356
+ return val64;
183
+ pauth_check_trap(env, el, GETPC());
357
+}
184
+ return pauth_addpac(env, x, y, &env->apib_key, false);
358
+
185
+}
359
+static uint64_t crl_rst_adma_prew(RegisterInfo *reg, uint64_t val64)
186
+
360
+{
187
+uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
361
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
188
+{
362
+ int i;
189
+ int el = arm_current_el(env);
363
+
190
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
364
+ /* A single register fans out to all ADMA reset inputs. */
191
+ return x;
365
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); i++) {
192
+ }
366
+ REGFIELD_RESET(dev, s, RST_ADMA, RESET, val64, s->cfg.adma[i]);
193
+ pauth_check_trap(env, el, GETPC());
367
+ }
194
+ return pauth_addpac(env, x, y, &env->apda_key, true);
368
+ return val64;
195
+}
369
+}
196
+
370
+
197
+uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
371
+static uint64_t crl_rst_uart0_prew(RegisterInfo *reg, uint64_t val64)
198
+{
372
+{
199
+ int el = arm_current_el(env);
373
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
200
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
374
+
201
+ return x;
375
+ REGFIELD_RESET(dev, s, RST_UART0, RESET, val64, s->cfg.uart[0]);
202
+ }
376
+ return val64;
203
+ pauth_check_trap(env, el, GETPC());
377
+}
204
+ return pauth_addpac(env, x, y, &env->apdb_key, true);
378
+
205
+}
379
+static uint64_t crl_rst_uart1_prew(RegisterInfo *reg, uint64_t val64)
206
+
380
+{
207
+uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
381
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
208
+{
382
+
209
+ uint64_t pac;
383
+ REGFIELD_RESET(dev, s, RST_UART1, RESET, val64, s->cfg.uart[1]);
210
+
384
+ return val64;
211
+ pauth_check_trap(env, arm_current_el(env), GETPC());
385
+}
212
+ pac = pauth_computepac(x, y, env->apga_key);
386
+
213
+
387
+static uint64_t crl_rst_gem0_prew(RegisterInfo *reg, uint64_t val64)
214
+ return pac & 0xffffffff00000000ull;
388
+{
215
+}
389
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
216
+
390
+
217
+uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
391
+ REGFIELD_RESET(dev, s, RST_GEM0, RESET, val64, s->cfg.gem[0]);
218
+{
392
+ return val64;
219
+ int el = arm_current_el(env);
393
+}
220
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
394
+
221
+ return x;
395
+static uint64_t crl_rst_gem1_prew(RegisterInfo *reg, uint64_t val64)
222
+ }
396
+{
223
+ pauth_check_trap(env, el, GETPC());
397
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
224
+ return pauth_auth(env, x, y, &env->apia_key, false, 0);
398
+
225
+}
399
+ REGFIELD_RESET(dev, s, RST_GEM1, RESET, val64, s->cfg.gem[1]);
226
+
400
+ return val64;
227
+uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
401
+}
228
+{
402
+
229
+ int el = arm_current_el(env);
403
+static uint64_t crl_rst_usb_prew(RegisterInfo *reg, uint64_t val64)
230
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
404
+{
231
+ return x;
405
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(reg->opaque);
232
+ }
406
+
233
+ pauth_check_trap(env, el, GETPC());
407
+ REGFIELD_RESET(dev, s, RST_USB0, RESET, val64, s->cfg.usb);
234
+ return pauth_auth(env, x, y, &env->apib_key, false, 1);
408
+ return val64;
235
+}
409
+}
236
+
410
+
237
+uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
411
+static const RegisterAccessInfo crl_regs_info[] = {
238
+{
412
+ { .name = "ERR_CTRL", .addr = A_ERR_CTRL,
239
+ int el = arm_current_el(env);
413
+ },{ .name = "IR_STATUS", .addr = A_IR_STATUS,
240
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
414
+ .w1c = 0x1,
241
+ return x;
415
+ .post_write = crl_status_postw,
242
+ }
416
+ },{ .name = "IR_MASK", .addr = A_IR_MASK,
243
+ pauth_check_trap(env, el, GETPC());
417
+ .reset = 0x1,
244
+ return pauth_auth(env, x, y, &env->apda_key, true, 0);
418
+ .ro = 0x1,
245
+}
419
+ },{ .name = "IR_ENABLE", .addr = A_IR_ENABLE,
246
+
420
+ .pre_write = crl_enable_prew,
247
+uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
421
+ },{ .name = "IR_DISABLE", .addr = A_IR_DISABLE,
248
+{
422
+ .pre_write = crl_disable_prew,
249
+ int el = arm_current_el(env);
423
+ },{ .name = "WPROT", .addr = A_WPROT,
250
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
424
+ },{ .name = "PLL_CLK_OTHER_DMN", .addr = A_PLL_CLK_OTHER_DMN,
251
+ return x;
425
+ .reset = 0x1,
252
+ }
426
+ .rsvd = 0xe,
253
+ pauth_check_trap(env, el, GETPC());
427
+ },{ .name = "RPLL_CTRL", .addr = A_RPLL_CTRL,
254
+ return pauth_auth(env, x, y, &env->apdb_key, true, 1);
428
+ .reset = 0x24809,
255
+}
429
+ .rsvd = 0xf88c00f6,
256
+
430
+ },{ .name = "RPLL_CFG", .addr = A_RPLL_CFG,
257
+uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
431
+ .reset = 0x2000000,
258
+{
432
+ .rsvd = 0x1801210,
259
+ return pauth_strip(env, a, false);
433
+ },{ .name = "RPLL_FRAC_CFG", .addr = A_RPLL_FRAC_CFG,
260
+}
434
+ .rsvd = 0x7e330000,
261
+
435
+ },{ .name = "PLL_STATUS", .addr = A_PLL_STATUS,
262
+uint64_t HELPER(xpacd)(CPUARMState *env, uint64_t a)
436
+ .reset = R_PLL_STATUS_RPLL_STABLE_MASK |
263
+{
437
+ R_PLL_STATUS_RPLL_LOCK_MASK,
264
+ return pauth_strip(env, a, true);
438
+ .rsvd = 0xfa,
265
+}
439
+ .ro = 0x5,
440
+ },{ .name = "RPLL_TO_XPD_CTRL", .addr = A_RPLL_TO_XPD_CTRL,
441
+ .reset = 0x2000100,
442
+ .rsvd = 0xfdfc00ff,
443
+ },{ .name = "LPD_TOP_SWITCH_CTRL", .addr = A_LPD_TOP_SWITCH_CTRL,
444
+ .reset = 0x6000300,
445
+ .rsvd = 0xf9fc00f8,
446
+ },{ .name = "LPD_LSBUS_CTRL", .addr = A_LPD_LSBUS_CTRL,
447
+ .reset = 0x2000800,
448
+ .rsvd = 0xfdfc00f8,
449
+ },{ .name = "CPU_R5_CTRL", .addr = A_CPU_R5_CTRL,
450
+ .reset = 0xe000300,
451
+ .rsvd = 0xe1fc00f8,
452
+ },{ .name = "IOU_SWITCH_CTRL", .addr = A_IOU_SWITCH_CTRL,
453
+ .reset = 0x2000500,
454
+ .rsvd = 0xfdfc00f8,
455
+ },{ .name = "GEM0_REF_CTRL", .addr = A_GEM0_REF_CTRL,
456
+ .reset = 0xe000a00,
457
+ .rsvd = 0xf1fc00f8,
458
+ },{ .name = "GEM1_REF_CTRL", .addr = A_GEM1_REF_CTRL,
459
+ .reset = 0xe000a00,
460
+ .rsvd = 0xf1fc00f8,
461
+ },{ .name = "GEM_TSU_REF_CTRL", .addr = A_GEM_TSU_REF_CTRL,
462
+ .reset = 0x300,
463
+ .rsvd = 0xfdfc00f8,
464
+ },{ .name = "USB0_BUS_REF_CTRL", .addr = A_USB0_BUS_REF_CTRL,
465
+ .reset = 0x2001900,
466
+ .rsvd = 0xfdfc00f8,
467
+ },{ .name = "UART0_REF_CTRL", .addr = A_UART0_REF_CTRL,
468
+ .reset = 0xc00,
469
+ .rsvd = 0xfdfc00f8,
470
+ },{ .name = "UART1_REF_CTRL", .addr = A_UART1_REF_CTRL,
471
+ .reset = 0xc00,
472
+ .rsvd = 0xfdfc00f8,
473
+ },{ .name = "SPI0_REF_CTRL", .addr = A_SPI0_REF_CTRL,
474
+ .reset = 0x600,
475
+ .rsvd = 0xfdfc00f8,
476
+ },{ .name = "SPI1_REF_CTRL", .addr = A_SPI1_REF_CTRL,
477
+ .reset = 0x600,
478
+ .rsvd = 0xfdfc00f8,
479
+ },{ .name = "CAN0_REF_CTRL", .addr = A_CAN0_REF_CTRL,
480
+ .reset = 0xc00,
481
+ .rsvd = 0xfdfc00f8,
482
+ },{ .name = "CAN1_REF_CTRL", .addr = A_CAN1_REF_CTRL,
483
+ .reset = 0xc00,
484
+ .rsvd = 0xfdfc00f8,
485
+ },{ .name = "I2C0_REF_CTRL", .addr = A_I2C0_REF_CTRL,
486
+ .reset = 0xc00,
487
+ .rsvd = 0xfdfc00f8,
488
+ },{ .name = "I2C1_REF_CTRL", .addr = A_I2C1_REF_CTRL,
489
+ .reset = 0xc00,
490
+ .rsvd = 0xfdfc00f8,
491
+ },{ .name = "DBG_LPD_CTRL", .addr = A_DBG_LPD_CTRL,
492
+ .reset = 0x300,
493
+ .rsvd = 0xfdfc00f8,
494
+ },{ .name = "TIMESTAMP_REF_CTRL", .addr = A_TIMESTAMP_REF_CTRL,
495
+ .reset = 0x2000c00,
496
+ .rsvd = 0xfdfc00f8,
497
+ },{ .name = "CRL_SAFETY_CHK", .addr = A_CRL_SAFETY_CHK,
498
+ },{ .name = "PSM_REF_CTRL", .addr = A_PSM_REF_CTRL,
499
+ .reset = 0xf04,
500
+ .rsvd = 0xfffc00f8,
501
+ },{ .name = "DBG_TSTMP_CTRL", .addr = A_DBG_TSTMP_CTRL,
502
+ .reset = 0x300,
503
+ .rsvd = 0xfdfc00f8,
504
+ },{ .name = "CPM_TOPSW_REF_CTRL", .addr = A_CPM_TOPSW_REF_CTRL,
505
+ .reset = 0x300,
506
+ .rsvd = 0xfdfc00f8,
507
+ },{ .name = "USB3_DUAL_REF_CTRL", .addr = A_USB3_DUAL_REF_CTRL,
508
+ .reset = 0x3c00,
509
+ .rsvd = 0xfdfc00f8,
510
+ },{ .name = "RST_CPU_R5", .addr = A_RST_CPU_R5,
511
+ .reset = 0x17,
512
+ .rsvd = 0x8,
513
+ .pre_write = crl_rst_r5_prew,
514
+ },{ .name = "RST_ADMA", .addr = A_RST_ADMA,
515
+ .reset = 0x1,
516
+ .pre_write = crl_rst_adma_prew,
517
+ },{ .name = "RST_GEM0", .addr = A_RST_GEM0,
518
+ .reset = 0x1,
519
+ .pre_write = crl_rst_gem0_prew,
520
+ },{ .name = "RST_GEM1", .addr = A_RST_GEM1,
521
+ .reset = 0x1,
522
+ .pre_write = crl_rst_gem1_prew,
523
+ },{ .name = "RST_SPARE", .addr = A_RST_SPARE,
524
+ .reset = 0x1,
525
+ },{ .name = "RST_USB0", .addr = A_RST_USB0,
526
+ .reset = 0x1,
527
+ .pre_write = crl_rst_usb_prew,
528
+ },{ .name = "RST_UART0", .addr = A_RST_UART0,
529
+ .reset = 0x1,
530
+ .pre_write = crl_rst_uart0_prew,
531
+ },{ .name = "RST_UART1", .addr = A_RST_UART1,
532
+ .reset = 0x1,
533
+ .pre_write = crl_rst_uart1_prew,
534
+ },{ .name = "RST_SPI0", .addr = A_RST_SPI0,
535
+ .reset = 0x1,
536
+ },{ .name = "RST_SPI1", .addr = A_RST_SPI1,
537
+ .reset = 0x1,
538
+ },{ .name = "RST_CAN0", .addr = A_RST_CAN0,
539
+ .reset = 0x1,
540
+ },{ .name = "RST_CAN1", .addr = A_RST_CAN1,
541
+ .reset = 0x1,
542
+ },{ .name = "RST_I2C0", .addr = A_RST_I2C0,
543
+ .reset = 0x1,
544
+ },{ .name = "RST_I2C1", .addr = A_RST_I2C1,
545
+ .reset = 0x1,
546
+ },{ .name = "RST_DBG_LPD", .addr = A_RST_DBG_LPD,
547
+ .reset = 0x33,
548
+ .rsvd = 0xcc,
549
+ },{ .name = "RST_GPIO", .addr = A_RST_GPIO,
550
+ .reset = 0x1,
551
+ },{ .name = "RST_TTC", .addr = A_RST_TTC,
552
+ .reset = 0xf,
553
+ },{ .name = "RST_TIMESTAMP", .addr = A_RST_TIMESTAMP,
554
+ .reset = 0x1,
555
+ },{ .name = "RST_SWDT", .addr = A_RST_SWDT,
556
+ .reset = 0x1,
557
+ },{ .name = "RST_OCM", .addr = A_RST_OCM,
558
+ },{ .name = "RST_IPI", .addr = A_RST_IPI,
559
+ },{ .name = "RST_FPD", .addr = A_RST_FPD,
560
+ .reset = 0x3,
561
+ },{ .name = "PSM_RST_MODE", .addr = A_PSM_RST_MODE,
562
+ .reset = 0x1,
563
+ .rsvd = 0xf8,
564
+ }
565
+};
566
+
567
+static void crl_reset_enter(Object *obj, ResetType type)
568
+{
569
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
570
+ unsigned int i;
571
+
572
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
573
+ register_reset(&s->regs_info[i]);
574
+ }
575
+}
576
+
577
+static void crl_reset_hold(Object *obj)
578
+{
579
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
580
+
581
+ crl_update_irq(s);
582
+}
583
+
584
+static const MemoryRegionOps crl_ops = {
585
+ .read = register_read_memory,
586
+ .write = register_write_memory,
587
+ .endianness = DEVICE_LITTLE_ENDIAN,
588
+ .valid = {
589
+ .min_access_size = 4,
590
+ .max_access_size = 4,
591
+ },
592
+};
593
+
594
+static void crl_init(Object *obj)
595
+{
596
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
597
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
598
+ int i;
599
+
600
+ s->reg_array =
601
+ register_init_block32(DEVICE(obj), crl_regs_info,
602
+ ARRAY_SIZE(crl_regs_info),
603
+ s->regs_info, s->regs,
604
+ &crl_ops,
605
+ XLNX_VERSAL_CRL_ERR_DEBUG,
606
+ CRL_R_MAX * 4);
607
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
608
+ sysbus_init_irq(sbd, &s->irq);
609
+
610
+ for (i = 0; i < ARRAY_SIZE(s->cfg.cpu_r5); ++i) {
611
+ object_property_add_link(obj, "cpu_r5[*]", TYPE_ARM_CPU,
612
+ (Object **)&s->cfg.cpu_r5[i],
613
+ qdev_prop_allow_set_link_before_realize,
614
+ OBJ_PROP_LINK_STRONG);
615
+ }
616
+
617
+ for (i = 0; i < ARRAY_SIZE(s->cfg.adma); ++i) {
618
+ object_property_add_link(obj, "adma[*]", TYPE_DEVICE,
619
+ (Object **)&s->cfg.adma[i],
620
+ qdev_prop_allow_set_link_before_realize,
621
+ OBJ_PROP_LINK_STRONG);
622
+ }
623
+
624
+ for (i = 0; i < ARRAY_SIZE(s->cfg.uart); ++i) {
625
+ object_property_add_link(obj, "uart[*]", TYPE_DEVICE,
626
+ (Object **)&s->cfg.uart[i],
627
+ qdev_prop_allow_set_link_before_realize,
628
+ OBJ_PROP_LINK_STRONG);
629
+ }
630
+
631
+ for (i = 0; i < ARRAY_SIZE(s->cfg.gem); ++i) {
632
+ object_property_add_link(obj, "gem[*]", TYPE_DEVICE,
633
+ (Object **)&s->cfg.gem[i],
634
+ qdev_prop_allow_set_link_before_realize,
635
+ OBJ_PROP_LINK_STRONG);
636
+ }
637
+
638
+ object_property_add_link(obj, "usb", TYPE_DEVICE,
639
+ (Object **)&s->cfg.gem[i],
640
+ qdev_prop_allow_set_link_before_realize,
641
+ OBJ_PROP_LINK_STRONG);
642
+}
643
+
644
+static void crl_finalize(Object *obj)
645
+{
646
+ XlnxVersalCRL *s = XLNX_VERSAL_CRL(obj);
647
+ register_finalize_block(s->reg_array);
648
+}
649
+
650
+static const VMStateDescription vmstate_crl = {
651
+ .name = TYPE_XLNX_VERSAL_CRL,
652
+ .version_id = 1,
653
+ .minimum_version_id = 1,
654
+ .fields = (VMStateField[]) {
655
+ VMSTATE_UINT32_ARRAY(regs, XlnxVersalCRL, CRL_R_MAX),
656
+ VMSTATE_END_OF_LIST(),
657
+ }
658
+};
659
+
660
+static void crl_class_init(ObjectClass *klass, void *data)
661
+{
662
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
663
+ DeviceClass *dc = DEVICE_CLASS(klass);
664
+
665
+ dc->vmsd = &vmstate_crl;
666
+
667
+ rc->phases.enter = crl_reset_enter;
668
+ rc->phases.hold = crl_reset_hold;
669
+}
670
+
671
+static const TypeInfo crl_info = {
672
+ .name = TYPE_XLNX_VERSAL_CRL,
673
+ .parent = TYPE_SYS_BUS_DEVICE,
674
+ .instance_size = sizeof(XlnxVersalCRL),
675
+ .class_init = crl_class_init,
676
+ .instance_init = crl_init,
677
+ .instance_finalize = crl_finalize,
678
+};
679
+
680
+static void crl_register_types(void)
681
+{
682
+ type_register_static(&crl_info);
683
+}
684
+
685
+type_init(crl_register_types)
686
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
687
index XXXXXXX..XXXXXXX 100644
688
--- a/hw/misc/meson.build
689
+++ b/hw/misc/meson.build
690
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
691
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
692
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-crf.c'))
693
specific_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp-apu-ctrl.c'))
694
+specific_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-crl.c'))
695
softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files(
696
'xlnx-versal-xramc.c',
697
'xlnx-versal-pmc-iou-slcr.c',
266
--
698
--
267
2.20.1
699
2.25.1
268
269
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: "Edgar E. Iglesias" <edgar.iglesias@amd.com>
2
2
3
This function is, or will shortly become, too big to inline.
3
Connect the CRL (Clock Reset LPD) to the Versal SoC.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Frederic Konrad <fkonrad@amd.com>
7
Message-id: 20190108223129.5570-16-richard.henderson@linaro.org
7
Reviewed-by: Francisco Iglesias <francisco.iglesias@amd.com>
8
Message-id: 20220406174303.2022038-5-edgar.iglesias@xilinx.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/cpu.h | 48 +++++----------------------------------------
11
include/hw/arm/xlnx-versal.h | 4 +++
11
target/arm/helper.c | 44 +++++++++++++++++++++++++++++++++++++++++
12
hw/arm/xlnx-versal.c | 54 ++++++++++++++++++++++++++++++++++--
12
2 files changed, 49 insertions(+), 43 deletions(-)
13
2 files changed, 56 insertions(+), 2 deletions(-)
13
14
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
--- a/include/hw/arm/xlnx-versal.h
17
+++ b/target/arm/cpu.h
18
+++ b/include/hw/arm/xlnx-versal.h
18
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/nvram/xlnx-versal-efuse.h"
21
#include "hw/ssi/xlnx-versal-ospi.h"
22
#include "hw/dma/xlnx_csu_dma.h"
23
+#include "hw/misc/xlnx-versal-crl.h"
24
#include "hw/misc/xlnx-versal-pmc-iou-slcr.h"
25
26
#define TYPE_XLNX_VERSAL "xlnx-versal"
27
@@ -XXX,XX +XXX,XX @@ struct Versal {
28
qemu_or_irq irq_orgate;
29
XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
30
} xram;
31
+
32
+ XlnxVersalCRL crl;
33
} lpd;
34
35
/* The Platform Management Controller subsystem. */
36
@@ -XXX,XX +XXX,XX @@ struct Versal {
37
#define VERSAL_TIMER_NS_EL1_IRQ 14
38
#define VERSAL_TIMER_NS_EL2_IRQ 10
39
40
+#define VERSAL_CRL_IRQ 10
41
#define VERSAL_UART0_IRQ_0 18
42
#define VERSAL_UART1_IRQ_0 19
43
#define VERSAL_USB0_IRQ_0 22
44
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/xlnx-versal.c
47
+++ b/hw/arm/xlnx-versal.c
48
@@ -XXX,XX +XXX,XX @@ static void versal_create_ospi(Versal *s, qemu_irq *pic)
49
qdev_connect_gpio_out(orgate, 0, pic[VERSAL_OSPI_IRQ]);
19
}
50
}
20
51
21
/* Return the MMU index for a v7M CPU in the specified security and
52
+static void versal_create_crl(Versal *s, qemu_irq *pic)
22
- * privilege state
23
+ * privilege state.
24
*/
25
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
26
- bool secstate,
27
- bool priv)
28
-{
29
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
30
-
31
- if (priv) {
32
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
33
- }
34
-
35
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
36
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
37
- }
38
-
39
- if (secstate) {
40
- mmu_idx |= ARM_MMU_IDX_M_S;
41
- }
42
-
43
- return mmu_idx;
44
-}
45
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
46
+ bool secstate, bool priv);
47
48
/* Return the MMU index for a v7M CPU in the specified security state */
49
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
50
- bool secstate)
51
-{
52
- bool priv = arm_current_el(env) != 0;
53
-
54
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
55
-}
56
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
57
58
/* Determine the current mmu_idx to use for normal loads/stores */
59
-static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
60
-{
61
- int el = arm_current_el(env);
62
-
63
- if (arm_feature(env, ARM_FEATURE_M)) {
64
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
65
-
66
- return arm_to_core_mmu_idx(mmu_idx);
67
- }
68
-
69
- if (el < 2 && arm_is_secure_below_el3(env)) {
70
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
71
- }
72
- return el;
73
-}
74
+int cpu_mmu_index(CPUARMState *env, bool ifetch);
75
76
/* Indexes used when registering address spaces with cpu_address_space_init */
77
typedef enum ARMASIdx {
78
diff --git a/target/arm/helper.c b/target/arm/helper.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/helper.c
81
+++ b/target/arm/helper.c
82
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
83
return 0;
84
}
85
86
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
87
+ bool secstate, bool priv)
88
+{
53
+{
89
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
54
+ SysBusDevice *sbd;
55
+ int i;
90
+
56
+
91
+ if (priv) {
57
+ object_initialize_child(OBJECT(s), "crl", &s->lpd.crl,
92
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
58
+ TYPE_XLNX_VERSAL_CRL);
59
+ sbd = SYS_BUS_DEVICE(&s->lpd.crl);
60
+
61
+ for (i = 0; i < ARRAY_SIZE(s->lpd.rpu.cpu); i++) {
62
+ g_autofree gchar *name = g_strdup_printf("cpu_r5[%d]", i);
63
+
64
+ object_property_set_link(OBJECT(&s->lpd.crl),
65
+ name, OBJECT(&s->lpd.rpu.cpu[i]),
66
+ &error_abort);
93
+ }
67
+ }
94
+
68
+
95
+ if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
69
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.gem); i++) {
96
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
70
+ g_autofree gchar *name = g_strdup_printf("gem[%d]", i);
71
+
72
+ object_property_set_link(OBJECT(&s->lpd.crl),
73
+ name, OBJECT(&s->lpd.iou.gem[i]),
74
+ &error_abort);
97
+ }
75
+ }
98
+
76
+
99
+ if (secstate) {
77
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.adma); i++) {
100
+ mmu_idx |= ARM_MMU_IDX_M_S;
78
+ g_autofree gchar *name = g_strdup_printf("adma[%d]", i);
79
+
80
+ object_property_set_link(OBJECT(&s->lpd.crl),
81
+ name, OBJECT(&s->lpd.iou.adma[i]),
82
+ &error_abort);
101
+ }
83
+ }
102
+
84
+
103
+ return mmu_idx;
85
+ for (i = 0; i < ARRAY_SIZE(s->lpd.iou.uart); i++) {
86
+ g_autofree gchar *name = g_strdup_printf("uart[%d]", i);
87
+
88
+ object_property_set_link(OBJECT(&s->lpd.crl),
89
+ name, OBJECT(&s->lpd.iou.uart[i]),
90
+ &error_abort);
91
+ }
92
+
93
+ object_property_set_link(OBJECT(&s->lpd.crl),
94
+ "usb", OBJECT(&s->lpd.iou.usb),
95
+ &error_abort);
96
+
97
+ sysbus_realize(sbd, &error_fatal);
98
+ memory_region_add_subregion(&s->mr_ps, MM_CRL,
99
+ sysbus_mmio_get_region(sbd, 0));
100
+ sysbus_connect_irq(sbd, 0, pic[VERSAL_CRL_IRQ]);
104
+}
101
+}
105
+
102
+
106
+/* Return the MMU index for a v7M CPU in the specified security state */
103
/* This takes the board allocated linear DDR memory and creates aliases
107
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
104
* for each split DDR range/aperture on the Versal address map.
108
+{
105
*/
109
+ bool priv = arm_current_el(env) != 0;
106
@@ -XXX,XX +XXX,XX @@ static void versal_unimp(Versal *s)
110
+
107
111
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
108
versal_unimp_area(s, "psm", &s->mr_ps,
112
+}
109
MM_PSM_START, MM_PSM_END - MM_PSM_START);
113
+
110
- versal_unimp_area(s, "crl", &s->mr_ps,
114
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
111
- MM_CRL, MM_CRL_SIZE);
115
+{
112
versal_unimp_area(s, "crf", &s->mr_ps,
116
+ int el = arm_current_el(env);
113
MM_FPD_CRF, MM_FPD_CRF_SIZE);
117
+
114
versal_unimp_area(s, "apu", &s->mr_ps,
118
+ if (arm_feature(env, ARM_FEATURE_M)) {
115
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
119
+ ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
116
versal_create_efuse(s, pic);
120
+
117
versal_create_pmc_iou_slcr(s, pic);
121
+ return arm_to_core_mmu_idx(mmu_idx);
118
versal_create_ospi(s, pic);
122
+ }
119
+ versal_create_crl(s, pic);
123
+
120
versal_map_ddr(s);
124
+ if (el < 2 && arm_is_secure_below_el3(env)) {
121
versal_unimp(s);
125
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
122
126
+ }
127
+ return el;
128
+}
129
+
130
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
131
target_ulong *cs_base, uint32_t *pflags)
132
{
133
--
123
--
134
2.20.1
124
2.25.1
135
136
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
The Exynos4210 SoC device currently uses a custom device
2
"exynos4210.irq_gate" to model the OR gate that feeds each CPU's IRQ
3
line. We have a standard TYPE_OR_IRQ device for this now, so use
4
that instead.
2
5
3
In some cases it may be helpful to modify state before saving it for
6
(This is a migration compatibility break, but that is OK for this
4
migration, and then modify the state back after it has been saved. The
7
machine type.)
5
existing pre_save function provides half of this functionality. This
6
patch adds a post_save function to provide the second half.
7
8
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
11
Message-id: 20181211151945.29137-2-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-2-peter.maydell@linaro.org
13
---
12
---
14
include/migration/vmstate.h | 1 +
13
include/hw/arm/exynos4210.h | 1 +
15
migration/vmstate.c | 13 ++++++++++++-
14
hw/arm/exynos4210.c | 31 ++++++++++++++++---------------
16
docs/devel/migration.rst | 9 +++++++--
15
2 files changed, 17 insertions(+), 15 deletions(-)
17
3 files changed, 20 insertions(+), 3 deletions(-)
18
16
19
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/include/migration/vmstate.h
19
--- a/include/hw/arm/exynos4210.h
22
+++ b/include/migration/vmstate.h
20
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ struct VMStateDescription {
21
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
24
int (*pre_load)(void *opaque);
22
MemoryRegion bootreg_mem;
25
int (*post_load)(void *opaque, int version_id);
23
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
26
int (*pre_save)(void *opaque);
24
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
27
+ int (*post_save)(void *opaque);
25
+ qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
28
bool (*needed)(void *opaque);
26
};
29
const VMStateField *fields;
27
30
const VMStateDescription **subsections;
28
#define TYPE_EXYNOS4210_SOC "exynos4210"
31
diff --git a/migration/vmstate.c b/migration/vmstate.c
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
32
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
33
--- a/migration/vmstate.c
31
--- a/hw/arm/exynos4210.c
34
+++ b/migration/vmstate.c
32
+++ b/hw/arm/exynos4210.c
35
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
36
if (ret) {
34
{
37
error_report("Save of field %s/%s failed",
35
Exynos4210State *s = EXYNOS4210_SOC(socdev);
38
vmsd->name, field->name);
36
MemoryRegion *system_mem = get_system_memory();
39
+ if (vmsd->post_save) {
37
- qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
40
+ vmsd->post_save(opaque);
38
SysBusDevice *busdev;
41
+ }
39
DeviceState *dev, *uart[4], *pl330[3];
42
return ret;
40
int i, n;
43
}
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
42
45
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
43
/* IRQ Gate */
46
json_end_array(vmdesc);
44
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
45
- dev = qdev_new("exynos4210.irq_gate");
46
- qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
47
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
48
- /* Get IRQ Gate input in gate_irq */
49
- for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
50
- gate_irq[i][n] = qdev_get_gpio_in(dev, n);
51
- }
52
- busdev = SYS_BUS_DEVICE(dev);
53
-
54
- /* Connect IRQ Gate output to CPU's IRQ line */
55
- sysbus_connect_irq(busdev, 0,
56
- qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
57
+ DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
58
+ object_property_set_int(OBJECT(orgate), "num-lines",
59
+ EXYNOS4210_IRQ_GATE_NINPUTS,
60
+ &error_abort);
61
+ qdev_realize(orgate, NULL, &error_abort);
62
+ qdev_connect_gpio_out(orgate, 0,
63
+ qdev_get_gpio_in(DEVICE(s->cpu[i]), ARM_CPU_IRQ));
47
}
64
}
48
65
49
- return vmstate_subsection_save(f, vmsd, opaque, vmdesc);
66
/* Private memory region and Internal GIC */
50
+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
67
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
68
sysbus_realize_and_unref(busdev, &error_fatal);
69
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
70
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
71
- sysbus_connect_irq(busdev, n, gate_irq[n][0]);
72
+ sysbus_connect_irq(busdev, n,
73
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
74
}
75
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
76
s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
77
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
78
/* Map Distributer interface */
79
sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
80
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
81
- sysbus_connect_irq(busdev, n, gate_irq[n][1]);
82
+ sysbus_connect_irq(busdev, n,
83
+ qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
84
}
85
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
86
s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
87
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
88
object_initialize_child(obj, name, orgate, TYPE_OR_IRQ);
89
g_free(name);
90
}
51
+
91
+
52
+ if (vmsd->post_save) {
92
+ for (i = 0; i < ARRAY_SIZE(s->cpu_irq_orgate); i++) {
53
+ int ps_ret = vmsd->post_save(opaque);
93
+ g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
54
+ if (!ret) {
94
+ object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
55
+ ret = ps_ret;
56
+ }
57
+ }
95
+ }
58
+ return ret;
59
}
96
}
60
97
61
static const VMStateDescription *
98
static void exynos4210_class_init(ObjectClass *klass, void *data)
62
diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
63
index XXXXXXX..XXXXXXX 100644
64
--- a/docs/devel/migration.rst
65
+++ b/docs/devel/migration.rst
66
@@ -XXX,XX +XXX,XX @@ The functions to do that are inside a vmstate definition, and are called:
67
68
This function is called before we save the state of one device.
69
70
-Example: You can look at hpet.c, that uses the three function to
71
-massage the state that is transferred.
72
+- ``int (*post_save)(void *opaque);``
73
+
74
+ This function is called after we save the state of one device
75
+ (even upon failure, unless the call to pre_save returned an error).
76
+
77
+Example: You can look at hpet.c, that uses the first three functions
78
+to massage the state that is transferred.
79
80
The ``VMSTATE_WITH_TMP`` macro may be useful when the migration
81
data doesn't match the stored device data well; it allows an
82
--
99
--
83
2.20.1
100
2.25.1
84
85
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Now we have removed the only use of TYPE_EXYNOS4210_IRQ_GATE we can
2
delete the device entirely.
2
3
3
The instruction event is only enabled when icount is used, cycles are
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
always supported. Always defining get_cycle_count (but altering its
5
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
behavior depending on CONFIG_USER_ONLY) allows us to remove some
6
Message-id: 20220404154658.565020-3-peter.maydell@linaro.org
6
CONFIG_USER_ONLY #defines throughout the rest of the code.
7
---
8
hw/intc/exynos4210_gic.c | 107 ---------------------------------------
9
1 file changed, 107 deletions(-)
7
10
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
11
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20181211151945.29137-12-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.c | 90 ++++++++++++++++++++++-----------------------
15
1 file changed, 44 insertions(+), 46 deletions(-)
16
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
13
--- a/hw/intc/exynos4210_gic.c
20
+++ b/target/arm/helper.c
14
+++ b/hw/intc/exynos4210_gic.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_register_types(void)
22
#include "arm_ldst.h"
23
#include <zlib.h> /* For crc32 */
24
#include "exec/semihost.h"
25
+#include "sysemu/cpus.h"
26
#include "sysemu/kvm.h"
27
#include "fpu/softfloat.h"
28
#include "qemu/range.h"
29
@@ -XXX,XX +XXX,XX @@ typedef struct pm_event {
30
uint64_t (*get_count)(CPUARMState *);
31
} pm_event;
32
33
+static bool event_always_supported(CPUARMState *env)
34
+{
35
+ return true;
36
+}
37
+
38
+/*
39
+ * Return the underlying cycle count for the PMU cycle counters. If we're in
40
+ * usermode, simply return 0.
41
+ */
42
+static uint64_t cycles_get_count(CPUARMState *env)
43
+{
44
+#ifndef CONFIG_USER_ONLY
45
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
46
+ ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
47
+#else
48
+ return cpu_get_host_ticks();
49
+#endif
50
+}
51
+
52
+#ifndef CONFIG_USER_ONLY
53
+static bool instructions_supported(CPUARMState *env)
54
+{
55
+ return use_icount == 1 /* Precise instruction counting */;
56
+}
57
+
58
+static uint64_t instructions_get_count(CPUARMState *env)
59
+{
60
+ return (uint64_t)cpu_get_icount_raw();
61
+}
62
+#endif
63
+
64
static const pm_event pm_events[] = {
65
+#ifndef CONFIG_USER_ONLY
66
+ { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
67
+ .supported = instructions_supported,
68
+ .get_count = instructions_get_count,
69
+ },
70
+ { .number = 0x011, /* CPU_CYCLES, Cycle */
71
+ .supported = event_always_supported,
72
+ .get_count = cycles_get_count,
73
+ }
74
+#endif
75
};
76
77
/*
78
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
79
* should first be updated to something sparse instead of the current
80
* supported_event_map[] array.
81
*/
82
-#define MAX_EVENT_ID 0x0
83
+#define MAX_EVENT_ID 0x11
84
#define UNSUPPORTED_EVENT UINT16_MAX
85
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
86
87
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_swinc(CPUARMState *env,
88
return pmreg_access(env, ri, isread);
89
}
16
}
90
17
91
-#ifndef CONFIG_USER_ONLY
18
type_init(exynos4210_gic_register_types)
92
-
19
-
93
static CPAccessResult pmreg_access_selr(CPUARMState *env,
20
-/* IRQ OR Gate struct.
94
const ARMCPRegInfo *ri,
21
- *
95
bool isread)
22
- * This device models an OR gate. There are n_in input qdev gpio lines and one
96
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
23
- * output sysbus IRQ line. The output IRQ level is formed as OR between all
97
*/
24
- * gpio inputs.
98
void pmccntr_op_start(CPUARMState *env)
25
- */
99
{
100
- uint64_t cycles = 0;
101
- cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
102
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
103
+ uint64_t cycles = cycles_get_count(env);
104
105
if (pmu_counter_enabled(env, 31)) {
106
uint64_t eff_cycles = cycles;
107
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
108
pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
109
}
110
111
-#else /* CONFIG_USER_ONLY */
112
-
26
-
113
-void pmccntr_op_start(CPUARMState *env)
27
-#define TYPE_EXYNOS4210_IRQ_GATE "exynos4210.irq_gate"
28
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210IRQGateState, EXYNOS4210_IRQ_GATE)
29
-
30
-struct Exynos4210IRQGateState {
31
- SysBusDevice parent_obj;
32
-
33
- uint32_t n_in; /* inputs amount */
34
- uint32_t *level; /* input levels */
35
- qemu_irq out; /* output IRQ */
36
-};
37
-
38
-static Property exynos4210_irq_gate_properties[] = {
39
- DEFINE_PROP_UINT32("n_in", Exynos4210IRQGateState, n_in, 1),
40
- DEFINE_PROP_END_OF_LIST(),
41
-};
42
-
43
-static const VMStateDescription vmstate_exynos4210_irq_gate = {
44
- .name = "exynos4210.irq_gate",
45
- .version_id = 2,
46
- .minimum_version_id = 2,
47
- .fields = (VMStateField[]) {
48
- VMSTATE_VBUFFER_UINT32(level, Exynos4210IRQGateState, 1, NULL, n_in),
49
- VMSTATE_END_OF_LIST()
50
- }
51
-};
52
-
53
-/* Process a change in IRQ input. */
54
-static void exynos4210_irq_gate_handler(void *opaque, int irq, int level)
114
-{
55
-{
56
- Exynos4210IRQGateState *s = (Exynos4210IRQGateState *)opaque;
57
- uint32_t i;
58
-
59
- assert(irq < s->n_in);
60
-
61
- s->level[irq] = level;
62
-
63
- for (i = 0; i < s->n_in; i++) {
64
- if (s->level[i] >= 1) {
65
- qemu_irq_raise(s->out);
66
- return;
67
- }
68
- }
69
-
70
- qemu_irq_lower(s->out);
115
-}
71
-}
116
-
72
-
117
-void pmccntr_op_finish(CPUARMState *env)
73
-static void exynos4210_irq_gate_reset(DeviceState *d)
118
-{
74
-{
75
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(d);
76
-
77
- memset(s->level, 0, s->n_in * sizeof(*s->level));
119
-}
78
-}
120
-
79
-
121
-void pmevcntr_op_start(CPUARMState *env, uint8_t i)
80
-/*
81
- * IRQ Gate initialization.
82
- */
83
-static void exynos4210_irq_gate_init(Object *obj)
122
-{
84
-{
85
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(obj);
86
- SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
87
-
88
- sysbus_init_irq(sbd, &s->out);
123
-}
89
-}
124
-
90
-
125
-void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
91
-static void exynos4210_irq_gate_realize(DeviceState *dev, Error **errp)
126
-{
92
-{
93
- Exynos4210IRQGateState *s = EXYNOS4210_IRQ_GATE(dev);
94
-
95
- /* Allocate general purpose input signals and connect a handler to each of
96
- * them */
97
- qdev_init_gpio_in(dev, exynos4210_irq_gate_handler, s->n_in);
98
-
99
- s->level = g_malloc0(s->n_in * sizeof(*s->level));
127
-}
100
-}
128
-
101
-
129
-void pmu_op_start(CPUARMState *env)
102
-static void exynos4210_irq_gate_class_init(ObjectClass *klass, void *data)
130
-{
103
-{
104
- DeviceClass *dc = DEVICE_CLASS(klass);
105
-
106
- dc->reset = exynos4210_irq_gate_reset;
107
- dc->vmsd = &vmstate_exynos4210_irq_gate;
108
- device_class_set_props(dc, exynos4210_irq_gate_properties);
109
- dc->realize = exynos4210_irq_gate_realize;
131
-}
110
-}
132
-
111
-
133
-void pmu_op_finish(CPUARMState *env)
112
-static const TypeInfo exynos4210_irq_gate_info = {
113
- .name = TYPE_EXYNOS4210_IRQ_GATE,
114
- .parent = TYPE_SYS_BUS_DEVICE,
115
- .instance_size = sizeof(Exynos4210IRQGateState),
116
- .instance_init = exynos4210_irq_gate_init,
117
- .class_init = exynos4210_irq_gate_class_init,
118
-};
119
-
120
-static void exynos4210_irq_gate_register_types(void)
134
-{
121
-{
122
- type_register_static(&exynos4210_irq_gate_info);
135
-}
123
-}
136
-
124
-
137
-void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
125
-type_init(exynos4210_irq_gate_register_types)
138
-{
139
-}
140
-
141
-void pmu_post_el_change(ARMCPU *cpu, void *ignored)
142
-{
143
-}
144
-
145
-#endif
146
-
147
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
148
uint64_t value)
149
{
150
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
151
/* Unimplemented so WI. */
152
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
153
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
154
-#ifndef CONFIG_USER_ONLY
155
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
156
.access = PL0_RW, .type = ARM_CP_ALIAS,
157
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
158
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
159
.fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
160
.readfn = pmccntr_read, .writefn = pmccntr_write,
161
.raw_readfn = raw_read, .raw_writefn = raw_write, },
162
-#endif
163
{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
164
.writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
165
.access = PL0_RW, .accessfn = pmreg_access,
166
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
167
* count register.
168
*/
169
unsigned int i, pmcrn = 0;
170
-#ifndef CONFIG_USER_ONLY
171
ARMCPRegInfo pmcr = {
172
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
173
.access = PL0_RW,
174
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
175
g_free(pmevtyper_name);
176
g_free(pmevtyper_el0_name);
177
}
178
-#endif
179
ARMCPRegInfo clidr = {
180
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
181
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
182
--
126
--
183
2.20.1
127
2.25.1
184
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The exynos4210 SoC mostly creates its child devices as if it were
2
board code. This includes the a9mpcore object. Switch that to a
3
new-style "embedded in the state struct" creation, because in the
4
next commit we're going to want to refer to the object again further
5
down in the exynos4210_realize() function.
2
6
3
Now properly signals unallocated for REV64 with SF=0.
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Allows for the opcode2 field to be decoded shortly.
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20220404154658.565020-4-peter.maydell@linaro.org
10
---
11
include/hw/arm/exynos4210.h | 2 ++
12
hw/arm/exynos4210.c | 11 ++++++-----
13
2 files changed, 8 insertions(+), 5 deletions(-)
5
14
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 31 ++++++++++++++++++++++---------
12
1 file changed, 22 insertions(+), 9 deletions(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
--- a/include/hw/arm/exynos4210.h
17
+++ b/target/arm/translate-a64.c
18
+++ b/include/hw/arm/exynos4210.h
18
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
19
@@ -XXX,XX +XXX,XX @@
19
*/
20
20
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
21
#include "hw/or-irq.h"
21
{
22
#include "hw/sysbus.h"
22
- unsigned int sf, opcode, rn, rd;
23
+#include "hw/cpu/a9mpcore.h"
23
+ unsigned int sf, opcode, opcode2, rn, rd;
24
#include "target/arm/cpu-qom.h"
24
25
#include "qom/object.h"
25
- if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
26
26
+ if (extract32(insn, 29, 1)) {
27
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
27
unallocated_encoding(s);
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
28
return;
29
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
30
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
31
+ A9MPPrivState a9mpcore;
32
};
33
34
#define TYPE_EXYNOS4210_SOC "exynos4210"
35
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/arm/exynos4210.c
38
+++ b/hw/arm/exynos4210.c
39
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
29
}
40
}
30
41
31
sf = extract32(insn, 31, 1);
42
/* Private memory region and Internal GIC */
32
opcode = extract32(insn, 10, 6);
43
- dev = qdev_new(TYPE_A9MPCORE_PRIV);
33
+ opcode2 = extract32(insn, 16, 5);
44
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
34
rn = extract32(insn, 5, 5);
45
- busdev = SYS_BUS_DEVICE(dev);
35
rd = extract32(insn, 0, 5);
46
- sysbus_realize_and_unref(busdev, &error_fatal);
36
47
+ qdev_prop_set_uint32(DEVICE(&s->a9mpcore), "num-cpu", EXYNOS4210_NCPUS);
37
- switch (opcode) {
48
+ busdev = SYS_BUS_DEVICE(&s->a9mpcore);
38
- case 0: /* RBIT */
49
+ sysbus_realize(busdev, &error_fatal);
39
+#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7))
50
sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
40
+
51
for (n = 0; n < EXYNOS4210_NCPUS; n++) {
41
+ switch (MAP(sf, opcode2, opcode)) {
52
sysbus_connect_irq(busdev, n,
42
+ case MAP(0, 0x00, 0x00): /* RBIT */
53
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
43
+ case MAP(1, 0x00, 0x00):
54
}
44
handle_rbit(s, sf, rn, rd);
55
for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
45
break;
56
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
46
- case 1: /* REV16 */
57
+ s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
47
+ case MAP(0, 0x00, 0x01): /* REV16 */
58
}
48
+ case MAP(1, 0x00, 0x01):
59
49
handle_rev16(s, sf, rn, rd);
60
/* Cache controller */
50
break;
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
51
- case 2: /* REV32 */
62
g_autofree char *name = g_strdup_printf("cpu-irq-orgate%d", i);
52
+ case MAP(0, 0x00, 0x02): /* REV/REV32 */
63
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
53
+ case MAP(1, 0x00, 0x02):
54
handle_rev32(s, sf, rn, rd);
55
break;
56
- case 3: /* REV64 */
57
+ case MAP(1, 0x00, 0x03): /* REV64 */
58
handle_rev64(s, sf, rn, rd);
59
break;
60
- case 4: /* CLZ */
61
+ case MAP(0, 0x00, 0x04): /* CLZ */
62
+ case MAP(1, 0x00, 0x04):
63
handle_clz(s, sf, rn, rd);
64
break;
65
- case 5: /* CLS */
66
+ case MAP(0, 0x00, 0x05): /* CLS */
67
+ case MAP(1, 0x00, 0x05):
68
handle_cls(s, sf, rn, rd);
69
break;
70
+ default:
71
+ unallocated_encoding(s);
72
+ break;
73
}
64
}
74
+
65
+
75
+#undef MAP
66
+ object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
76
}
67
}
77
68
78
static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
69
static void exynos4210_class_init(ObjectClass *klass, void *data)
79
--
70
--
80
2.20.1
71
2.25.1
81
82
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
The only time we use the int_gic_irq[] array in the Exynos4210Irq
2
struct is in the exynos4210_realize() function: we initialize it with
3
the GPIO inputs of the a9mpcore device, and then a bit later on we
4
connect those to the outputs of the internal combiner. Now that the
5
a9mpcore object is easily accessible as s->a9mpcore we can make the
6
connection directly from one device to the other without going via
7
this array.
2
8
3
This both advertises that we support four counters and enables them
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
because the pmu_num_counters() reads this value from PMCR.
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-5-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 1 -
14
hw/arm/exynos4210.c | 6 ++----
15
2 files changed, 2 insertions(+), 5 deletions(-)
5
16
6
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20181211151945.29137-13-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/helper.c | 10 +++++-----
13
1 file changed, 5 insertions(+), 5 deletions(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
19
--- a/include/hw/arm/exynos4210.h
18
+++ b/target/arm/helper.c
20
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
21
@@ -XXX,XX +XXX,XX @@
20
.access = PL1_W, .type = ARM_CP_NOP },
22
typedef struct Exynos4210Irq {
21
/* Performance monitors are implementation defined in v7,
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
22
* but with an ARM recommended set of registers, which we
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
23
- * follow (although we don't actually implement any counters)
25
- qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
24
+ * follow.
26
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
25
*
27
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
26
* Performance registers fall into three categories:
28
} Exynos4210Irq;
27
* (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR)
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
28
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/exynos4210.c
32
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
sysbus_connect_irq(busdev, n,
35
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 0));
29
}
36
}
30
if (arm_feature(env, ARM_FEATURE_V7)) {
37
- for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
31
/* v7 performance monitor control register: same implementor
38
- s->irqs.int_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->a9mpcore), n);
32
- * field as main ID register, and we implement only the cycle
39
- }
33
- * count register.
40
34
+ * field as main ID register, and we implement four counters in
41
/* Cache controller */
35
+ * addition to the cycle count register.
42
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
36
*/
43
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
37
- unsigned int i, pmcrn = 0;
44
busdev = SYS_BUS_DEVICE(dev);
38
+ unsigned int i, pmcrn = 4;
45
sysbus_realize_and_unref(busdev, &error_fatal);
39
ARMCPRegInfo pmcr = {
46
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
40
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
47
- sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
41
.access = PL0_RW,
48
+ sysbus_connect_irq(busdev, n,
42
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
49
+ qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
43
.access = PL0_RW, .accessfn = pmreg_access,
50
}
44
.type = ARM_CP_IO,
51
exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
45
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
52
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
46
- .resetvalue = cpu->midr & 0xff000000,
47
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
48
.writefn = pmcr_write, .raw_writefn = raw_write,
49
};
50
define_one_arm_cp_reg(cpu, &pmcr);
51
--
53
--
52
2.20.1
54
2.25.1
53
54
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
The exynos4210 code currently has two very similar arrays of IRQs:
2
2
3
Rename arm_ccnt_enabled to pmu_counter_enabled, and add logic to only
3
* board_irqs is a field of the Exynos4210Irq struct which is filled
4
return 'true' if the specified counter is enabled and neither prohibited
4
in by exynos4210_init_board_irqs() with the appropriate qemu_irqs
5
or filtered.
5
for each IRQ the board/SoC can assert
6
* irq_table is a set of qemu_irqs pointed to from the
7
Exynos4210State struct. It's allocated in exynos4210_init_irq,
8
and the only behaviour these irqs have is that they pass on the
9
level to the equivalent board_irqs[] irq
6
10
7
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
11
The extra indirection through irq_table is unnecessary, so coalesce
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
12
these into a single irq_table[] array as a direct field in
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Exynos4210State which exynos4210_init_board_irqs() fills in.
14
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181211151945.29137-5-aaron@os.amperecomputing.com
17
Message-id: 20220404154658.565020-6-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
18
---
14
target/arm/cpu.h | 10 ++++-
19
include/hw/arm/exynos4210.h | 8 ++------
15
target/arm/cpu.c | 3 ++
20
hw/arm/exynos4210.c | 6 +-----
16
target/arm/helper.c | 96 +++++++++++++++++++++++++++++++++++++++++----
21
hw/intc/exynos4210_gic.c | 32 ++++++++------------------------
17
3 files changed, 101 insertions(+), 8 deletions(-)
22
3 files changed, 11 insertions(+), 35 deletions(-)
18
23
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
26
--- a/include/hw/arm/exynos4210.h
22
+++ b/target/arm/cpu.h
27
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env);
28
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210Irq {
24
void pmu_op_start(CPUARMState *env);
29
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
25
void pmu_op_finish(CPUARMState *env);
30
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
26
31
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
27
+/**
32
- qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
28
+ * Functions to register as EL change hooks for PMU mode filtering
33
} Exynos4210Irq;
29
+ */
34
30
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
35
struct Exynos4210State {
31
+void pmu_post_el_change(ARMCPU *cpu, void *ignored);
36
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
32
+
37
/*< public >*/
33
/* SCTLR bit meanings. Several bits have been reused in newer
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
34
* versions of the architecture; in that case we define constants
39
Exynos4210Irq irqs;
35
* for both old and new bit meanings. Code which tests against those
40
- qemu_irq *irq_table;
36
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
41
+ qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
37
42
38
#define MDCR_EPMAD (1U << 21)
43
MemoryRegion chipid_mem;
39
#define MDCR_EDAD (1U << 20)
44
MemoryRegion iram_mem;
40
-#define MDCR_SPME (1U << 17)
45
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
41
+#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
46
void exynos4210_write_secondary(ARMCPU *cpu,
42
+#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
47
const struct arm_boot_info *info);
43
#define MDCR_SDD (1U << 16)
48
44
#define MDCR_SPD (3U << 14)
49
-/* Initialize exynos4210 IRQ subsystem stub */
45
#define MDCR_TDRA (1U << 11)
50
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
46
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
51
-
47
#define MDCR_HPME (1U << 7)
52
/* Initialize board IRQs.
48
#define MDCR_TPM (1U << 6)
53
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
49
#define MDCR_TPMCR (1U << 5)
54
-void exynos4210_init_board_irqs(Exynos4210Irq *s);
50
+#define MDCR_HPMN (0x1fU)
55
+void exynos4210_init_board_irqs(Exynos4210State *s);
51
56
52
/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
57
/* Get IRQ number from exynos4210 IRQ subsystem stub.
53
#define SDCR_VALID_MASK (MDCR_EPMAD | MDCR_EDAD | MDCR_SPME | MDCR_SPD)
58
* To identify IRQ source use internal combiner group and bit number
54
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
59
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
55
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/cpu.c
61
--- a/hw/arm/exynos4210.c
57
+++ b/target/arm/cpu.c
62
+++ b/hw/arm/exynos4210.c
58
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
63
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
59
if (!cpu->has_pmu) {
64
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
60
unset_feature(env, ARM_FEATURE_PMU);
61
cpu->id_aa64dfr0 &= ~0xf00;
62
+ } else if (!kvm_enabled()) {
63
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
64
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
65
}
65
}
66
66
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
67
- /*** IRQs ***/
68
diff --git a/target/arm/helper.c b/target/arm/helper.c
68
-
69
- s->irq_table = exynos4210_init_irq(&s->irqs);
70
-
71
/* IRQ Gate */
72
for (i = 0; i < EXYNOS4210_NCPUS; i++) {
73
DeviceState *orgate = DEVICE(&s->cpu_irq_orgate[i]);
74
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
75
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
76
77
/* Initialize board IRQs. */
78
- exynos4210_init_board_irqs(&s->irqs);
79
+ exynos4210_init_board_irqs(s);
80
81
/*** Memory ***/
82
83
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
69
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/helper.c
85
--- a/hw/intc/exynos4210_gic.c
71
+++ b/target/arm/helper.c
86
+++ b/hw/intc/exynos4210_gic.c
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
87
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
73
/* Definitions for the PMU registers */
88
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
74
#define PMCRN_MASK 0xf800
89
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
75
#define PMCRN_SHIFT 11
90
76
+#define PMCRDP 0x10
91
-static void exynos4210_irq_handler(void *opaque, int irq, int level)
77
#define PMCRD 0x8
92
-{
78
#define PMCRC 0x4
93
- Exynos4210Irq *s = (Exynos4210Irq *)opaque;
79
#define PMCRE 0x1
94
-
80
95
- /* Bypass */
81
+#define PMXEVTYPER_P 0x80000000
96
- qemu_set_irq(s->board_irqs[irq], level);
82
+#define PMXEVTYPER_U 0x40000000
97
-}
83
+#define PMXEVTYPER_NSK 0x20000000
98
-
84
+#define PMXEVTYPER_NSU 0x10000000
99
-/*
85
+#define PMXEVTYPER_NSH 0x08000000
100
- * Initialize exynos4210 IRQ subsystem stub.
86
+#define PMXEVTYPER_M 0x04000000
101
- */
87
+#define PMXEVTYPER_MT 0x02000000
102
-qemu_irq *exynos4210_init_irq(Exynos4210Irq *s)
88
+#define PMXEVTYPER_EVTCOUNT 0x0000ffff
103
-{
89
+#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
104
- return qemu_allocate_irqs(exynos4210_irq_handler, s,
90
+ PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
105
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ);
91
+ PMXEVTYPER_M | PMXEVTYPER_MT | \
106
-}
92
+ PMXEVTYPER_EVTCOUNT)
107
-
93
+
108
/*
94
static inline uint32_t pmu_num_counters(CPUARMState *env)
109
* Initialize board IRQs.
110
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
111
*/
112
-void exynos4210_init_board_irqs(Exynos4210Irq *s)
113
+void exynos4210_init_board_irqs(Exynos4210State *s)
95
{
114
{
96
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
115
uint32_t grp, bit, irq_id, n;
97
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
116
+ Exynos4210Irq *is = &s->irqs;
98
return pmreg_access(env, ri, isread);
117
118
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
119
irq_id = 0;
120
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
121
irq_id = EXT_GIC_ID_MCT_G1;
122
}
123
if (irq_id) {
124
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
125
- s->ext_gic_irq[irq_id-32]);
126
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
127
+ is->ext_gic_irq[irq_id - 32]);
128
} else {
129
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
130
- s->ext_combiner_irq[n]);
131
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
132
+ is->ext_combiner_irq[n]);
133
}
134
}
135
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
136
@@ -XXX,XX +XXX,XX @@ void exynos4210_init_board_irqs(Exynos4210Irq *s)
137
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
138
139
if (irq_id) {
140
- s->board_irqs[n] = qemu_irq_split(s->int_combiner_irq[n],
141
- s->ext_gic_irq[irq_id-32]);
142
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
143
+ is->ext_gic_irq[irq_id - 32]);
144
}
145
}
99
}
146
}
100
101
-static inline bool arm_ccnt_enabled(CPUARMState *env)
102
+/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
103
+ * the current EL, security state, and register configuration.
104
+ */
105
+static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
106
{
107
- /* This does not support checking PMCCFILTR_EL0 register */
108
+ uint64_t filter;
109
+ bool e, p, u, nsk, nsu, nsh, m;
110
+ bool enabled, prohibited, filtered;
111
+ bool secure = arm_is_secure(env);
112
+ int el = arm_current_el(env);
113
+ uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
114
115
- if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
116
- return false;
117
+ if (!arm_feature(env, ARM_FEATURE_EL2) ||
118
+ (counter < hpmn || counter == 31)) {
119
+ e = env->cp15.c9_pmcr & PMCRE;
120
+ } else {
121
+ e = env->cp15.mdcr_el2 & MDCR_HPME;
122
+ }
123
+ enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
124
+
125
+ if (!secure) {
126
+ if (el == 2 && (counter < hpmn || counter == 31)) {
127
+ prohibited = env->cp15.mdcr_el2 & MDCR_HPMD;
128
+ } else {
129
+ prohibited = false;
130
+ }
131
+ } else {
132
+ prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
133
+ (env->cp15.mdcr_el3 & MDCR_SPME);
134
}
135
136
- return true;
137
+ if (prohibited && counter == 31) {
138
+ prohibited = env->cp15.c9_pmcr & PMCRDP;
139
+ }
140
+
141
+ /* TODO Remove assert, set filter to correct PMEVTYPER */
142
+ assert(counter == 31);
143
+ filter = env->cp15.pmccfiltr_el0;
144
+
145
+ p = filter & PMXEVTYPER_P;
146
+ u = filter & PMXEVTYPER_U;
147
+ nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK);
148
+ nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU);
149
+ nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH);
150
+ m = arm_el_is_aa64(env, 1) &&
151
+ arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M);
152
+
153
+ if (el == 0) {
154
+ filtered = secure ? u : u != nsu;
155
+ } else if (el == 1) {
156
+ filtered = secure ? p : p != nsk;
157
+ } else if (el == 2) {
158
+ filtered = !nsh;
159
+ } else { /* EL3 */
160
+ filtered = m != p;
161
+ }
162
+
163
+ return enabled && !prohibited && !filtered;
164
}
165
+
166
/*
167
* Ensure c15_ccnt is the guest-visible count so that operations such as
168
* enabling/disabling the counter or filtering, modifying the count itself,
169
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
170
cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
171
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
172
173
- if (arm_ccnt_enabled(env)) {
174
+ if (pmu_counter_enabled(env, 31)) {
175
uint64_t eff_cycles = cycles;
176
if (env->cp15.c9_pmcr & PMCRD) {
177
/* Increment once every 64 processor clock cycles */
178
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
179
*/
180
void pmccntr_op_finish(CPUARMState *env)
181
{
182
- if (arm_ccnt_enabled(env)) {
183
+ if (pmu_counter_enabled(env, 31)) {
184
uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
185
186
if (env->cp15.c9_pmcr & PMCRD) {
187
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
188
pmccntr_op_finish(env);
189
}
190
191
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
192
+{
193
+ pmu_op_start(&cpu->env);
194
+}
195
+
196
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
197
+{
198
+ pmu_op_finish(&cpu->env);
199
+}
200
+
201
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
202
uint64_t value)
203
{
204
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
205
{
206
}
207
208
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
209
+{
210
+}
211
+
212
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
213
+{
214
+}
215
+
216
#endif
217
218
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
219
--
147
--
220
2.20.1
148
2.25.1
221
222
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@suse.de>
1
Fix a missing set of spaces around '-' in the definition of
2
combiner_grp_to_gic_id[]. We're about to move this code, so
3
fix the style issue first to keep checkpatch happy with the
4
code-motion patch.
2
5
3
In U-boot, we switch from S-SVC -> Mon -> Hyp mode when we want to
4
enter Hyp mode. The change into Hyp mode is done by doing an
5
exception return from Mon. This doesn't work with current QEMU.
6
7
The problem is that in bad_mode_switch() we refuse to allow
8
the change of mode.
9
10
Note that bad_mode_switch() is used to do validation for two situations:
11
12
(1) changes to mode by instructions writing to CPSR.M
13
(ie not exception take/return) -- this corresponds to the
14
Armv8 Arm ARM pseudocode Arch32.WriteModeByInstr
15
(2) changes to mode by exception return
16
17
Attempting to enter or leave Hyp mode via case (1) is forbidden in
18
v8 and UNPREDICTABLE in v7, and QEMU is correct to disallow it
19
there. However, we're already doing that check at the top of the
20
bad_mode_switch() function, so if that passes then we should allow
21
the case (2) exception return mode changes to switch into Hyp mode.
22
23
We want to test whether we're trying to return to the nonexistent
24
"secure Hyp" mode, so we need to look at arm_is_secure_below_el3()
25
rather than arm_is_secure(), since the latter is always true if
26
we're in Mon (EL3).
27
28
Signed-off-by: Alexander Graf <agraf@suse.de>
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Message-id: 20190109152430.32359-1-agraf@suse.de
31
[PMM: rewrote commit message]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20220404154658.565020-7-peter.maydell@linaro.org
33
---
9
---
34
target/arm/helper.c | 2 +-
10
hw/intc/exynos4210_gic.c | 2 +-
35
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
36
12
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
38
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
15
--- a/hw/intc/exynos4210_gic.c
40
+++ b/target/arm/helper.c
16
+++ b/hw/intc/exynos4210_gic.c
41
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
42
return 0;
18
*/
43
case ARM_CPU_MODE_HYP:
19
44
return !arm_feature(env, ARM_FEATURE_EL2)
20
static const uint32_t
45
- || arm_current_el(env) < 2 || arm_is_secure(env);
21
-combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
46
+ || arm_current_el(env) < 2 || arm_is_secure_below_el3(env);
22
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
47
case ARM_CPU_MODE_MON:
23
/* int combiner groups 16-19 */
48
return arm_current_el(env) < 3;
24
{ }, { }, { }, { },
49
default:
25
/* int combiner group 20 */
50
--
26
--
51
2.20.1
27
2.25.1
52
53
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function exynos4210_init_board_irqs() currently lives in
2
exynos4210_gic.c, but it isn't really part of the exynos4210.gic
3
device -- it is a function that implements (some of) the wiring up of
4
interrupts between the SoC's GIC and combiner components. This means
5
it fits better in exynos4210.c, which is the SoC-level code. Move it
6
there. Similarly, exynos4210_git_irq() is used almost only in the
7
SoC-level code, so move it too.
2
8
3
This function is only used by AArch64. Code movement only.
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-8-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 4 -
14
hw/arm/exynos4210.c | 202 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_gic.c | 204 ------------------------------------
16
3 files changed, 202 insertions(+), 208 deletions(-)
4
17
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper-a64.h | 2 +
11
target/arm/helper.h | 1 -
12
target/arm/helper-a64.c | 155 ++++++++++++++++++++++++++++++++++++++++
13
target/arm/op_helper.c | 155 ----------------------------------------
14
4 files changed, 157 insertions(+), 156 deletions(-)
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
20
--- a/include/hw/arm/exynos4210.h
19
+++ b/target/arm/helper-a64.h
21
+++ b/include/hw/arm/exynos4210.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
22
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210State, EXYNOS4210_SOC)
21
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
23
void exynos4210_write_secondary(ARMCPU *cpu,
22
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
24
const struct arm_boot_info *info);
23
25
24
+DEF_HELPER_1(exception_return, void, env)
26
-/* Initialize board IRQs.
25
+
27
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs */
26
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
28
-void exynos4210_init_board_irqs(Exynos4210State *s);
27
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
29
-
28
DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
30
/* Get IRQ number from exynos4210 IRQ subsystem stub.
29
diff --git a/target/arm/helper.h b/target/arm/helper.h
31
* To identify IRQ source use internal combiner group and bit number
32
* grp - group number
33
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
30
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.h
35
--- a/hw/arm/exynos4210.c
32
+++ b/target/arm/helper.h
36
+++ b/hw/arm/exynos4210.c
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
37
@@ -XXX,XX +XXX,XX @@
34
38
#define EXYNOS4210_PL330_BASE1_ADDR 0x12690000
35
DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
39
#define EXYNOS4210_PL330_BASE2_ADDR 0x12850000
36
DEF_HELPER_1(clear_pstate_ss, void, env)
40
37
-DEF_HELPER_1(exception_return, void, env)
41
+enum ExtGicId {
38
42
+ EXT_GIC_ID_MDMA_LCD0 = 66,
39
DEF_HELPER_2(get_r13_banked, i32, env, i32)
43
+ EXT_GIC_ID_PDMA0,
40
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
44
+ EXT_GIC_ID_PDMA1,
41
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
45
+ EXT_GIC_ID_TIMER0,
42
index XXXXXXX..XXXXXXX 100644
46
+ EXT_GIC_ID_TIMER1,
43
--- a/target/arm/helper-a64.c
47
+ EXT_GIC_ID_TIMER2,
44
+++ b/target/arm/helper-a64.c
48
+ EXT_GIC_ID_TIMER3,
45
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
49
+ EXT_GIC_ID_TIMER4,
46
return float16_to_uint16(a, fpst);
50
+ EXT_GIC_ID_MCT_L0,
47
}
51
+ EXT_GIC_ID_WDT,
48
52
+ EXT_GIC_ID_RTC_ALARM,
49
+static int el_from_spsr(uint32_t spsr)
53
+ EXT_GIC_ID_RTC_TIC,
54
+ EXT_GIC_ID_GPIO_XB,
55
+ EXT_GIC_ID_GPIO_XA,
56
+ EXT_GIC_ID_MCT_L1,
57
+ EXT_GIC_ID_IEM_APC,
58
+ EXT_GIC_ID_IEM_IEC,
59
+ EXT_GIC_ID_NFC,
60
+ EXT_GIC_ID_UART0,
61
+ EXT_GIC_ID_UART1,
62
+ EXT_GIC_ID_UART2,
63
+ EXT_GIC_ID_UART3,
64
+ EXT_GIC_ID_UART4,
65
+ EXT_GIC_ID_MCT_G0,
66
+ EXT_GIC_ID_I2C0,
67
+ EXT_GIC_ID_I2C1,
68
+ EXT_GIC_ID_I2C2,
69
+ EXT_GIC_ID_I2C3,
70
+ EXT_GIC_ID_I2C4,
71
+ EXT_GIC_ID_I2C5,
72
+ EXT_GIC_ID_I2C6,
73
+ EXT_GIC_ID_I2C7,
74
+ EXT_GIC_ID_SPI0,
75
+ EXT_GIC_ID_SPI1,
76
+ EXT_GIC_ID_SPI2,
77
+ EXT_GIC_ID_MCT_G1,
78
+ EXT_GIC_ID_USB_HOST,
79
+ EXT_GIC_ID_USB_DEVICE,
80
+ EXT_GIC_ID_MODEMIF,
81
+ EXT_GIC_ID_HSMMC0,
82
+ EXT_GIC_ID_HSMMC1,
83
+ EXT_GIC_ID_HSMMC2,
84
+ EXT_GIC_ID_HSMMC3,
85
+ EXT_GIC_ID_SDMMC,
86
+ EXT_GIC_ID_MIPI_CSI_4LANE,
87
+ EXT_GIC_ID_MIPI_DSI_4LANE,
88
+ EXT_GIC_ID_MIPI_CSI_2LANE,
89
+ EXT_GIC_ID_MIPI_DSI_2LANE,
90
+ EXT_GIC_ID_ONENAND_AUDI,
91
+ EXT_GIC_ID_ROTATOR,
92
+ EXT_GIC_ID_FIMC0,
93
+ EXT_GIC_ID_FIMC1,
94
+ EXT_GIC_ID_FIMC2,
95
+ EXT_GIC_ID_FIMC3,
96
+ EXT_GIC_ID_JPEG,
97
+ EXT_GIC_ID_2D,
98
+ EXT_GIC_ID_PCIe,
99
+ EXT_GIC_ID_MIXER,
100
+ EXT_GIC_ID_HDMI,
101
+ EXT_GIC_ID_HDMI_I2C,
102
+ EXT_GIC_ID_MFC,
103
+ EXT_GIC_ID_TVENC,
104
+};
105
+
106
+enum ExtInt {
107
+ EXT_GIC_ID_EXTINT0 = 48,
108
+ EXT_GIC_ID_EXTINT1,
109
+ EXT_GIC_ID_EXTINT2,
110
+ EXT_GIC_ID_EXTINT3,
111
+ EXT_GIC_ID_EXTINT4,
112
+ EXT_GIC_ID_EXTINT5,
113
+ EXT_GIC_ID_EXTINT6,
114
+ EXT_GIC_ID_EXTINT7,
115
+ EXT_GIC_ID_EXTINT8,
116
+ EXT_GIC_ID_EXTINT9,
117
+ EXT_GIC_ID_EXTINT10,
118
+ EXT_GIC_ID_EXTINT11,
119
+ EXT_GIC_ID_EXTINT12,
120
+ EXT_GIC_ID_EXTINT13,
121
+ EXT_GIC_ID_EXTINT14,
122
+ EXT_GIC_ID_EXTINT15
123
+};
124
+
125
+/*
126
+ * External GIC sources which are not from External Interrupt Combiner or
127
+ * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
128
+ * which is INTG16 in Internal Interrupt Combiner.
129
+ */
130
+
131
+static const uint32_t
132
+combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
133
+ /* int combiner groups 16-19 */
134
+ { }, { }, { }, { },
135
+ /* int combiner group 20 */
136
+ { 0, EXT_GIC_ID_MDMA_LCD0 },
137
+ /* int combiner group 21 */
138
+ { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
139
+ /* int combiner group 22 */
140
+ { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
141
+ EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
142
+ /* int combiner group 23 */
143
+ { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
144
+ /* int combiner group 24 */
145
+ { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
146
+ /* int combiner group 25 */
147
+ { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
148
+ /* int combiner group 26 */
149
+ { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
150
+ EXT_GIC_ID_UART4 },
151
+ /* int combiner group 27 */
152
+ { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
153
+ EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
154
+ EXT_GIC_ID_I2C7 },
155
+ /* int combiner group 28 */
156
+ { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
157
+ /* int combiner group 29 */
158
+ { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
159
+ EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
160
+ /* int combiner group 30 */
161
+ { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
162
+ /* int combiner group 31 */
163
+ { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
164
+ /* int combiner group 32 */
165
+ { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
166
+ /* int combiner group 33 */
167
+ { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
168
+ /* int combiner group 34 */
169
+ { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
170
+ /* int combiner group 35 */
171
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
172
+ /* int combiner group 36 */
173
+ { EXT_GIC_ID_MIXER },
174
+ /* int combiner group 37 */
175
+ { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
176
+ EXT_GIC_ID_EXTINT7 },
177
+ /* groups 38-50 */
178
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
179
+ /* int combiner group 51 */
180
+ { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
181
+ /* group 52 */
182
+ { },
183
+ /* int combiner group 53 */
184
+ { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
185
+ /* groups 54-63 */
186
+ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
187
+};
188
+
189
+/*
190
+ * Initialize board IRQs.
191
+ * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
192
+ */
193
+static void exynos4210_init_board_irqs(Exynos4210State *s)
50
+{
194
+{
51
+ /* Return the exception level that this SPSR is requesting a return to,
195
+ uint32_t grp, bit, irq_id, n;
52
+ * or -1 if it is invalid (an illegal return)
196
+ Exynos4210Irq *is = &s->irqs;
53
+ */
197
+
54
+ if (spsr & PSTATE_nRW) {
198
+ for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
55
+ switch (spsr & CPSR_M) {
199
+ irq_id = 0;
56
+ case ARM_CPU_MODE_USR:
200
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
57
+ return 0;
201
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
58
+ case ARM_CPU_MODE_HYP:
202
+ /* MCT_G0 is passed to External GIC */
59
+ return 2;
203
+ irq_id = EXT_GIC_ID_MCT_G0;
60
+ case ARM_CPU_MODE_FIQ:
61
+ case ARM_CPU_MODE_IRQ:
62
+ case ARM_CPU_MODE_SVC:
63
+ case ARM_CPU_MODE_ABT:
64
+ case ARM_CPU_MODE_UND:
65
+ case ARM_CPU_MODE_SYS:
66
+ return 1;
67
+ case ARM_CPU_MODE_MON:
68
+ /* Returning to Mon from AArch64 is never possible,
69
+ * so this is an illegal return.
70
+ */
71
+ default:
72
+ return -1;
73
+ }
204
+ }
74
+ } else {
205
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
75
+ if (extract32(spsr, 1, 1)) {
206
+ n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
76
+ /* Return with reserved M[1] bit set */
207
+ /* MCT_G1 is passed to External and GIC */
77
+ return -1;
208
+ irq_id = EXT_GIC_ID_MCT_G1;
78
+ }
209
+ }
79
+ if (extract32(spsr, 0, 4) == 1) {
210
+ if (irq_id) {
80
+ /* return to EL0 with M[0] bit set */
211
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
81
+ return -1;
212
+ is->ext_gic_irq[irq_id - 32]);
213
+ } else {
214
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
215
+ is->ext_combiner_irq[n]);
82
+ }
216
+ }
83
+ return extract32(spsr, 2, 2);
217
+ }
218
+ for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
219
+ /* these IDs are passed to Internal Combiner and External GIC */
220
+ grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
221
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
222
+ irq_id = combiner_grp_to_gic_id[grp -
223
+ EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
224
+
225
+ if (irq_id) {
226
+ s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
227
+ is->ext_gic_irq[irq_id - 32]);
228
+ }
84
+ }
229
+ }
85
+}
230
+}
86
+
231
+
87
+void HELPER(exception_return)(CPUARMState *env)
232
+/*
233
+ * Get IRQ number from exynos4210 IRQ subsystem stub.
234
+ * To identify IRQ source use internal combiner group and bit number
235
+ * grp - group number
236
+ * bit - bit number inside group
237
+ */
238
+uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
88
+{
239
+{
89
+ int cur_el = arm_current_el(env);
240
+ return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
90
+ unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
91
+ uint32_t spsr = env->banked_spsr[spsr_idx];
92
+ int new_el;
93
+ bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
94
+
95
+ aarch64_save_sp(env, cur_el);
96
+
97
+ arm_clear_exclusive(env);
98
+
99
+ /* We must squash the PSTATE.SS bit to zero unless both of the
100
+ * following hold:
101
+ * 1. debug exceptions are currently disabled
102
+ * 2. singlestep will be active in the EL we return to
103
+ * We check 1 here and 2 after we've done the pstate/cpsr write() to
104
+ * transition to the EL we're going to.
105
+ */
106
+ if (arm_generate_debug_exceptions(env)) {
107
+ spsr &= ~PSTATE_SS;
108
+ }
109
+
110
+ new_el = el_from_spsr(spsr);
111
+ if (new_el == -1) {
112
+ goto illegal_return;
113
+ }
114
+ if (new_el > cur_el
115
+ || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
116
+ /* Disallow return to an EL which is unimplemented or higher
117
+ * than the current one.
118
+ */
119
+ goto illegal_return;
120
+ }
121
+
122
+ if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
123
+ /* Return to an EL which is configured for a different register width */
124
+ goto illegal_return;
125
+ }
126
+
127
+ if (new_el == 2 && arm_is_secure_below_el3(env)) {
128
+ /* Return to the non-existent secure-EL2 */
129
+ goto illegal_return;
130
+ }
131
+
132
+ if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
133
+ goto illegal_return;
134
+ }
135
+
136
+ qemu_mutex_lock_iothread();
137
+ arm_call_pre_el_change_hook(arm_env_get_cpu(env));
138
+ qemu_mutex_unlock_iothread();
139
+
140
+ if (!return_to_aa64) {
141
+ env->aarch64 = 0;
142
+ /* We do a raw CPSR write because aarch64_sync_64_to_32()
143
+ * will sort the register banks out for us, and we've already
144
+ * caught all the bad-mode cases in el_from_spsr().
145
+ */
146
+ cpsr_write(env, spsr, ~0, CPSRWriteRaw);
147
+ if (!arm_singlestep_active(env)) {
148
+ env->uncached_cpsr &= ~PSTATE_SS;
149
+ }
150
+ aarch64_sync_64_to_32(env);
151
+
152
+ if (spsr & CPSR_T) {
153
+ env->regs[15] = env->elr_el[cur_el] & ~0x1;
154
+ } else {
155
+ env->regs[15] = env->elr_el[cur_el] & ~0x3;
156
+ }
157
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
158
+ "AArch32 EL%d PC 0x%" PRIx32 "\n",
159
+ cur_el, new_el, env->regs[15]);
160
+ } else {
161
+ env->aarch64 = 1;
162
+ pstate_write(env, spsr);
163
+ if (!arm_singlestep_active(env)) {
164
+ env->pstate &= ~PSTATE_SS;
165
+ }
166
+ aarch64_restore_sp(env, new_el);
167
+ env->pc = env->elr_el[cur_el];
168
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
169
+ "AArch64 EL%d PC 0x%" PRIx64 "\n",
170
+ cur_el, new_el, env->pc);
171
+ }
172
+ /*
173
+ * Note that cur_el can never be 0. If new_el is 0, then
174
+ * el0_a64 is return_to_aa64, else el0_a64 is ignored.
175
+ */
176
+ aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
177
+
178
+ qemu_mutex_lock_iothread();
179
+ arm_call_el_change_hook(arm_env_get_cpu(env));
180
+ qemu_mutex_unlock_iothread();
181
+
182
+ return;
183
+
184
+illegal_return:
185
+ /* Illegal return events of various kinds have architecturally
186
+ * mandated behaviour:
187
+ * restore NZCV and DAIF from SPSR_ELx
188
+ * set PSTATE.IL
189
+ * restore PC from ELR_ELx
190
+ * no change to exception level, execution state or stack pointer
191
+ */
192
+ env->pstate |= PSTATE_IL;
193
+ env->pc = env->elr_el[cur_el];
194
+ spsr &= PSTATE_NZCV | PSTATE_DAIF;
195
+ spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
196
+ pstate_write(env, spsr);
197
+ if (!arm_singlestep_active(env)) {
198
+ env->pstate &= ~PSTATE_SS;
199
+ }
200
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
201
+ "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
202
+}
241
+}
203
+
242
+
204
/*
243
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
205
* Square Root and Reciprocal square root
244
0x09, 0x00, 0x00, 0x00 };
206
*/
245
207
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
246
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
208
index XXXXXXX..XXXXXXX 100644
247
index XXXXXXX..XXXXXXX 100644
209
--- a/target/arm/op_helper.c
248
--- a/hw/intc/exynos4210_gic.c
210
+++ b/target/arm/op_helper.c
249
+++ b/hw/intc/exynos4210_gic.c
211
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
250
@@ -XXX,XX +XXX,XX @@
212
}
251
#include "hw/arm/exynos4210.h"
213
}
252
#include "qom/object.h"
214
253
215
-static int el_from_spsr(uint32_t spsr)
254
-enum ExtGicId {
255
- EXT_GIC_ID_MDMA_LCD0 = 66,
256
- EXT_GIC_ID_PDMA0,
257
- EXT_GIC_ID_PDMA1,
258
- EXT_GIC_ID_TIMER0,
259
- EXT_GIC_ID_TIMER1,
260
- EXT_GIC_ID_TIMER2,
261
- EXT_GIC_ID_TIMER3,
262
- EXT_GIC_ID_TIMER4,
263
- EXT_GIC_ID_MCT_L0,
264
- EXT_GIC_ID_WDT,
265
- EXT_GIC_ID_RTC_ALARM,
266
- EXT_GIC_ID_RTC_TIC,
267
- EXT_GIC_ID_GPIO_XB,
268
- EXT_GIC_ID_GPIO_XA,
269
- EXT_GIC_ID_MCT_L1,
270
- EXT_GIC_ID_IEM_APC,
271
- EXT_GIC_ID_IEM_IEC,
272
- EXT_GIC_ID_NFC,
273
- EXT_GIC_ID_UART0,
274
- EXT_GIC_ID_UART1,
275
- EXT_GIC_ID_UART2,
276
- EXT_GIC_ID_UART3,
277
- EXT_GIC_ID_UART4,
278
- EXT_GIC_ID_MCT_G0,
279
- EXT_GIC_ID_I2C0,
280
- EXT_GIC_ID_I2C1,
281
- EXT_GIC_ID_I2C2,
282
- EXT_GIC_ID_I2C3,
283
- EXT_GIC_ID_I2C4,
284
- EXT_GIC_ID_I2C5,
285
- EXT_GIC_ID_I2C6,
286
- EXT_GIC_ID_I2C7,
287
- EXT_GIC_ID_SPI0,
288
- EXT_GIC_ID_SPI1,
289
- EXT_GIC_ID_SPI2,
290
- EXT_GIC_ID_MCT_G1,
291
- EXT_GIC_ID_USB_HOST,
292
- EXT_GIC_ID_USB_DEVICE,
293
- EXT_GIC_ID_MODEMIF,
294
- EXT_GIC_ID_HSMMC0,
295
- EXT_GIC_ID_HSMMC1,
296
- EXT_GIC_ID_HSMMC2,
297
- EXT_GIC_ID_HSMMC3,
298
- EXT_GIC_ID_SDMMC,
299
- EXT_GIC_ID_MIPI_CSI_4LANE,
300
- EXT_GIC_ID_MIPI_DSI_4LANE,
301
- EXT_GIC_ID_MIPI_CSI_2LANE,
302
- EXT_GIC_ID_MIPI_DSI_2LANE,
303
- EXT_GIC_ID_ONENAND_AUDI,
304
- EXT_GIC_ID_ROTATOR,
305
- EXT_GIC_ID_FIMC0,
306
- EXT_GIC_ID_FIMC1,
307
- EXT_GIC_ID_FIMC2,
308
- EXT_GIC_ID_FIMC3,
309
- EXT_GIC_ID_JPEG,
310
- EXT_GIC_ID_2D,
311
- EXT_GIC_ID_PCIe,
312
- EXT_GIC_ID_MIXER,
313
- EXT_GIC_ID_HDMI,
314
- EXT_GIC_ID_HDMI_I2C,
315
- EXT_GIC_ID_MFC,
316
- EXT_GIC_ID_TVENC,
317
-};
318
-
319
-enum ExtInt {
320
- EXT_GIC_ID_EXTINT0 = 48,
321
- EXT_GIC_ID_EXTINT1,
322
- EXT_GIC_ID_EXTINT2,
323
- EXT_GIC_ID_EXTINT3,
324
- EXT_GIC_ID_EXTINT4,
325
- EXT_GIC_ID_EXTINT5,
326
- EXT_GIC_ID_EXTINT6,
327
- EXT_GIC_ID_EXTINT7,
328
- EXT_GIC_ID_EXTINT8,
329
- EXT_GIC_ID_EXTINT9,
330
- EXT_GIC_ID_EXTINT10,
331
- EXT_GIC_ID_EXTINT11,
332
- EXT_GIC_ID_EXTINT12,
333
- EXT_GIC_ID_EXTINT13,
334
- EXT_GIC_ID_EXTINT14,
335
- EXT_GIC_ID_EXTINT15
336
-};
337
-
338
-/*
339
- * External GIC sources which are not from External Interrupt Combiner or
340
- * External Interrupts are starting from EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ,
341
- * which is INTG16 in Internal Interrupt Combiner.
342
- */
343
-
344
-static const uint32_t
345
-combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
346
- /* int combiner groups 16-19 */
347
- { }, { }, { }, { },
348
- /* int combiner group 20 */
349
- { 0, EXT_GIC_ID_MDMA_LCD0 },
350
- /* int combiner group 21 */
351
- { EXT_GIC_ID_PDMA0, EXT_GIC_ID_PDMA1 },
352
- /* int combiner group 22 */
353
- { EXT_GIC_ID_TIMER0, EXT_GIC_ID_TIMER1, EXT_GIC_ID_TIMER2,
354
- EXT_GIC_ID_TIMER3, EXT_GIC_ID_TIMER4 },
355
- /* int combiner group 23 */
356
- { EXT_GIC_ID_RTC_ALARM, EXT_GIC_ID_RTC_TIC },
357
- /* int combiner group 24 */
358
- { EXT_GIC_ID_GPIO_XB, EXT_GIC_ID_GPIO_XA },
359
- /* int combiner group 25 */
360
- { EXT_GIC_ID_IEM_APC, EXT_GIC_ID_IEM_IEC },
361
- /* int combiner group 26 */
362
- { EXT_GIC_ID_UART0, EXT_GIC_ID_UART1, EXT_GIC_ID_UART2, EXT_GIC_ID_UART3,
363
- EXT_GIC_ID_UART4 },
364
- /* int combiner group 27 */
365
- { EXT_GIC_ID_I2C0, EXT_GIC_ID_I2C1, EXT_GIC_ID_I2C2, EXT_GIC_ID_I2C3,
366
- EXT_GIC_ID_I2C4, EXT_GIC_ID_I2C5, EXT_GIC_ID_I2C6,
367
- EXT_GIC_ID_I2C7 },
368
- /* int combiner group 28 */
369
- { EXT_GIC_ID_SPI0, EXT_GIC_ID_SPI1, EXT_GIC_ID_SPI2 , EXT_GIC_ID_USB_HOST},
370
- /* int combiner group 29 */
371
- { EXT_GIC_ID_HSMMC0, EXT_GIC_ID_HSMMC1, EXT_GIC_ID_HSMMC2,
372
- EXT_GIC_ID_HSMMC3, EXT_GIC_ID_SDMMC },
373
- /* int combiner group 30 */
374
- { EXT_GIC_ID_MIPI_CSI_4LANE, EXT_GIC_ID_MIPI_CSI_2LANE },
375
- /* int combiner group 31 */
376
- { EXT_GIC_ID_MIPI_DSI_4LANE, EXT_GIC_ID_MIPI_DSI_2LANE },
377
- /* int combiner group 32 */
378
- { EXT_GIC_ID_FIMC0, EXT_GIC_ID_FIMC1 },
379
- /* int combiner group 33 */
380
- { EXT_GIC_ID_FIMC2, EXT_GIC_ID_FIMC3 },
381
- /* int combiner group 34 */
382
- { EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
383
- /* int combiner group 35 */
384
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
385
- /* int combiner group 36 */
386
- { EXT_GIC_ID_MIXER },
387
- /* int combiner group 37 */
388
- { EXT_GIC_ID_EXTINT4, EXT_GIC_ID_EXTINT5, EXT_GIC_ID_EXTINT6,
389
- EXT_GIC_ID_EXTINT7 },
390
- /* groups 38-50 */
391
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
392
- /* int combiner group 51 */
393
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
394
- /* group 52 */
395
- { },
396
- /* int combiner group 53 */
397
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
398
- /* groups 54-63 */
399
- { }, { }, { }, { }, { }, { }, { }, { }, { }, { }
400
-};
401
-
402
#define EXYNOS4210_GIC_NIRQ 160
403
404
#define EXYNOS4210_EXT_GIC_CPU_REGION_SIZE 0x10000
405
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
406
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
407
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
408
409
-/*
410
- * Initialize board IRQs.
411
- * These IRQs contain splitted Int/External Combiner and External Gic IRQs.
412
- */
413
-void exynos4210_init_board_irqs(Exynos4210State *s)
216
-{
414
-{
217
- /* Return the exception level that this SPSR is requesting a return to,
415
- uint32_t grp, bit, irq_id, n;
218
- * or -1 if it is invalid (an illegal return)
416
- Exynos4210Irq *is = &s->irqs;
219
- */
417
-
220
- if (spsr & PSTATE_nRW) {
418
- for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
221
- switch (spsr & CPSR_M) {
419
- irq_id = 0;
222
- case ARM_CPU_MODE_USR:
420
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
223
- return 0;
421
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
224
- case ARM_CPU_MODE_HYP:
422
- /* MCT_G0 is passed to External GIC */
225
- return 2;
423
- irq_id = EXT_GIC_ID_MCT_G0;
226
- case ARM_CPU_MODE_FIQ:
227
- case ARM_CPU_MODE_IRQ:
228
- case ARM_CPU_MODE_SVC:
229
- case ARM_CPU_MODE_ABT:
230
- case ARM_CPU_MODE_UND:
231
- case ARM_CPU_MODE_SYS:
232
- return 1;
233
- case ARM_CPU_MODE_MON:
234
- /* Returning to Mon from AArch64 is never possible,
235
- * so this is an illegal return.
236
- */
237
- default:
238
- return -1;
239
- }
424
- }
240
- } else {
425
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
241
- if (extract32(spsr, 1, 1)) {
426
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
242
- /* Return with reserved M[1] bit set */
427
- /* MCT_G1 is passed to External and GIC */
243
- return -1;
428
- irq_id = EXT_GIC_ID_MCT_G1;
244
- }
429
- }
245
- if (extract32(spsr, 0, 4) == 1) {
430
- if (irq_id) {
246
- /* return to EL0 with M[0] bit set */
431
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
247
- return -1;
432
- is->ext_gic_irq[irq_id - 32]);
433
- } else {
434
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
435
- is->ext_combiner_irq[n]);
248
- }
436
- }
249
- return extract32(spsr, 2, 2);
437
- }
438
- for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
439
- /* these IDs are passed to Internal Combiner and External GIC */
440
- grp = EXYNOS4210_COMBINER_GET_GRP_NUM(n);
441
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
442
- irq_id = combiner_grp_to_gic_id[grp -
443
- EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
444
-
445
- if (irq_id) {
446
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
447
- is->ext_gic_irq[irq_id - 32]);
448
- }
250
- }
449
- }
251
-}
450
-}
252
-
451
-
253
-void HELPER(exception_return)(CPUARMState *env)
452
-/*
453
- * Get IRQ number from exynos4210 IRQ subsystem stub.
454
- * To identify IRQ source use internal combiner group and bit number
455
- * grp - group number
456
- * bit - bit number inside group
457
- */
458
-uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
254
-{
459
-{
255
- int cur_el = arm_current_el(env);
460
- return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
256
- unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
257
- uint32_t spsr = env->banked_spsr[spsr_idx];
258
- int new_el;
259
- bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
260
-
261
- aarch64_save_sp(env, cur_el);
262
-
263
- arm_clear_exclusive(env);
264
-
265
- /* We must squash the PSTATE.SS bit to zero unless both of the
266
- * following hold:
267
- * 1. debug exceptions are currently disabled
268
- * 2. singlestep will be active in the EL we return to
269
- * We check 1 here and 2 after we've done the pstate/cpsr write() to
270
- * transition to the EL we're going to.
271
- */
272
- if (arm_generate_debug_exceptions(env)) {
273
- spsr &= ~PSTATE_SS;
274
- }
275
-
276
- new_el = el_from_spsr(spsr);
277
- if (new_el == -1) {
278
- goto illegal_return;
279
- }
280
- if (new_el > cur_el
281
- || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
282
- /* Disallow return to an EL which is unimplemented or higher
283
- * than the current one.
284
- */
285
- goto illegal_return;
286
- }
287
-
288
- if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
289
- /* Return to an EL which is configured for a different register width */
290
- goto illegal_return;
291
- }
292
-
293
- if (new_el == 2 && arm_is_secure_below_el3(env)) {
294
- /* Return to the non-existent secure-EL2 */
295
- goto illegal_return;
296
- }
297
-
298
- if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
299
- goto illegal_return;
300
- }
301
-
302
- qemu_mutex_lock_iothread();
303
- arm_call_pre_el_change_hook(arm_env_get_cpu(env));
304
- qemu_mutex_unlock_iothread();
305
-
306
- if (!return_to_aa64) {
307
- env->aarch64 = 0;
308
- /* We do a raw CPSR write because aarch64_sync_64_to_32()
309
- * will sort the register banks out for us, and we've already
310
- * caught all the bad-mode cases in el_from_spsr().
311
- */
312
- cpsr_write(env, spsr, ~0, CPSRWriteRaw);
313
- if (!arm_singlestep_active(env)) {
314
- env->uncached_cpsr &= ~PSTATE_SS;
315
- }
316
- aarch64_sync_64_to_32(env);
317
-
318
- if (spsr & CPSR_T) {
319
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
320
- } else {
321
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
322
- }
323
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
324
- "AArch32 EL%d PC 0x%" PRIx32 "\n",
325
- cur_el, new_el, env->regs[15]);
326
- } else {
327
- env->aarch64 = 1;
328
- pstate_write(env, spsr);
329
- if (!arm_singlestep_active(env)) {
330
- env->pstate &= ~PSTATE_SS;
331
- }
332
- aarch64_restore_sp(env, new_el);
333
- env->pc = env->elr_el[cur_el];
334
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
335
- "AArch64 EL%d PC 0x%" PRIx64 "\n",
336
- cur_el, new_el, env->pc);
337
- }
338
- /*
339
- * Note that cur_el can never be 0. If new_el is 0, then
340
- * el0_a64 is return_to_aa64, else el0_a64 is ignored.
341
- */
342
- aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
343
-
344
- qemu_mutex_lock_iothread();
345
- arm_call_el_change_hook(arm_env_get_cpu(env));
346
- qemu_mutex_unlock_iothread();
347
-
348
- return;
349
-
350
-illegal_return:
351
- /* Illegal return events of various kinds have architecturally
352
- * mandated behaviour:
353
- * restore NZCV and DAIF from SPSR_ELx
354
- * set PSTATE.IL
355
- * restore PC from ELR_ELx
356
- * no change to exception level, execution state or stack pointer
357
- */
358
- env->pstate |= PSTATE_IL;
359
- env->pc = env->elr_el[cur_el];
360
- spsr &= PSTATE_NZCV | PSTATE_DAIF;
361
- spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
362
- pstate_write(env, spsr);
363
- if (!arm_singlestep_active(env)) {
364
- env->pstate &= ~PSTATE_SS;
365
- }
366
- qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
367
- "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
368
-}
461
-}
369
-
462
-
370
/* Return true if the linked breakpoint entry lbn passes its checks */
463
-/********* GIC part *********/
371
static bool linked_bp_matches(ARMCPU *cpu, int lbn)
464
-
372
{
465
#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
466
OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
467
373
--
468
--
374
2.20.1
469
2.25.1
375
376
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Switch the creation of the external GIC to the new-style "embedded in
2
state struct" approach, so we can easily refer to the object
3
elsewhere during realize.
2
4
3
Add an array for PMOVSSET so we only define it for v7ve+ platforms
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220404154658.565020-9-peter.maydell@linaro.org
8
---
9
include/hw/arm/exynos4210.h | 2 ++
10
include/hw/intc/exynos4210_gic.h | 43 ++++++++++++++++++++++++++++++++
11
hw/arm/exynos4210.c | 10 ++++----
12
hw/intc/exynos4210_gic.c | 17 ++-----------
13
MAINTAINERS | 2 +-
14
5 files changed, 53 insertions(+), 21 deletions(-)
15
create mode 100644 include/hw/intc/exynos4210_gic.h
4
16
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20181211151945.29137-7-aaron@os.amperecomputing.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.c | 28 ++++++++++++++++++++++++++++
11
1 file changed, 28 insertions(+)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
19
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/helper.c
20
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
21
@@ -XXX,XX +XXX,XX @@
18
env->cp15.c9_pmovsr &= ~value;
22
#include "hw/or-irq.h"
19
}
23
#include "hw/sysbus.h"
20
24
#include "hw/cpu/a9mpcore.h"
21
+static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
25
+#include "hw/intc/exynos4210_gic.h"
22
+ uint64_t value)
26
#include "target/arm/cpu-qom.h"
23
+{
27
#include "qom/object.h"
24
+ value &= pmu_counter_mask(env);
28
25
+ env->cp15.c9_pmovsr |= value;
29
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
26
+}
30
qemu_or_irq pl330_irq_orgate[EXYNOS4210_NUM_DMA];
31
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
32
A9MPPrivState a9mpcore;
33
+ Exynos4210GicState ext_gic;
34
};
35
36
#define TYPE_EXYNOS4210_SOC "exynos4210"
37
diff --git a/include/hw/intc/exynos4210_gic.h b/include/hw/intc/exynos4210_gic.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/intc/exynos4210_gic.h
42
@@ -XXX,XX +XXX,XX @@
43
+/*
44
+ * Samsung exynos4210 GIC implementation. Based on hw/arm_gic.c
45
+ *
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
47
+ * All rights reserved.
48
+ *
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or modify it
52
+ * under the terms of the GNU General Public License as published by the
53
+ * Free Software Foundation; either version 2 of the License, or (at your
54
+ * option) any later version.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
59
+ * See the GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
64
+#ifndef HW_INTC_EXYNOS4210_GIC_H
65
+#define HW_INTC_EXYNOS4210_GIC_H
27
+
66
+
28
static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
67
+#include "hw/sysbus.h"
29
uint64_t value)
68
+
30
{
69
+#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
70
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
32
REGINFO_SENTINEL
71
+
33
};
72
+#define EXYNOS4210_GIC_NCPUS 2
34
73
+
35
+static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
74
+struct Exynos4210GicState {
36
+ /* PMOVSSET is not implemented in v7 before v7ve */
75
+ SysBusDevice parent_obj;
37
+ { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
76
+
38
+ .access = PL0_RW, .accessfn = pmreg_access,
77
+ MemoryRegion cpu_container;
39
+ .type = ARM_CP_ALIAS,
78
+ MemoryRegion dist_container;
40
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
79
+ MemoryRegion cpu_alias[EXYNOS4210_GIC_NCPUS];
41
+ .writefn = pmovsset_write,
80
+ MemoryRegion dist_alias[EXYNOS4210_GIC_NCPUS];
42
+ .raw_writefn = raw_write },
81
+ uint32_t num_cpu;
43
+ { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
82
+ DeviceState *gic;
44
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
45
+ .access = PL0_RW, .accessfn = pmreg_access,
46
+ .type = ARM_CP_ALIAS,
47
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
48
+ .writefn = pmovsset_write,
49
+ .raw_writefn = raw_write },
50
+ REGINFO_SENTINEL
51
+};
83
+};
52
+
84
+
53
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
85
+#endif
54
uint64_t value)
86
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/arm/exynos4210.c
89
+++ b/hw/arm/exynos4210.c
90
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
91
sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
92
93
/* External GIC */
94
- dev = qdev_new("exynos4210.gic");
95
- qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
96
- busdev = SYS_BUS_DEVICE(dev);
97
- sysbus_realize_and_unref(busdev, &error_fatal);
98
+ qdev_prop_set_uint32(DEVICE(&s->ext_gic), "num-cpu", EXYNOS4210_NCPUS);
99
+ busdev = SYS_BUS_DEVICE(&s->ext_gic);
100
+ sysbus_realize(busdev, &error_fatal);
101
/* Map CPU interface */
102
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
103
/* Map Distributer interface */
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
106
}
107
for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
108
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
109
+ s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
110
}
111
112
/* Internal Interrupt Combiner */
113
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
114
}
115
116
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
117
+ object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
118
}
119
120
static void exynos4210_class_init(ObjectClass *klass, void *data)
121
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/hw/intc/exynos4210_gic.c
124
+++ b/hw/intc/exynos4210_gic.c
125
@@ -XXX,XX +XXX,XX @@
126
#include "qemu/module.h"
127
#include "hw/irq.h"
128
#include "hw/qdev-properties.h"
129
+#include "hw/intc/exynos4210_gic.h"
130
#include "hw/arm/exynos4210.h"
131
#include "qom/object.h"
132
133
@@ -XXX,XX +XXX,XX @@
134
#define EXYNOS4210_GIC_CPU_REGION_SIZE 0x100
135
#define EXYNOS4210_GIC_DIST_REGION_SIZE 0x1000
136
137
-#define TYPE_EXYNOS4210_GIC "exynos4210.gic"
138
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210GicState, EXYNOS4210_GIC)
139
-
140
-struct Exynos4210GicState {
141
- SysBusDevice parent_obj;
142
-
143
- MemoryRegion cpu_container;
144
- MemoryRegion dist_container;
145
- MemoryRegion cpu_alias[EXYNOS4210_NCPUS];
146
- MemoryRegion dist_alias[EXYNOS4210_NCPUS];
147
- uint32_t num_cpu;
148
- DeviceState *gic;
149
-};
150
-
151
static void exynos4210_gic_set_irq(void *opaque, int irq, int level)
55
{
152
{
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
153
Exynos4210GicState *s = (Exynos4210GicState *)opaque;
57
!arm_feature(env, ARM_FEATURE_PMSA)) {
154
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_realize(DeviceState *dev, Error **errp)
58
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
155
* enough room for the cpu numbers. gcc 9.2.1 on 32-bit x86
59
}
156
* doesn't figure this out, otherwise and gives spurious warnings.
60
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
157
*/
61
+ define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
158
- assert(n <= EXYNOS4210_NCPUS);
62
+ }
159
+ assert(n <= EXYNOS4210_GIC_NCPUS);
63
if (arm_feature(env, ARM_FEATURE_V7)) {
160
for (i = 0; i < n; i++) {
64
/* v7 performance monitor control register: same implementor
161
/* Map CPU interface per SMP Core */
65
* field as main ID register, and we implement only the cycle
162
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
163
diff --git a/MAINTAINERS b/MAINTAINERS
164
index XXXXXXX..XXXXXXX 100644
165
--- a/MAINTAINERS
166
+++ b/MAINTAINERS
167
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
168
L: qemu-arm@nongnu.org
169
S: Odd Fixes
170
F: hw/*/exynos*
171
-F: include/hw/arm/exynos4210.h
172
+F: include/hw/*/exynos*
173
174
Calxeda Highbank
175
M: Rob Herring <robh@kernel.org>
66
--
176
--
67
2.20.1
177
2.25.1
68
69
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The only time we use the ext_gic_irq[] array in the Exynos4210Irq
2
struct is during realize of the SoC -- we initialize it with the
3
input IRQs of the external GIC device, and then connect those to
4
outputs of other devices further on in realize (including in the
5
exynos4210_init_board_irqs() function). Now that the ext_gic object
6
is easily accessible as s->ext_gic we can make the connections
7
directly from one device to the other without going via this array.
2
8
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-10-peter.maydell@linaro.org
7
---
12
---
8
target/arm/helper-a64.h | 2 +-
13
include/hw/arm/exynos4210.h | 1 -
9
target/arm/helper-a64.c | 10 +++++-----
14
hw/arm/exynos4210.c | 12 ++++++------
10
target/arm/translate-a64.c | 7 ++++++-
15
2 files changed, 6 insertions(+), 7 deletions(-)
11
3 files changed, 12 insertions(+), 7 deletions(-)
12
16
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
19
--- a/include/hw/arm/exynos4210.h
16
+++ b/target/arm/helper-a64.h
20
+++ b/include/hw/arm/exynos4210.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
21
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
22
typedef struct Exynos4210Irq {
19
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
23
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
20
24
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
21
-DEF_HELPER_1(exception_return, void, env)
25
- qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
22
+DEF_HELPER_2(exception_return, void, env, i64)
26
} Exynos4210Irq;
23
27
24
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
28
struct Exynos4210State {
25
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
29
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper-a64.c
31
--- a/hw/arm/exynos4210.c
29
+++ b/target/arm/helper-a64.c
32
+++ b/hw/arm/exynos4210.c
30
@@ -XXX,XX +XXX,XX @@ static int el_from_spsr(uint32_t spsr)
33
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
34
{
35
uint32_t grp, bit, irq_id, n;
36
Exynos4210Irq *is = &s->irqs;
37
+ DeviceState *extgicdev = DEVICE(&s->ext_gic);
38
39
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
40
irq_id = 0;
41
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
42
}
43
if (irq_id) {
44
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
45
- is->ext_gic_irq[irq_id - 32]);
46
+ qdev_get_gpio_in(extgicdev,
47
+ irq_id - 32));
48
} else {
49
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
50
is->ext_combiner_irq[n]);
51
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
53
if (irq_id) {
54
s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
55
- is->ext_gic_irq[irq_id - 32]);
56
+ qdev_get_gpio_in(extgicdev,
57
+ irq_id - 32));
58
}
31
}
59
}
32
}
60
}
33
61
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
34
-void HELPER(exception_return)(CPUARMState *env)
62
sysbus_connect_irq(busdev, n,
35
+void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
63
qdev_get_gpio_in(DEVICE(&s->cpu_irq_orgate[n]), 1));
36
{
64
}
37
int cur_el = arm_current_el(env);
65
- for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
38
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
66
- s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(DEVICE(&s->ext_gic), n);
39
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
67
- }
40
aarch64_sync_64_to_32(env);
68
41
69
/* Internal Interrupt Combiner */
42
if (spsr & CPSR_T) {
70
dev = qdev_new("exynos4210.combiner");
43
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
44
+ env->regs[15] = new_pc & ~0x1;
72
busdev = SYS_BUS_DEVICE(dev);
45
} else {
73
sysbus_realize_and_unref(busdev, &error_fatal);
46
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
74
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
47
+ env->regs[15] = new_pc & ~0x3;
75
- sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
48
}
76
+ sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
49
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
77
}
50
"AArch32 EL%d PC 0x%" PRIx32 "\n",
78
exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
51
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
79
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
52
env->pstate &= ~PSTATE_SS;
53
}
54
aarch64_restore_sp(env, new_el);
55
- env->pc = env->elr_el[cur_el];
56
+ env->pc = new_pc;
57
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
58
"AArch64 EL%d PC 0x%" PRIx64 "\n",
59
cur_el, new_el, env->pc);
60
@@ -XXX,XX +XXX,XX @@ illegal_return:
61
* no change to exception level, execution state or stack pointer
62
*/
63
env->pstate |= PSTATE_IL;
64
- env->pc = env->elr_el[cur_el];
65
+ env->pc = new_pc;
66
spsr &= PSTATE_NZCV | PSTATE_DAIF;
67
spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
68
pstate_write(env, spsr);
69
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-a64.c
72
+++ b/target/arm/translate-a64.c
73
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
74
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
75
{
76
unsigned int opc, op2, op3, rn, op4;
77
+ TCGv_i64 dst;
78
79
opc = extract32(insn, 21, 4);
80
op2 = extract32(insn, 16, 5);
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
83
gen_io_start();
84
}
85
- gen_helper_exception_return(cpu_env);
86
+ dst = tcg_temp_new_i64();
87
+ tcg_gen_ld_i64(dst, cpu_env,
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
89
+ gen_helper_exception_return(cpu_env, dst);
90
+ tcg_temp_free_i64(dst);
91
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
92
gen_io_end();
93
}
94
--
80
--
95
2.20.1
81
2.25.1
96
97
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The function exynos4210_combiner_get_gpioin() currently lives in
2
exynos4210_combiner.c, but it isn't really part of the combiner
3
device itself -- it is a function that implements the wiring up of
4
some interrupt sources to multiple combiner inputs. Move it to live
5
with the other SoC-level code in exynos4210.c, along with a few
6
macros previously defined in exynos4210.h which are now used only
7
in exynos4210.c.
2
8
3
Not that there are any stores involved, but why argue with ARM's
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
naming convention.
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220404154658.565020-11-peter.maydell@linaro.org
12
---
13
include/hw/arm/exynos4210.h | 11 -----
14
hw/arm/exynos4210.c | 82 +++++++++++++++++++++++++++++++++++
15
hw/intc/exynos4210_combiner.c | 77 --------------------------------
16
3 files changed, 82 insertions(+), 88 deletions(-)
5
17
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
18
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-15-richard.henderson@linaro.org
9
[fixed trivial comment nit]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 61 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
20
--- a/include/hw/arm/exynos4210.h
18
+++ b/target/arm/translate-a64.c
21
+++ b/include/hw/arm/exynos4210.h
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
22
@@ -XXX,XX +XXX,XX @@
20
s->be_data | size | MO_ALIGN);
23
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
24
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
25
26
-#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
27
-#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
28
-#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
29
- ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
30
-
31
/* IRQs number for external and internal GIC */
32
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
33
#define EXYNOS4210_INT_GIC_NIRQ 64
34
@@ -XXX,XX +XXX,XX @@ void exynos4210_write_secondary(ARMCPU *cpu,
35
* bit - bit number inside group */
36
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
37
38
-/*
39
- * Get Combiner input GPIO into irqs structure
40
- */
41
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
42
- int ext);
43
-
44
/*
45
* exynos4210 UART
46
*/
47
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/exynos4210.c
50
+++ b/hw/arm/exynos4210.c
51
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
52
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
53
};
54
55
+#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp) * 8 + (bit))
56
+#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
57
+#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
58
+ ((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
59
+
60
/*
61
* Initialize board IRQs.
62
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
63
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
64
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
21
}
65
}
22
66
23
+/*
67
+/*
24
+ * PAC memory operations
68
+ * Get Combiner input GPIO into irqs structure
25
+ *
26
+ * 31 30 27 26 24 22 21 12 11 10 5 0
27
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
28
+ * | size | 1 1 1 | V | 0 0 | M S | 1 | imm9 | W | 1 | Rn | Rt |
29
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
30
+ *
31
+ * Rt: the result register
32
+ * Rn: base address or SP
33
+ * V: vector flag (always 0 as of v8.3)
34
+ * M: clear for key DA, set for key DB
35
+ * W: pre-indexing flag
36
+ * S: sign for imm9.
37
+ */
69
+ */
38
+static void disas_ldst_pac(DisasContext *s, uint32_t insn,
70
+static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
39
+ int size, int rt, bool is_vector)
71
+ DeviceState *dev, int ext)
40
+{
72
+{
41
+ int rn = extract32(insn, 5, 5);
73
+ int n;
42
+ bool is_wback = extract32(insn, 11, 1);
74
+ int bit;
43
+ bool use_key_a = !extract32(insn, 23, 1);
75
+ int max;
44
+ int offset;
76
+ qemu_irq *irq;
45
+ TCGv_i64 tcg_addr, tcg_rt;
77
+
46
+
78
+ max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
47
+ if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
79
+ EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
48
+ unallocated_encoding(s);
80
+ irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
49
+ return;
81
+
50
+ }
82
+ /*
51
+
83
+ * Some IRQs of Int/External Combiner are going to two Combiners groups,
52
+ if (rn == 31) {
84
+ * so let split them.
53
+ gen_check_sp_alignment(s);
85
+ */
54
+ }
86
+ for (n = 0; n < max; n++) {
55
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
87
+
56
+
88
+ bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
57
+ if (s->pauth_active) {
89
+
58
+ if (use_key_a) {
90
+ switch (n) {
59
+ gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
91
+ /* MDNIE_LCD1 INTG1 */
60
+ } else {
92
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
61
+ gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
93
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
94
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
95
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
96
+ continue;
97
+
98
+ /* TMU INTG3 */
99
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
100
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
101
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
102
+ continue;
103
+
104
+ /* LCD1 INTG12 */
105
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
106
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
107
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
108
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
109
+ continue;
110
+
111
+ /* Multi-Core Timer INTG12 */
112
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
113
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
114
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
115
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
116
+ continue;
117
+
118
+ /* Multi-Core Timer INTG35 */
119
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
120
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
121
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
122
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
123
+ continue;
124
+
125
+ /* Multi-Core Timer INTG51 */
126
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
127
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
128
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
129
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
130
+ continue;
131
+
132
+ /* Multi-Core Timer INTG53 */
133
+ case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
134
+ EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
135
+ irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
136
+ irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
137
+ continue;
62
+ }
138
+ }
63
+ }
139
+
64
+
140
+ irq[n] = qdev_get_gpio_in(dev, n);
65
+ /* Form the 10-bit signed, scaled offset. */
66
+ offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
67
+ offset = sextract32(offset << size, 0, 10 + size);
68
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
69
+
70
+ tcg_rt = cpu_reg(s, rt);
71
+
72
+ do_gpr_ld(s, tcg_rt, tcg_addr, size, /* is_signed */ false,
73
+ /* extend */ false, /* iss_valid */ !is_wback,
74
+ /* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
75
+
76
+ if (is_wback) {
77
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
78
+ }
141
+ }
79
+}
142
+}
80
+
143
+
81
/* Load/store register (all forms) */
144
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
82
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
145
0x09, 0x00, 0x00, 0x00 };
146
147
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/intc/exynos4210_combiner.c
150
+++ b/hw/intc/exynos4210_combiner.c
151
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_exynos4210_combiner = {
152
}
153
};
154
155
-/*
156
- * Get Combiner input GPIO into irqs structure
157
- */
158
-void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
159
- int ext)
160
-{
161
- int n;
162
- int bit;
163
- int max;
164
- qemu_irq *irq;
165
-
166
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
167
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
168
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
169
-
170
- /*
171
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
172
- * so let split them.
173
- */
174
- for (n = 0; n < max; n++) {
175
-
176
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
177
-
178
- switch (n) {
179
- /* MDNIE_LCD1 INTG1 */
180
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
181
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
182
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
183
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
184
- continue;
185
-
186
- /* TMU INTG3 */
187
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
188
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
189
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
190
- continue;
191
-
192
- /* LCD1 INTG12 */
193
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
194
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
195
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
196
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
197
- continue;
198
-
199
- /* Multi-Core Timer INTG12 */
200
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
201
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
202
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
203
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
204
- continue;
205
-
206
- /* Multi-Core Timer INTG35 */
207
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
208
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
209
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
210
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
211
- continue;
212
-
213
- /* Multi-Core Timer INTG51 */
214
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
215
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
216
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
217
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
218
- continue;
219
-
220
- /* Multi-Core Timer INTG53 */
221
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
222
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
223
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
224
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
225
- continue;
226
- }
227
-
228
- irq[n] = qdev_get_gpio_in(dev, n);
229
- }
230
-}
231
-
232
static uint64_t
233
exynos4210_combiner_read(void *opaque, hwaddr offset, unsigned size)
83
{
234
{
84
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
85
case 2:
86
disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
87
return;
88
+ default:
89
+ disas_ldst_pac(s, insn, size, rt, is_vector);
90
+ return;
91
}
92
break;
93
case 1:
94
--
235
--
95
2.20.1
236
2.25.1
96
97
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Delete a couple of #defines which are never used.
2
2
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20181211151945.29137-9-aaron@os.amperecomputing.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220404154658.565020-12-peter.maydell@linaro.org
7
---
6
---
8
target/arm/cpu.h | 4 ++--
7
include/hw/arm/exynos4210.h | 4 ----
9
target/arm/helper.c | 19 +++++++++++++++++--
8
1 file changed, 4 deletions(-)
10
2 files changed, 19 insertions(+), 4 deletions(-)
11
9
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
10
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
12
--- a/include/hw/arm/exynos4210.h
15
+++ b/target/arm/cpu.h
13
+++ b/include/hw/arm/exynos4210.h
16
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
14
@@ -XXX,XX +XXX,XX @@
17
uint32_t id_pfr0;
15
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
18
uint32_t id_pfr1;
16
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
19
uint32_t id_dfr0;
17
20
- uint32_t pmceid0;
18
-/* IRQs number for external and internal GIC */
21
- uint32_t pmceid1;
19
-#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
22
+ uint64_t pmceid0;
20
-#define EXYNOS4210_INT_GIC_NIRQ 64
23
+ uint64_t pmceid1;
21
-
24
uint32_t id_afr0;
22
#define EXYNOS4210_I2C_NUMBER 9
25
uint32_t id_mmfr0;
23
26
uint32_t id_mmfr1;
24
#define EXYNOS4210_NUM_DMA 3
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
32
} else {
33
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
34
}
35
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
36
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
37
+ ARMCPRegInfo v81_pmu_regs[] = {
38
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
39
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
40
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
41
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
42
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
43
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
44
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
45
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
46
+ REGINFO_SENTINEL
47
+ };
48
+ define_arm_cp_regs(cpu, v81_pmu_regs);
49
+ }
50
if (arm_feature(env, ARM_FEATURE_V8)) {
51
/* AArch64 ID registers, which all have impdef reset values.
52
* Note that within the ID register ranges the unused slots
53
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
54
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
55
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
56
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
57
- .resetvalue = cpu->pmceid0 },
58
+ .resetvalue = extract64(cpu->pmceid0, 0, 32) },
59
{ .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
60
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
61
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
{ .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
64
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
65
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
66
- .resetvalue = cpu->pmceid1 },
67
+ .resetvalue = extract64(cpu->pmceid1, 0, 32) },
68
{ .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
69
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
70
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
71
--
25
--
72
2.20.1
26
2.25.1
73
74
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
In exynos4210_init_board_irqs(), use the TYPE_SPLIT_IRQ device
2
instead of qemu_irq_split().
2
3
3
Split out functions to extract the virtual address parameters.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Let the functions choose T0 or T1 address space half, if present.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Extract (most of) the control bits that vary between EL or Tx.
6
Message-id: 20220404154658.565020-13-peter.maydell@linaro.org
7
---
8
include/hw/arm/exynos4210.h | 9 ++++++++
9
hw/arm/exynos4210.c | 41 +++++++++++++++++++++++++++++--------
10
2 files changed, 42 insertions(+), 8 deletions(-)
6
11
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-19-richard.henderson@linaro.org
10
[PMM: fixed minor checkpatch comment nits]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/internals.h | 14 +++
14
target/arm/helper.c | 278 ++++++++++++++++++++++-------------------
15
2 files changed, 164 insertions(+), 128 deletions(-)
16
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/internals.h
14
--- a/include/hw/arm/exynos4210.h
20
+++ b/target/arm/internals.h
15
+++ b/include/hw/arm/exynos4210.h
21
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
16
@@ -XXX,XX +XXX,XX @@
22
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
17
#include "hw/sysbus.h"
23
#endif
18
#include "hw/cpu/a9mpcore.h"
19
#include "hw/intc/exynos4210_gic.h"
20
+#include "hw/core/split-irq.h"
21
#include "target/arm/cpu-qom.h"
22
#include "qom/object.h"
23
24
@@ -XXX,XX +XXX,XX @@
25
26
#define EXYNOS4210_NUM_DMA 3
24
27
25
+/*
28
+/*
26
+ * Parameters of a given virtual address, as extracted from the
29
+ * We need one splitter for every external combiner input, plus
27
+ * translation control register (TCR) for a given regime.
30
+ * one for every non-zero entry in combiner_grp_to_gic_id[].
31
+ * We'll assert in exynos4210_init_board_irqs() if this is wrong.
28
+ */
32
+ */
29
+typedef struct ARMVAParameters {
33
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
30
+ unsigned tsz : 8;
31
+ unsigned select : 1;
32
+ bool tbi : 1;
33
+ bool epd : 1;
34
+ bool hpd : 1;
35
+ bool using16k : 1;
36
+ bool using64k : 1;
37
+} ARMVAParameters;
38
+
34
+
39
#endif
35
typedef struct Exynos4210Irq {
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
37
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
38
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
39
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
40
A9MPPrivState a9mpcore;
41
Exynos4210GicState ext_gic;
42
+ SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
43
};
44
45
#define TYPE_EXYNOS4210_SOC "exynos4210"
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
41
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.c
48
--- a/hw/arm/exynos4210.c
43
+++ b/target/arm/helper.c
49
+++ b/hw/arm/exynos4210.c
44
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
50
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
45
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
51
uint32_t grp, bit, irq_id, n;
52
Exynos4210Irq *is = &s->irqs;
53
DeviceState *extgicdev = DEVICE(&s->ext_gic);
54
+ int splitcount = 0;
55
+ DeviceState *splitter;
56
57
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
58
irq_id = 0;
59
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
60
/* MCT_G1 is passed to External and GIC */
61
irq_id = EXT_GIC_ID_MCT_G1;
62
}
63
+
64
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
65
+ splitter = DEVICE(&s->splitter[splitcount]);
66
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
67
+ qdev_realize(splitter, NULL, &error_abort);
68
+ splitcount++;
69
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
70
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
71
if (irq_id) {
72
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
73
- qdev_get_gpio_in(extgicdev,
74
- irq_id - 32));
75
+ qdev_connect_gpio_out(splitter, 1,
76
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
77
} else {
78
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
79
- is->ext_combiner_irq[n]);
80
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
81
}
82
}
83
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
84
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
85
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
86
87
if (irq_id) {
88
- s->irq_table[n] = qemu_irq_split(is->int_combiner_irq[n],
89
- qdev_get_gpio_in(extgicdev,
90
- irq_id - 32));
91
+ assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
92
+ splitter = DEVICE(&s->splitter[splitcount]);
93
+ qdev_prop_set_uint16(splitter, "num-lines", 2);
94
+ qdev_realize(splitter, NULL, &error_abort);
95
+ splitcount++;
96
+ s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
97
+ qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
98
+ qdev_connect_gpio_out(splitter, 1,
99
+ qdev_get_gpio_in(extgicdev, irq_id - 32));
100
}
101
}
102
+ /*
103
+ * We check this here to avoid a more obscure assert later when
104
+ * qdev_assert_realized_properly() checks that we realized every
105
+ * child object we initialized.
106
+ */
107
+ assert(splitcount == EXYNOS4210_NUM_SPLITTERS);
46
}
108
}
47
109
48
+static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
110
/*
49
+ ARMMMUIdx mmu_idx, bool data)
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
50
+{
112
object_initialize_child(obj, name, &s->cpu_irq_orgate[i], TYPE_OR_IRQ);
51
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
113
}
52
+ uint32_t el = regime_el(env, mmu_idx);
114
53
+ bool tbi, epd, hpd, using16k, using64k;
115
+ for (i = 0; i < ARRAY_SIZE(s->splitter); i++) {
54
+ int select, tsz;
116
+ g_autofree char *name = g_strdup_printf("irq-splitter%d", i);
55
+
117
+ object_initialize_child(obj, name, &s->splitter[i], TYPE_SPLIT_IRQ);
56
+ /*
57
+ * Bit 55 is always between the two regions, and is canonical for
58
+ * determining if address tagging is enabled.
59
+ */
60
+ select = extract64(va, 55, 1);
61
+
62
+ if (el > 1) {
63
+ tsz = extract32(tcr, 0, 6);
64
+ using64k = extract32(tcr, 14, 1);
65
+ using16k = extract32(tcr, 15, 1);
66
+ if (mmu_idx == ARMMMUIdx_S2NS) {
67
+ /* VTCR_EL2 */
68
+ tbi = hpd = false;
69
+ } else {
70
+ tbi = extract32(tcr, 20, 1);
71
+ hpd = extract32(tcr, 24, 1);
72
+ }
73
+ epd = false;
74
+ } else if (!select) {
75
+ tsz = extract32(tcr, 0, 6);
76
+ epd = extract32(tcr, 7, 1);
77
+ using64k = extract32(tcr, 14, 1);
78
+ using16k = extract32(tcr, 15, 1);
79
+ tbi = extract64(tcr, 37, 1);
80
+ hpd = extract64(tcr, 41, 1);
81
+ } else {
82
+ int tg = extract32(tcr, 30, 2);
83
+ using16k = tg == 1;
84
+ using64k = tg == 3;
85
+ tsz = extract32(tcr, 16, 6);
86
+ epd = extract32(tcr, 23, 1);
87
+ tbi = extract64(tcr, 38, 1);
88
+ hpd = extract64(tcr, 42, 1);
89
+ }
90
+ tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
91
+ tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
92
+
93
+ return (ARMVAParameters) {
94
+ .tsz = tsz,
95
+ .select = select,
96
+ .tbi = tbi,
97
+ .epd = epd,
98
+ .hpd = hpd,
99
+ .using16k = using16k,
100
+ .using64k = using64k,
101
+ };
102
+}
103
+
104
+static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
105
+ ARMMMUIdx mmu_idx)
106
+{
107
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
108
+ uint32_t el = regime_el(env, mmu_idx);
109
+ int select, tsz;
110
+ bool epd, hpd;
111
+
112
+ if (mmu_idx == ARMMMUIdx_S2NS) {
113
+ /* VTCR */
114
+ bool sext = extract32(tcr, 4, 1);
115
+ bool sign = extract32(tcr, 3, 1);
116
+
117
+ /*
118
+ * If the sign-extend bit is not the same as t0sz[3], the result
119
+ * is unpredictable. Flag this as a guest error.
120
+ */
121
+ if (sign != sext) {
122
+ qemu_log_mask(LOG_GUEST_ERROR,
123
+ "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
124
+ }
125
+ tsz = sextract32(tcr, 0, 4) + 8;
126
+ select = 0;
127
+ hpd = false;
128
+ epd = false;
129
+ } else if (el == 2) {
130
+ /* HTCR */
131
+ tsz = extract32(tcr, 0, 3);
132
+ select = 0;
133
+ hpd = extract64(tcr, 24, 1);
134
+ epd = false;
135
+ } else {
136
+ int t0sz = extract32(tcr, 0, 3);
137
+ int t1sz = extract32(tcr, 16, 3);
138
+
139
+ if (t1sz == 0) {
140
+ select = va > (0xffffffffu >> t0sz);
141
+ } else {
142
+ /* Note that we will detect errors later. */
143
+ select = va >= ~(0xffffffffu >> t1sz);
144
+ }
145
+ if (!select) {
146
+ tsz = t0sz;
147
+ epd = extract32(tcr, 7, 1);
148
+ hpd = extract64(tcr, 41, 1);
149
+ } else {
150
+ tsz = t1sz;
151
+ epd = extract32(tcr, 23, 1);
152
+ hpd = extract64(tcr, 42, 1);
153
+ }
154
+ /* For aarch32, hpd0 is not enabled without t2e as well. */
155
+ hpd &= extract32(tcr, 6, 1);
156
+ }
118
+ }
157
+
119
+
158
+ return (ARMVAParameters) {
120
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
159
+ .tsz = tsz,
121
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
160
+ .select = select,
122
}
161
+ .epd = epd,
162
+ .hpd = hpd,
163
+ };
164
+}
165
+
166
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
167
MMUAccessType access_type, ARMMMUIdx mmu_idx,
168
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
169
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
170
/* Read an LPAE long-descriptor translation table. */
171
ARMFaultType fault_type = ARMFault_Translation;
172
uint32_t level;
173
- uint32_t epd = 0;
174
- int32_t t0sz, t1sz;
175
- uint32_t tg;
176
+ ARMVAParameters param;
177
uint64_t ttbr;
178
- int ttbr_select;
179
hwaddr descaddr, indexmask, indexmask_grainsize;
180
uint32_t tableattrs;
181
- target_ulong page_size;
182
+ target_ulong page_size, top_bits;
183
uint32_t attrs;
184
- int32_t stride = 9;
185
- int32_t addrsize;
186
- int inputsize;
187
- int32_t tbi = 0;
188
+ int32_t stride;
189
+ int addrsize, inputsize;
190
TCR *tcr = regime_tcr(env, mmu_idx);
191
int ap, ns, xn, pxn;
192
uint32_t el = regime_el(env, mmu_idx);
193
- bool ttbr1_valid = true;
194
+ bool ttbr1_valid;
195
uint64_t descaddrmask;
196
bool aarch64 = arm_el_is_aa64(env, el);
197
- bool hpd = false;
198
199
/* TODO:
200
* This code does not handle the different format TCR for VTCR_EL2.
201
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
202
* support for those page table walks.
203
*/
204
if (aarch64) {
205
+ param = aa64_va_parameters(env, address, mmu_idx,
206
+ access_type != MMU_INST_FETCH);
207
level = 0;
208
- addrsize = 64;
209
- if (el > 1) {
210
- if (mmu_idx != ARMMMUIdx_S2NS) {
211
- tbi = extract64(tcr->raw_tcr, 20, 1);
212
- }
213
- } else {
214
- if (extract64(address, 55, 1)) {
215
- tbi = extract64(tcr->raw_tcr, 38, 1);
216
- } else {
217
- tbi = extract64(tcr->raw_tcr, 37, 1);
218
- }
219
- }
220
- tbi *= 8;
221
-
222
/* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it
223
* invalid.
224
*/
225
- if (el > 1) {
226
- ttbr1_valid = false;
227
- }
228
+ ttbr1_valid = (el < 2);
229
+ addrsize = 64 - 8 * param.tbi;
230
+ inputsize = 64 - param.tsz;
231
} else {
232
+ param = aa32_va_parameters(env, address, mmu_idx);
233
level = 1;
234
- addrsize = 32;
235
/* There is no TTBR1 for EL2 */
236
- if (el == 2) {
237
- ttbr1_valid = false;
238
- }
239
+ ttbr1_valid = (el != 2);
240
+ addrsize = (mmu_idx == ARMMMUIdx_S2NS ? 40 : 32);
241
+ inputsize = addrsize - param.tsz;
242
}
243
244
- /* Determine whether this address is in the region controlled by
245
- * TTBR0 or TTBR1 (or if it is in neither region and should fault).
246
- * This is a Non-secure PL0/1 stage 1 translation, so controlled by
247
- * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
248
+ /*
249
+ * We determined the region when collecting the parameters, but we
250
+ * have not yet validated that the address is valid for the region.
251
+ * Extract the top bits and verify that they all match select.
252
*/
253
- if (aarch64) {
254
- /* AArch64 translation. */
255
- t0sz = extract32(tcr->raw_tcr, 0, 6);
256
- t0sz = MIN(t0sz, 39);
257
- t0sz = MAX(t0sz, 16);
258
- } else if (mmu_idx != ARMMMUIdx_S2NS) {
259
- /* AArch32 stage 1 translation. */
260
- t0sz = extract32(tcr->raw_tcr, 0, 3);
261
- } else {
262
- /* AArch32 stage 2 translation. */
263
- bool sext = extract32(tcr->raw_tcr, 4, 1);
264
- bool sign = extract32(tcr->raw_tcr, 3, 1);
265
- /* Address size is 40-bit for a stage 2 translation,
266
- * and t0sz can be negative (from -8 to 7),
267
- * so we need to adjust it to use the TTBR selecting logic below.
268
- */
269
- addrsize = 40;
270
- t0sz = sextract32(tcr->raw_tcr, 0, 4) + 8;
271
-
272
- /* If the sign-extend bit is not the same as t0sz[3], the result
273
- * is unpredictable. Flag this as a guest error. */
274
- if (sign != sext) {
275
- qemu_log_mask(LOG_GUEST_ERROR,
276
- "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
277
- }
278
- }
279
- t1sz = extract32(tcr->raw_tcr, 16, 6);
280
- if (aarch64) {
281
- t1sz = MIN(t1sz, 39);
282
- t1sz = MAX(t1sz, 16);
283
- }
284
- if (t0sz && !extract64(address, addrsize - t0sz, t0sz - tbi)) {
285
- /* there is a ttbr0 region and we are in it (high bits all zero) */
286
- ttbr_select = 0;
287
- } else if (ttbr1_valid && t1sz &&
288
- !extract64(~address, addrsize - t1sz, t1sz - tbi)) {
289
- /* there is a ttbr1 region and we are in it (high bits all one) */
290
- ttbr_select = 1;
291
- } else if (!t0sz) {
292
- /* ttbr0 region is "everything not in the ttbr1 region" */
293
- ttbr_select = 0;
294
- } else if (!t1sz && ttbr1_valid) {
295
- /* ttbr1 region is "everything not in the ttbr0 region" */
296
- ttbr_select = 1;
297
- } else {
298
- /* in the gap between the two regions, this is a Translation fault */
299
+ top_bits = sextract64(address, inputsize, addrsize - inputsize);
300
+ if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
301
+ /* In the gap between the two regions, this is a Translation fault */
302
fault_type = ARMFault_Translation;
303
goto do_fault;
304
}
305
306
+ if (param.using64k) {
307
+ stride = 13;
308
+ } else if (param.using16k) {
309
+ stride = 11;
310
+ } else {
311
+ stride = 9;
312
+ }
313
+
314
/* Note that QEMU ignores shareability and cacheability attributes,
315
* so we don't need to do anything with the SH, ORGN, IRGN fields
316
* in the TTBCR. Similarly, TTBCR:A1 selects whether we get the
317
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
318
* implement any ASID-like capability so we can ignore it (instead
319
* we will always flush the TLB any time the ASID is changed).
320
*/
321
- if (ttbr_select == 0) {
322
- ttbr = regime_ttbr(env, mmu_idx, 0);
323
- if (el < 2) {
324
- epd = extract32(tcr->raw_tcr, 7, 1);
325
- }
326
- inputsize = addrsize - t0sz;
327
-
328
- tg = extract32(tcr->raw_tcr, 14, 2);
329
- if (tg == 1) { /* 64KB pages */
330
- stride = 13;
331
- }
332
- if (tg == 2) { /* 16KB pages */
333
- stride = 11;
334
- }
335
- if (aarch64 && el > 1) {
336
- hpd = extract64(tcr->raw_tcr, 24, 1);
337
- } else {
338
- hpd = extract64(tcr->raw_tcr, 41, 1);
339
- }
340
- if (!aarch64) {
341
- /* For aarch32, hpd0 is not enabled without t2e as well. */
342
- hpd &= extract64(tcr->raw_tcr, 6, 1);
343
- }
344
- } else {
345
- /* We should only be here if TTBR1 is valid */
346
- assert(ttbr1_valid);
347
-
348
- ttbr = regime_ttbr(env, mmu_idx, 1);
349
- epd = extract32(tcr->raw_tcr, 23, 1);
350
- inputsize = addrsize - t1sz;
351
-
352
- tg = extract32(tcr->raw_tcr, 30, 2);
353
- if (tg == 3) { /* 64KB pages */
354
- stride = 13;
355
- }
356
- if (tg == 1) { /* 16KB pages */
357
- stride = 11;
358
- }
359
- hpd = extract64(tcr->raw_tcr, 42, 1);
360
- if (!aarch64) {
361
- /* For aarch32, hpd1 is not enabled without t2e as well. */
362
- hpd &= extract64(tcr->raw_tcr, 6, 1);
363
- }
364
- }
365
+ ttbr = regime_ttbr(env, mmu_idx, param.select);
366
367
/* Here we should have set up all the parameters for the translation:
368
* inputsize, ttbr, epd, stride, tbi
369
*/
370
371
- if (epd) {
372
+ if (param.epd) {
373
/* Translation table walk disabled => Translation fault on TLB miss
374
* Note: This is always 0 on 64-bit EL2 and EL3.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
377
}
378
/* Merge in attributes from table descriptors */
379
attrs |= nstable << 3; /* NS */
380
- if (hpd) {
381
+ if (param.hpd) {
382
/* HPD disables all the table attributes except NSTable. */
383
break;
384
}
385
--
123
--
386
2.20.1
124
2.25.1
387
388
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
In exynos4210_init_board_irqs(), the loop that handles IRQ lines that
2
are in a range that applies to the internal combiner only creates a
3
splitter for those interrupts which go to both the internal combiner
4
and to the external GIC, but it does nothing at all for the
5
interrupts which don't go to the external GIC, leaving the
6
irq_table[] array element empty for those. (This will result in
7
those interrupts simply being lost, not in a QEMU crash.)
2
8
3
This is immediately necessary for the PMUv3 implementation to check
9
I don't have a reliable datasheet for this SoC, but since we do wire
4
ID_DFR0.PerfMon to enable/disable specific features, but defines the
10
up one interrupt line in this category (the HDMI I2C device on
5
full complement of fields for possible future use elsewhere.
11
interrupt 16,1), this seems like it must be a bug in the existing
12
QEMU code. Fill in the irq_table[] entries where we're not splitting
13
the IRQ to both the internal combiner and the external GIC with the
14
IRQ line of the internal combiner. (That is, these IRQ lines go to
15
just one device, not multiple.)
6
16
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
17
This bug didn't have any visible guest effects because the only
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
implemented device that was affected was the HDMI I2C controller,
9
Message-id: 20181211151945.29137-8-aaron@os.amperecomputing.com
19
and we never connect any I2C devices to that bus.
20
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20220404154658.565020-14-peter.maydell@linaro.org
11
---
24
---
12
target/arm/cpu.h | 9 +++++++++
25
hw/arm/exynos4210.c | 2 ++
13
1 file changed, 9 insertions(+)
26
1 file changed, 2 insertions(+)
14
27
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
16
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
30
--- a/hw/arm/exynos4210.c
18
+++ b/target/arm/cpu.h
31
+++ b/hw/arm/exynos4210.c
19
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
32
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
20
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
21
FIELD(ID_AA64MMFR1, XNX, 28, 4)
34
qdev_connect_gpio_out(splitter, 1,
22
35
qdev_get_gpio_in(extgicdev, irq_id - 32));
23
+FIELD(ID_DFR0, COPDBG, 0, 4)
36
+ } else {
24
+FIELD(ID_DFR0, COPSDBG, 4, 4)
37
+ s->irq_table[n] = is->int_combiner_irq[n];
25
+FIELD(ID_DFR0, MMAPDBG, 8, 4)
38
}
26
+FIELD(ID_DFR0, COPTRC, 12, 4)
39
}
27
+FIELD(ID_DFR0, MMAPTRC, 16, 4)
40
/*
28
+FIELD(ID_DFR0, MPROFDBG, 20, 4)
29
+FIELD(ID_DFR0, PERFMON, 24, 4)
30
+FIELD(ID_DFR0, TRACEFILT, 28, 4)
31
+
32
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
33
34
/* If adding a feature bit which corresponds to a Linux ELF
35
--
41
--
36
2.20.1
42
2.25.1
37
38
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Currently for the interrupts MCT_G0 and MCT_G1 which are
2
the only ones in the input range of the external combiner
3
and which are also wired to the external GIC, we connect
4
them only to the internal combiner and the external GIC.
5
This seems likely to be a bug, as all other interrupts
6
which are in the input range of both combiners are
7
connected to both combiners. (The fact that the code in
8
exynos4210_combiner_get_gpioin() is also trying to wire
9
up these inputs on both combiners also suggests this.)
2
10
3
We can perform this with fewer operations.
11
Wire these interrupts up to both combiners, like the rest.
4
12
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-32-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-15-peter.maydell@linaro.org
9
---
16
---
10
target/arm/translate-a64.c | 62 +++++++++++++-------------------------
17
hw/arm/exynos4210.c | 7 +++----
11
1 file changed, 21 insertions(+), 41 deletions(-)
18
1 file changed, 3 insertions(+), 4 deletions(-)
12
19
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
22
--- a/hw/arm/exynos4210.c
16
+++ b/target/arm/translate-a64.c
23
+++ b/hw/arm/exynos4210.c
17
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
24
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
18
/* Load the PC from a generic TCG variable.
25
19
*
26
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
20
* If address tagging is enabled via the TCR TBI bits, then loading
27
splitter = DEVICE(&s->splitter[splitcount]);
21
- * an address into the PC will clear out any tag in the it:
28
- qdev_prop_set_uint16(splitter, "num-lines", 2);
22
+ * an address into the PC will clear out any tag in it:
29
+ qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
23
* + for EL2 and EL3 there is only one TBI bit, and if it is set
30
qdev_realize(splitter, NULL, &error_abort);
24
* then the address is zero-extended, clearing bits [63:56]
31
splitcount++;
25
* + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
32
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
26
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
33
qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
27
int tbi = s->tbii;
34
+ qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
28
35
if (irq_id) {
29
if (s->current_el <= 1) {
36
- qdev_connect_gpio_out(splitter, 1,
30
- /* Test if NEITHER or BOTH TBI values are set. If so, no need to
37
+ qdev_connect_gpio_out(splitter, 2,
31
- * examine bit 55 of address, can just generate code.
38
qdev_get_gpio_in(extgicdev, irq_id - 32));
32
- * If mixed, then test via generated code
33
- */
34
- if (tbi == 3) {
35
- TCGv_i64 tmp_reg = tcg_temp_new_i64();
36
- /* Both bits set, sign extension from bit 55 into [63:56] will
37
- * cover both cases
38
- */
39
- tcg_gen_shli_i64(tmp_reg, src, 8);
40
- tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
41
- tcg_temp_free_i64(tmp_reg);
42
- } else if (tbi == 0) {
43
- /* Neither bit set, just load it as-is */
44
- tcg_gen_mov_i64(cpu_pc, src);
45
- } else {
39
- } else {
46
- TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
40
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
47
- TCGv_i64 tcg_bit55 = tcg_temp_new_i64();
48
- TCGv_i64 tcg_zero = tcg_const_i64(0);
49
+ if (tbi != 0) {
50
+ /* Sign-extend from bit 55. */
51
+ tcg_gen_sextract_i64(cpu_pc, src, 0, 56);
52
53
- tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
54
+ if (tbi != 3) {
55
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
56
57
- if (tbi == 1) {
58
- /* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
59
- tcg_gen_andi_i64(tcg_tmpval, src,
60
- 0x00FFFFFFFFFFFFFFull);
61
- tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
62
- tcg_tmpval, src);
63
- } else {
64
- /* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
65
- tcg_gen_ori_i64(tcg_tmpval, src,
66
- 0xFF00000000000000ull);
67
- tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
68
- tcg_tmpval, src);
69
+ /*
70
+ * The two TBI bits differ.
71
+ * If tbi0, then !tbi1: only use the extension if positive.
72
+ * if !tbi0, then tbi1: only use the extension if negative.
73
+ */
74
+ tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
75
+ cpu_pc, cpu_pc, tcg_zero, cpu_pc, src);
76
+ tcg_temp_free_i64(tcg_zero);
77
}
78
- tcg_temp_free_i64(tcg_zero);
79
- tcg_temp_free_i64(tcg_bit55);
80
- tcg_temp_free_i64(tcg_tmpval);
81
+ return;
82
}
83
- } else { /* EL > 1 */
84
+ } else {
85
if (tbi != 0) {
86
/* Force tag byte to all zero */
87
- tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
88
- } else {
89
- /* Load unmodified address */
90
- tcg_gen_mov_i64(cpu_pc, src);
91
+ tcg_gen_extract_i64(cpu_pc, src, 0, 56);
92
+ return;
93
}
41
}
94
}
42
}
95
+
43
for (; n < EXYNOS4210_MAX_INT_COMBINER_IN_IRQ; n++) {
96
+ /* Load unmodified address */
97
+ tcg_gen_mov_i64(cpu_pc, src);
98
}
99
100
typedef struct DisasCompare64 {
101
--
44
--
102
2.20.1
45
2.25.1
103
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The combiner_grp_to_gic_id[] array includes the EXT_GIC_ID_MCT_G0
2
and EXT_GIC_ID_MCT_G1 multiple times. This means that we will
3
connect multiple IRQs up to the same external GIC input, which
4
is not permitted. We do the same thing in the code in
5
exynos4210_init_board_irqs() because the conditionals selecting
6
an irq_id in the first loop match multiple interrupt IDs.
2
7
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Overall we do this for interrupt IDs
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
(1, 4), (12, 4), (35, 4), (51, 4), (53, 4) for EXT_GIC_ID_MCT_G0
5
Message-id: 20190108223129.5570-14-richard.henderson@linaro.org
10
and
11
(1, 5), (12, 5), (35, 5), (51, 5), (53, 5) for EXT_GIC_ID_MCT_G1
12
13
These correspond to the cases for the multi-core timer that we are
14
wiring up to multiple inputs on the combiner in
15
exynos4210_combiner_get_gpioin(). That code already deals with all
16
these interrupt IDs being the same input source, so we don't need to
17
connect the external GIC interrupt for any of them except the first
18
(1, 4) and (1, 5). Remove the array entries and conditionals which
19
were incorrectly causing us to wire up extra lines.
20
21
This bug didn't cause any visible effects, because we only connect
22
up a device to the "primary" ID values (1, 4) and (1, 5), so the
23
extra lines would never be set to a level.
24
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
27
Message-id: 20220404154658.565020-16-peter.maydell@linaro.org
7
---
28
---
8
target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++-
29
include/hw/arm/exynos4210.h | 2 +-
9
1 file changed, 81 insertions(+), 1 deletion(-)
30
hw/arm/exynos4210.c | 12 +++++-------
31
2 files changed, 6 insertions(+), 8 deletions(-)
10
32
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
33
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
35
--- a/include/hw/arm/exynos4210.h
14
+++ b/target/arm/translate-a64.c
36
+++ b/include/hw/arm/exynos4210.h
15
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
37
@@ -XXX,XX +XXX,XX @@
16
{
38
* one for every non-zero entry in combiner_grp_to_gic_id[].
17
unsigned int opc, op2, op3, rn, op4;
39
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
18
TCGv_i64 dst;
40
*/
19
+ TCGv_i64 modifier;
41
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 60)
20
42
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
21
opc = extract32(insn, 21, 4);
43
22
op2 = extract32(insn, 16, 5);
44
typedef struct Exynos4210Irq {
23
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
45
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
24
case 2: /* RET */
46
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
25
switch (op3) {
47
index XXXXXXX..XXXXXXX 100644
26
case 0:
48
--- a/hw/arm/exynos4210.c
27
+ /* BR, BLR, RET */
49
+++ b/hw/arm/exynos4210.c
28
if (op4 != 0) {
50
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
29
goto do_unallocated;
51
/* int combiner group 34 */
30
}
52
{ EXT_GIC_ID_ONENAND_AUDI, EXT_GIC_ID_NFC },
31
dst = cpu_reg(s, rn);
53
/* int combiner group 35 */
32
break;
54
- { 0, 0, 0, EXT_GIC_ID_MCT_L1, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
33
55
+ { 0, 0, 0, EXT_GIC_ID_MCT_L1 },
34
+ case 2:
56
/* int combiner group 36 */
35
+ case 3:
57
{ EXT_GIC_ID_MIXER },
36
+ if (!dc_isar_feature(aa64_pauth, s)) {
58
/* int combiner group 37 */
37
+ goto do_unallocated;
59
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
38
+ }
60
/* groups 38-50 */
39
+ if (opc == 2) {
61
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { },
40
+ /* RETAA, RETAB */
62
/* int combiner group 51 */
41
+ if (rn != 0x1f || op4 != 0x1f) {
63
- { EXT_GIC_ID_MCT_L0, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
42
+ goto do_unallocated;
64
+ { EXT_GIC_ID_MCT_L0 },
43
+ }
65
/* group 52 */
44
+ rn = 30;
66
{ },
45
+ modifier = cpu_X[31];
67
/* int combiner group 53 */
46
+ } else {
68
- { EXT_GIC_ID_WDT, 0, 0, 0, EXT_GIC_ID_MCT_G0, EXT_GIC_ID_MCT_G1 },
47
+ /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
69
+ { EXT_GIC_ID_WDT },
48
+ if (op4 != 0x1f) {
70
/* groups 54-63 */
49
+ goto do_unallocated;
71
{ }, { }, { }, { }, { }, { }, { }, { }, { }, { }
50
+ }
72
};
51
+ modifier = new_tmp_a64_zero(s);
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
52
+ }
74
53
+ if (s->pauth_active) {
75
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
54
+ dst = new_tmp_a64(s);
76
irq_id = 0;
55
+ if (op3 == 2) {
77
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4) ||
56
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
78
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4)) {
57
+ } else {
79
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 4)) {
58
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
80
/* MCT_G0 is passed to External GIC */
59
+ }
81
irq_id = EXT_GIC_ID_MCT_G0;
60
+ } else {
61
+ dst = cpu_reg(s, rn);
62
+ }
63
+ break;
64
+
65
default:
66
goto do_unallocated;
67
}
82
}
68
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
83
- if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5) ||
69
}
84
- n == EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 5)) {
70
break;
85
+ if (n == EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 5)) {
71
86
/* MCT_G1 is passed to External and GIC */
72
+ case 8: /* BRAA */
87
irq_id = EXT_GIC_ID_MCT_G1;
73
+ case 9: /* BLRAA */
74
+ if (!dc_isar_feature(aa64_pauth, s)) {
75
+ goto do_unallocated;
76
+ }
77
+ if (op3 != 2 || op3 != 3) {
78
+ goto do_unallocated;
79
+ }
80
+ if (s->pauth_active) {
81
+ dst = new_tmp_a64(s);
82
+ modifier = cpu_reg_sp(s, op4);
83
+ if (op3 == 2) {
84
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
85
+ } else {
86
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
87
+ }
88
+ } else {
89
+ dst = cpu_reg(s, rn);
90
+ }
91
+ gen_a64_set_pc(s, dst);
92
+ /* BLRAA also needs to load return address */
93
+ if (opc == 9) {
94
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
95
+ }
96
+ break;
97
+
98
case 4: /* ERET */
99
if (s->current_el == 0) {
100
goto do_unallocated;
101
}
102
switch (op3) {
103
- case 0:
104
+ case 0: /* ERET */
105
if (op4 != 0) {
106
goto do_unallocated;
107
}
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
109
offsetof(CPUARMState, elr_el[s->current_el]));
110
break;
111
112
+ case 2: /* ERETAA */
113
+ case 3: /* ERETAB */
114
+ if (!dc_isar_feature(aa64_pauth, s)) {
115
+ goto do_unallocated;
116
+ }
117
+ if (rn != 0x1f || op4 != 0x1f) {
118
+ goto do_unallocated;
119
+ }
120
+ dst = tcg_temp_new_i64();
121
+ tcg_gen_ld_i64(dst, cpu_env,
122
+ offsetof(CPUARMState, elr_el[s->current_el]));
123
+ if (s->pauth_active) {
124
+ modifier = cpu_X[31];
125
+ if (op3 == 2) {
126
+ gen_helper_autia(dst, cpu_env, dst, modifier);
127
+ } else {
128
+ gen_helper_autib(dst, cpu_env, dst, modifier);
129
+ }
130
+ }
131
+ break;
132
+
133
default:
134
goto do_unallocated;
135
}
88
}
136
--
89
--
137
2.20.1
90
2.25.1
138
139
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
At this point, the function exynos4210_init_board_irqs() splits input
2
2
IRQ lines to connect them to the input combiner, output combiner and
3
The PHY behind the MAC of an Aspeed SoC can be controlled using two
3
external GIC. The function exynos4210_combiner_get_gpioin() splits
4
different MDC/MDIO interfaces. The same registers PHYCR (MAC60) and
4
some of the combiner input lines further to connect them to multiple
5
PHYDATA (MAC64) are involved but they have a different layout.
5
different inputs on the combiner.
6
6
7
BIT31 of the Feature Register (MAC40) controls which MDC/MDIO
7
Because (unlike qemu_irq_split()) the TYPE_SPLIT_IRQ device has a
8
interface is active.
8
configurable number of outputs, we can do all this in one place, by
9
9
making exynos4210_init_board_irqs() add extra outputs to the splitter
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
device when it must be connected to more than one input on each
11
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
11
combiner.
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
12
13
Message-id: 20190111125759.31577-1-clg@kaod.org
13
We do this with a new data structure, the combinermap, which is an
14
array each of whose elements is a list of the interrupt IDs on the
15
combiner which must be tied together. As we loop through each
16
interrupt ID, if we find that it is the first one in one of these
17
lists, we configure the splitter device with eonugh extra outputs and
18
wire them up to the other interrupt IDs in the list.
19
20
Conveniently, for all the cases where this is necessary, the
21
lowest-numbered interrupt ID in each group is in the range of the
22
external combiner, so we only need to code for this in the first of
23
the two loops in exynos4210_init_board_irqs().
24
25
The old code in exynos4210_combiner_get_gpioin() which is being
26
deleted here had several problems which don't exist in the new code
27
in its handling of the multi-core timer interrupts:
28
(1) the case labels specified bits 4 ... 8, but bit '8' doesn't
29
exist; these should have been 4 ... 7
30
(2) it used the input irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]
31
multiple times as the input of several different splitters,
32
which isn't allowed
33
(3) in an apparent cut-and-paste error, the cases for all the
34
multi-core timer inputs used "bit + 4" even though the
35
bit range for the case was (intended to be) 4 ... 7, which
36
meant it was looking at non-existent bits 8 ... 11.
37
None of these exist in the new code.
38
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
39
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
40
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
41
Message-id: 20220404154658.565020-17-peter.maydell@linaro.org
15
---
42
---
16
hw/net/ftgmac100.c | 80 +++++++++++++++++++++++++++++++++++++++-------
43
include/hw/arm/exynos4210.h | 6 +-
17
1 file changed, 68 insertions(+), 12 deletions(-)
44
hw/arm/exynos4210.c | 178 +++++++++++++++++++++++-------------
18
45
2 files changed, 119 insertions(+), 65 deletions(-)
19
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
46
47
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
20
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/ftgmac100.c
49
--- a/include/hw/arm/exynos4210.h
22
+++ b/hw/net/ftgmac100.c
50
+++ b/include/hw/arm/exynos4210.h
23
@@ -XXX,XX +XXX,XX @@
51
@@ -XXX,XX +XXX,XX @@
24
#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff)
52
25
#define FTGMAC100_PHYDATA_MIIRDATA(x) (((x) >> 16) & 0xffff)
53
/*
54
* We need one splitter for every external combiner input, plus
55
- * one for every non-zero entry in combiner_grp_to_gic_id[].
56
+ * one for every non-zero entry in combiner_grp_to_gic_id[],
57
+ * minus one for every external combiner ID in second or later
58
+ * places in a combinermap[] line.
59
* We'll assert in exynos4210_init_board_irqs() if this is wrong.
60
*/
61
-#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 54)
62
+#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
63
64
typedef struct Exynos4210Irq {
65
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
66
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/exynos4210.c
69
+++ b/hw/arm/exynos4210.c
70
@@ -XXX,XX +XXX,XX @@ combiner_grp_to_gic_id[64 - EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
71
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
72
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
26
73
27
+/*
74
+/*
28
+ * PHY control register - New MDC/MDIO interface
75
+ * Some interrupt lines go to multiple combiner inputs.
76
+ * This data structure defines those: each array element is
77
+ * a list of combiner inputs which are connected together;
78
+ * the one with the smallest interrupt ID value must be first.
79
+ * As with combiner_grp_to_gic_id[], we rely on (0, 0) not being
80
+ * wired to anything so we can use 0 as a terminator.
29
+ */
81
+ */
30
+#define FTGMAC100_PHYCR_NEW_DATA(x) (((x) >> 16) & 0xffff)
82
+#define IRQNO(G, B) EXYNOS4210_COMBINER_GET_IRQ_NUM(G, B)
31
+#define FTGMAC100_PHYCR_NEW_FIRE (1 << 15)
83
+#define IRQNONE 0
32
+#define FTGMAC100_PHYCR_NEW_ST_22 (1 << 12)
84
+
33
+#define FTGMAC100_PHYCR_NEW_OP(x) (((x) >> 10) & 3)
85
+#define COMBINERMAP_SIZE 16
34
+#define FTGMAC100_PHYCR_NEW_OP_WRITE 0x1
86
+
35
+#define FTGMAC100_PHYCR_NEW_OP_READ 0x2
87
+static const int combinermap[COMBINERMAP_SIZE][6] = {
36
+#define FTGMAC100_PHYCR_NEW_DEV(x) (((x) >> 5) & 0x1f)
88
+ /* MDNIE_LCD1 */
37
+#define FTGMAC100_PHYCR_NEW_REG(x) ((x) & 0x1f)
89
+ { IRQNO(0, 4), IRQNO(1, 0), IRQNONE },
90
+ { IRQNO(0, 5), IRQNO(1, 1), IRQNONE },
91
+ { IRQNO(0, 6), IRQNO(1, 2), IRQNONE },
92
+ { IRQNO(0, 7), IRQNO(1, 3), IRQNONE },
93
+ /* TMU */
94
+ { IRQNO(2, 4), IRQNO(3, 4), IRQNONE },
95
+ { IRQNO(2, 5), IRQNO(3, 5), IRQNONE },
96
+ { IRQNO(2, 6), IRQNO(3, 6), IRQNONE },
97
+ { IRQNO(2, 7), IRQNO(3, 7), IRQNONE },
98
+ /* LCD1 */
99
+ { IRQNO(11, 4), IRQNO(12, 0), IRQNONE },
100
+ { IRQNO(11, 5), IRQNO(12, 1), IRQNONE },
101
+ { IRQNO(11, 6), IRQNO(12, 2), IRQNONE },
102
+ { IRQNO(11, 7), IRQNO(12, 3), IRQNONE },
103
+ /* Multi-core timer */
104
+ { IRQNO(1, 4), IRQNO(12, 4), IRQNO(35, 4), IRQNO(51, 4), IRQNO(53, 4), IRQNONE },
105
+ { IRQNO(1, 5), IRQNO(12, 5), IRQNO(35, 5), IRQNO(51, 5), IRQNO(53, 5), IRQNONE },
106
+ { IRQNO(1, 6), IRQNO(12, 6), IRQNO(35, 6), IRQNO(51, 6), IRQNO(53, 6), IRQNONE },
107
+ { IRQNO(1, 7), IRQNO(12, 7), IRQNO(35, 7), IRQNO(51, 7), IRQNO(53, 7), IRQNONE },
108
+};
109
+
110
+#undef IRQNO
111
+
112
+static const int *combinermap_entry(int irq)
113
+{
114
+ /*
115
+ * If the interrupt number passed in is the first entry in some
116
+ * line of the combinermap, return a pointer to that line;
117
+ * otherwise return NULL.
118
+ */
119
+ int i;
120
+ for (i = 0; i < COMBINERMAP_SIZE; i++) {
121
+ if (combinermap[i][0] == irq) {
122
+ return combinermap[i];
123
+ }
124
+ }
125
+ return NULL;
126
+}
127
+
128
+static int mapline_size(const int *mapline)
129
+{
130
+ /* Return number of entries in this mapline in total */
131
+ int i = 0;
132
+
133
+ if (!mapline) {
134
+ /* Not in the map? IRQ goes to exactly one combiner input */
135
+ return 1;
136
+ }
137
+ while (*mapline != IRQNONE) {
138
+ mapline++;
139
+ i++;
140
+ }
141
+ return i;
142
+}
38
+
143
+
39
/*
144
/*
40
* Feature Register
145
* Initialize board IRQs.
41
*/
146
* These IRQs contain splitted Int/External Combiner and External Gic IRQs.
42
@@ -XXX,XX +XXX,XX @@ static void phy_reset(FTGMAC100State *s)
147
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
43
s->phy_int = 0;
148
DeviceState *extgicdev = DEVICE(&s->ext_gic);
44
}
149
int splitcount = 0;
45
150
DeviceState *splitter;
46
-static uint32_t do_phy_read(FTGMAC100State *s, int reg)
151
+ const int *mapline;
47
+static uint16_t do_phy_read(FTGMAC100State *s, uint8_t reg)
152
+ int numlines, splitin, in;
153
154
for (n = 0; n < EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ; n++) {
155
irq_id = 0;
156
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
157
irq_id = EXT_GIC_ID_MCT_G1;
158
}
159
160
+ if (s->irq_table[n]) {
161
+ /*
162
+ * This must be some non-first entry in a combinermap line,
163
+ * and we've already filled it in.
164
+ */
165
+ continue;
166
+ }
167
+ mapline = combinermap_entry(n);
168
+ /*
169
+ * We need to connect the IRQ to multiple inputs on both combiners
170
+ * and possibly also to the external GIC.
171
+ */
172
+ numlines = 2 * mapline_size(mapline);
173
+ if (irq_id) {
174
+ numlines++;
175
+ }
176
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
177
splitter = DEVICE(&s->splitter[splitcount]);
178
- qdev_prop_set_uint16(splitter, "num-lines", irq_id ? 3 : 2);
179
+ qdev_prop_set_uint16(splitter, "num-lines", numlines);
180
qdev_realize(splitter, NULL, &error_abort);
181
splitcount++;
182
- s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
183
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
184
- qdev_connect_gpio_out(splitter, 1, is->ext_combiner_irq[n]);
185
+
186
+ in = n;
187
+ splitin = 0;
188
+ for (;;) {
189
+ s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
190
+ qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
191
+ qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
192
+ splitin += 2;
193
+ if (!mapline) {
194
+ break;
195
+ }
196
+ mapline++;
197
+ in = *mapline;
198
+ if (in == IRQNONE) {
199
+ break;
200
+ }
201
+ }
202
if (irq_id) {
203
- qdev_connect_gpio_out(splitter, 2,
204
+ qdev_connect_gpio_out(splitter, splitin,
205
qdev_get_gpio_in(extgicdev, irq_id - 32));
206
}
207
}
208
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
209
irq_id = combiner_grp_to_gic_id[grp -
210
EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][bit];
211
212
+ if (s->irq_table[n]) {
213
+ /*
214
+ * This must be some non-first entry in a combinermap line,
215
+ * and we've already filled it in.
216
+ */
217
+ continue;
218
+ }
219
+
220
if (irq_id) {
221
assert(splitcount < EXYNOS4210_NUM_SPLITTERS);
222
splitter = DEVICE(&s->splitter[splitcount]);
223
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
224
DeviceState *dev, int ext)
48
{
225
{
49
- uint32_t val;
226
int n;
50
+ uint16_t val;
227
- int bit;
51
228
int max;
52
switch (reg) {
229
qemu_irq *irq;
53
case MII_BMCR: /* Basic Control */
230
54
@@ -XXX,XX +XXX,XX @@ static uint32_t do_phy_read(FTGMAC100State *s, int reg)
231
@@ -XXX,XX +XXX,XX @@ static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
55
MII_BMCR_FD | MII_BMCR_CTST)
232
EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
56
#define MII_ANAR_MASK 0x2d7f
233
irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
57
234
58
-static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
235
- /*
59
+static void do_phy_write(FTGMAC100State *s, uint8_t reg, uint16_t val)
236
- * Some IRQs of Int/External Combiner are going to two Combiners groups,
60
{
237
- * so let split them.
61
switch (reg) {
238
- */
62
case MII_BMCR: /* Basic Control */
239
for (n = 0; n < max; n++) {
63
@@ -XXX,XX +XXX,XX @@ static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
240
-
241
- bit = EXYNOS4210_COMBINER_GET_BIT_NUM(n);
242
-
243
- switch (n) {
244
- /* MDNIE_LCD1 INTG1 */
245
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 0) ...
246
- EXYNOS4210_COMBINER_GET_IRQ_NUM(1, 3):
247
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
248
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(0, bit + 4)]);
249
- continue;
250
-
251
- /* TMU INTG3 */
252
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(3, 4):
253
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
254
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(2, bit)]);
255
- continue;
256
-
257
- /* LCD1 INTG12 */
258
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 0) ...
259
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 3):
260
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
261
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(11, bit + 4)]);
262
- continue;
263
-
264
- /* Multi-Core Timer INTG12 */
265
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 4) ...
266
- EXYNOS4210_COMBINER_GET_IRQ_NUM(12, 8):
267
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
268
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
269
- continue;
270
-
271
- /* Multi-Core Timer INTG35 */
272
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 4) ...
273
- EXYNOS4210_COMBINER_GET_IRQ_NUM(35, 8):
274
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
275
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
276
- continue;
277
-
278
- /* Multi-Core Timer INTG51 */
279
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 4) ...
280
- EXYNOS4210_COMBINER_GET_IRQ_NUM(51, 8):
281
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
282
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
283
- continue;
284
-
285
- /* Multi-Core Timer INTG53 */
286
- case EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 4) ...
287
- EXYNOS4210_COMBINER_GET_IRQ_NUM(53, 8):
288
- irq[n] = qemu_irq_split(qdev_get_gpio_in(dev, n),
289
- irq[EXYNOS4210_COMBINER_GET_IRQ_NUM(1, bit + 4)]);
290
- continue;
291
- }
292
-
293
irq[n] = qdev_get_gpio_in(dev, n);
64
}
294
}
65
}
295
}
66
67
+static void do_phy_new_ctl(FTGMAC100State *s)
68
+{
69
+ uint8_t reg;
70
+ uint16_t data;
71
+
72
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_ST_22)) {
73
+ qemu_log_mask(LOG_UNIMP, "%s: unsupported ST code\n", __func__);
74
+ return;
75
+ }
76
+
77
+ /* Nothing to do */
78
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_FIRE)) {
79
+ return;
80
+ }
81
+
82
+ reg = FTGMAC100_PHYCR_NEW_REG(s->phycr);
83
+ data = FTGMAC100_PHYCR_NEW_DATA(s->phycr);
84
+
85
+ switch (FTGMAC100_PHYCR_NEW_OP(s->phycr)) {
86
+ case FTGMAC100_PHYCR_NEW_OP_WRITE:
87
+ do_phy_write(s, reg, data);
88
+ break;
89
+ case FTGMAC100_PHYCR_NEW_OP_READ:
90
+ s->phydata = do_phy_read(s, reg) & 0xffff;
91
+ break;
92
+ default:
93
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid OP code %08x\n",
94
+ __func__, s->phycr);
95
+ }
96
+
97
+ s->phycr &= ~FTGMAC100_PHYCR_NEW_FIRE;
98
+}
99
+
100
+static void do_phy_ctl(FTGMAC100State *s)
101
+{
102
+ uint8_t reg = FTGMAC100_PHYCR_REG(s->phycr);
103
+
104
+ if (s->phycr & FTGMAC100_PHYCR_MIIWR) {
105
+ do_phy_write(s, reg, s->phydata & 0xffff);
106
+ s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
107
+ } else if (s->phycr & FTGMAC100_PHYCR_MIIRD) {
108
+ s->phydata = do_phy_read(s, reg) << 16;
109
+ s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
110
+ } else {
111
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no OP code %08x\n",
112
+ __func__, s->phycr);
113
+ }
114
+}
115
+
116
static int ftgmac100_read_bd(FTGMAC100Desc *bd, dma_addr_t addr)
117
{
118
if (dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd))) {
119
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
120
uint64_t value, unsigned size)
121
{
122
FTGMAC100State *s = FTGMAC100(opaque);
123
- int reg;
124
125
switch (addr & 0xff) {
126
case FTGMAC100_ISR: /* Interrupt status */
127
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
128
break;
129
130
case FTGMAC100_PHYCR: /* PHY Device control */
131
- reg = FTGMAC100_PHYCR_REG(value);
132
s->phycr = value;
133
- if (value & FTGMAC100_PHYCR_MIIWR) {
134
- do_phy_write(s, reg, s->phydata & 0xffff);
135
- s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
136
+ if (s->revr & FTGMAC100_REVR_NEW_MDIO_INTERFACE) {
137
+ do_phy_new_ctl(s);
138
} else {
139
- s->phydata = do_phy_read(s, reg) << 16;
140
- s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
141
+ do_phy_ctl(s);
142
}
143
break;
144
case FTGMAC100_PHYDATA:
145
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
146
s->dblac = value;
147
break;
148
case FTGMAC100_REVR: /* Feature Register */
149
- /* TODO: Only Old MDIO interface is supported */
150
- s->revr = value & ~FTGMAC100_REVR_NEW_MDIO_INTERFACE;
151
+ s->revr = value;
152
break;
153
case FTGMAC100_FEAR1: /* Feature Register 1 */
154
s->fear1 = value;
155
--
296
--
156
2.20.1
297
2.25.1
157
158
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Add storage space for the 5 encryption keys.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 30 +++++++++++++++++++++++++++++-
11
1 file changed, 29 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
18
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
19
} ARMVectorReg;
20
21
-/* In AArch32 mode, predicate registers do not exist at all. */
22
#ifdef TARGET_AARCH64
23
+/* In AArch32 mode, predicate registers do not exist at all. */
24
typedef struct ARMPredicateReg {
25
uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
26
} ARMPredicateReg;
27
+
28
+/* In AArch32 mode, PAC keys do not exist at all. */
29
+typedef struct ARMPACKey {
30
+ uint64_t lo, hi;
31
+} ARMPACKey;
32
#endif
33
34
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
36
uint32_t cregs[16];
37
} iwmmxt;
38
39
+#ifdef TARGET_AARCH64
40
+ ARMPACKey apia_key;
41
+ ARMPACKey apib_key;
42
+ ARMPACKey apda_key;
43
+ ARMPACKey apdb_key;
44
+ ARMPACKey apga_key;
45
+#endif
46
+
47
#if defined(CONFIG_USER_ONLY)
48
/* For usermode syscall translation. */
49
int eabi;
50
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
51
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
52
}
53
54
+static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
55
+{
56
+ /*
57
+ * Note that while QEMU will only implement the architected algorithm
58
+ * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
59
+ * defined algorithms, and thus API+GPI, and this predicate controls
60
+ * migration of the 128-bit keys.
61
+ */
62
+ return (id->id_aa64isar1 &
63
+ (FIELD_DP64(0, ID_AA64ISAR1, APA, -1) |
64
+ FIELD_DP64(0, ID_AA64ISAR1, API, -1) |
65
+ FIELD_DP64(0, ID_AA64ISAR1, GPA, -1) |
66
+ FIELD_DP64(0, ID_AA64ISAR1, GPI, -1))) != 0;
67
+}
68
+
69
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
70
{
71
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Post v8.4 bits taken from SysReg_v85_xml-00bet8.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 45 +++++++++++++++++++++++++++++++++------------
11
1 file changed, 33 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
18
#define SCTLR_A (1U << 1)
19
#define SCTLR_C (1U << 2)
20
#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */
21
-#define SCTLR_SA (1U << 3)
22
+#define SCTLR_nTLSMD_32 (1U << 3) /* v8.2-LSMAOC, AArch32 only */
23
+#define SCTLR_SA (1U << 3) /* AArch64 only */
24
#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */
25
+#define SCTLR_LSMAOE_32 (1U << 4) /* v8.2-LSMAOC, AArch32 only */
26
#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */
27
#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */
28
#define SCTLR_CP15BEN (1U << 5) /* v7 onward */
29
#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
30
+#define SCTLR_nAA (1U << 6) /* when v8.4-LSE is implemented */
31
#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */
32
#define SCTLR_ITD (1U << 7) /* v8 onward */
33
#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */
34
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
35
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
36
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
37
#define SCTLR_F (1U << 10) /* up to v6 */
38
-#define SCTLR_SW (1U << 10) /* v7 onward */
39
-#define SCTLR_Z (1U << 11)
40
+#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
41
+#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
42
+#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
43
#define SCTLR_I (1U << 12)
44
-#define SCTLR_V (1U << 13)
45
+#define SCTLR_V (1U << 13) /* AArch32 only */
46
+#define SCTLR_EnDB (1U << 13) /* v8.3, AArch64 only */
47
#define SCTLR_RR (1U << 14) /* up to v7 */
48
#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */
49
#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */
50
#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */
51
#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */
52
#define SCTLR_nTWI (1U << 16) /* v8 onward */
53
-#define SCTLR_HA (1U << 17)
54
+#define SCTLR_HA (1U << 17) /* up to v7, RES0 in v8 */
55
#define SCTLR_BR (1U << 17) /* PMSA only */
56
#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */
57
#define SCTLR_nTWE (1U << 18) /* v8 onward */
58
#define SCTLR_WXN (1U << 19)
59
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
60
-#define SCTLR_UWXN (1U << 20) /* v7 onward */
61
-#define SCTLR_FI (1U << 21)
62
-#define SCTLR_U (1U << 22)
63
+#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
64
+#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
65
+#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
66
+#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
67
+#define SCTLR_EIS (1U << 22) /* v8.5-ExS */
68
#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */
69
+#define SCTLR_SPAN (1U << 23) /* v8.1-PAN */
70
#define SCTLR_VE (1U << 24) /* up to v7 */
71
#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */
72
#define SCTLR_EE (1U << 25)
73
#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */
74
#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */
75
-#define SCTLR_NMFI (1U << 27)
76
-#define SCTLR_TRE (1U << 28)
77
-#define SCTLR_AFE (1U << 29)
78
-#define SCTLR_TE (1U << 30)
79
+#define SCTLR_NMFI (1U << 27) /* up to v7, RAZ in v7VE and v8 */
80
+#define SCTLR_EnDA (1U << 27) /* v8.3, AArch64 only */
81
+#define SCTLR_TRE (1U << 28) /* AArch32 only */
82
+#define SCTLR_nTLSMD_64 (1U << 28) /* v8.2-LSMAOC, AArch64 only */
83
+#define SCTLR_AFE (1U << 29) /* AArch32 only */
84
+#define SCTLR_LSMAOE_64 (1U << 29) /* v8.2-LSMAOC, AArch64 only */
85
+#define SCTLR_TE (1U << 30) /* AArch32 only */
86
+#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
87
+#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
88
+#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
89
+#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
90
+#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
91
+#define SCTLR_TCF0 (3ULL << 38) /* v8.5-MemTag */
92
+#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
93
+#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
94
+#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
95
+#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
96
97
#define CPTR_TCPAC (1U << 31)
98
#define CPTR_TTA (1U << 20)
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
There are 5 bits of state that could be added, but to save
4
space within tbflags, add only a single enable bit.
5
Helpers will determine the rest of the state at runtime.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/translate.h | 2 ++
14
target/arm/helper.c | 19 +++++++++++++++++++
15
target/arm/translate-a64.c | 1 +
16
4 files changed, 23 insertions(+)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TBI0, 0, 1)
23
FIELD(TBFLAG_A64, TBI1, 1, 1)
24
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
25
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
26
+FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
27
28
static inline bool bswap_code(bool sctlr_b)
29
{
30
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate.h
33
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
35
bool is_ldex;
36
/* True if a single-step exception will be taken to the current EL */
37
bool ss_same_el;
38
+ /* True if v8.3-PAuth is active. */
39
+ bool pauth_active;
40
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
41
int c15_cpar;
42
/* TCG op of the current insn_start. */
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
48
flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
49
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
50
}
51
+
52
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
53
+ /*
54
+ * In order to save space in flags, we record only whether
55
+ * pauth is "inactive", meaning all insns are implemented as
56
+ * a nop, or "active" when some action must be performed.
57
+ * The decision of which action to take is left to a helper.
58
+ */
59
+ uint64_t sctlr;
60
+ if (current_el == 0) {
61
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
62
+ sctlr = env->cp15.sctlr_el[1];
63
+ } else {
64
+ sctlr = env->cp15.sctlr_el[current_el];
65
+ }
66
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
67
+ flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
68
+ }
69
+ }
70
} else {
71
*pc = env->regs[15];
72
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
73
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate-a64.c
76
+++ b/target/arm/translate-a64.c
77
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
78
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
79
dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
80
dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
81
+ dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
82
dc->vec_len = 0;
83
dc->vec_stride = 0;
84
dc->cp_regs = arm_cpu->cp_regs;
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
Switch the creation of the combiner devices to the new-style
2
"embedded in state struct" approach, so we can easily refer
3
to the object elsewhere during realize.
2
4
3
pmccntr_read and pmccntr_write contained duplicate code that was already
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
being handled by pmccntr_sync. Consolidate the duplicated code into two
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to
7
Message-id: 20220404154658.565020-18-peter.maydell@linaro.org
6
c15_ccnt in CPUARMState so that we can simultaneously save both the
8
---
7
architectural register value and the last underlying cycle count - this
9
include/hw/arm/exynos4210.h | 3 ++
8
ensures time isn't lost and will also allow us to access the 'old'
10
include/hw/intc/exynos4210_combiner.h | 57 +++++++++++++++++++++++++++
9
architectural register value in order to detect overflows in later
11
hw/arm/exynos4210.c | 20 +++++-----
10
patches.
12
hw/intc/exynos4210_combiner.c | 31 +--------------
13
4 files changed, 72 insertions(+), 39 deletions(-)
14
create mode 100644 include/hw/intc/exynos4210_combiner.h
11
15
12
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
13
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Message-id: 20181211151945.29137-3-aaron@os.amperecomputing.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
target/arm/cpu.h | 37 +++++++++++---
19
target/arm/helper.c | 118 ++++++++++++++++++++++++++------------------
20
2 files changed, 100 insertions(+), 55 deletions(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
18
--- a/include/hw/arm/exynos4210.h
25
+++ b/target/arm/cpu.h
19
+++ b/include/hw/arm/exynos4210.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
20
@@ -XXX,XX +XXX,XX @@
27
uint64_t oslsr_el1; /* OS Lock Status */
21
#include "hw/sysbus.h"
28
uint64_t mdcr_el2;
22
#include "hw/cpu/a9mpcore.h"
29
uint64_t mdcr_el3;
23
#include "hw/intc/exynos4210_gic.h"
30
- /* If the counter is enabled, this stores the last time the counter
24
+#include "hw/intc/exynos4210_combiner.h"
31
- * was reset. Otherwise it stores the counter value
25
#include "hw/core/split-irq.h"
32
+ /* Stores the architectural value of the counter *the last time it was
26
#include "target/arm/cpu-qom.h"
33
+ * updated* by pmccntr_op_start. Accesses should always be surrounded
27
#include "qom/object.h"
34
+ * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest
28
@@ -XXX,XX +XXX,XX @@ struct Exynos4210State {
35
+ * architecturally-correct value is being read/set.
29
qemu_or_irq cpu_irq_orgate[EXYNOS4210_NCPUS];
36
*/
30
A9MPPrivState a9mpcore;
37
uint64_t c15_ccnt;
31
Exynos4210GicState ext_gic;
38
+ /* Stores the delta between the architectural value and the underlying
32
+ Exynos4210CombinerState int_combiner;
39
+ * cycle count during normal operation. It is used to update c15_ccnt
33
+ Exynos4210CombinerState ext_combiner;
40
+ * to be the correct architectural value before accesses. During
34
SplitIRQ splitter[EXYNOS4210_NUM_SPLITTERS];
41
+ * accesses, c15_ccnt_delta contains the underlying count being used
35
};
42
+ * for the access, after which it reverts to the delta value in
36
43
+ * pmccntr_op_finish.
37
diff --git a/include/hw/intc/exynos4210_combiner.h b/include/hw/intc/exynos4210_combiner.h
44
+ */
38
new file mode 100644
45
+ uint64_t c15_ccnt_delta;
39
index XXXXXXX..XXXXXXX
46
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
40
--- /dev/null
47
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
41
+++ b/include/hw/intc/exynos4210_combiner.h
48
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
42
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
43
+/*
50
void *puc);
44
+ * Samsung exynos4210 Interrupt Combiner
51
45
+ *
52
/**
46
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
53
- * pmccntr_sync
47
+ * All rights reserved.
54
+ * pmccntr_op_start/finish
48
+ *
55
* @env: CPUARMState
49
+ * Evgeny Voevodin <e.voevodin@samsung.com>
56
*
50
+ *
57
- * Synchronises the counter in the PMCCNTR. This must always be called twice,
51
+ * This program is free software; you can redistribute it and/or modify it
58
- * once before any action that might affect the timer and again afterwards.
52
+ * under the terms of the GNU General Public License as published by the
59
- * The function is used to swap the state of the register if required.
53
+ * Free Software Foundation; either version 2 of the License, or (at your
60
- * This only happens when not in user mode (!CONFIG_USER_ONLY)
54
+ * option) any later version.
61
+ * Convert the counter in the PMCCNTR between its delta form (the typical mode
55
+ *
62
+ * when it's enabled) and the guest-visible value. These two calls must always
56
+ * This program is distributed in the hope that it will be useful,
63
+ * surround any action which might affect the counter.
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
64
*/
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
65
-void pmccntr_sync(CPUARMState *env);
59
+ * See the GNU General Public License for more details.
66
+void pmccntr_op_start(CPUARMState *env);
60
+ *
67
+void pmccntr_op_finish(CPUARMState *env);
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
68
+
64
+
69
+/**
65
+#ifndef HW_INTC_EXYNOS4210_COMBINER
70
+ * pmu_op_start/finish
66
+#define HW_INTC_EXYNOS4210_COMBINER
71
+ * @env: CPUARMState
72
+ *
73
+ * Convert all PMU counters between their delta form (the typical mode when
74
+ * they are enabled) and the guest-visible values. These two calls must
75
+ * surround any action which might affect the counters.
76
+ */
77
+void pmu_op_start(CPUARMState *env);
78
+void pmu_op_finish(CPUARMState *env);
79
80
/* SCTLR bit meanings. Several bits have been reused in newer
81
* versions of the architecture; in that case we define constants
82
diff --git a/target/arm/helper.c b/target/arm/helper.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/helper.c
85
+++ b/target/arm/helper.c
86
@@ -XXX,XX +XXX,XX @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
87
88
return true;
89
}
90
-
91
-void pmccntr_sync(CPUARMState *env)
92
+/*
93
+ * Ensure c15_ccnt is the guest-visible count so that operations such as
94
+ * enabling/disabling the counter or filtering, modifying the count itself,
95
+ * etc. can be done logically. This is essentially a no-op if the counter is
96
+ * not enabled at the time of the call.
97
+ */
98
+void pmccntr_op_start(CPUARMState *env)
99
{
100
- uint64_t temp_ticks;
101
-
102
- temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
103
+ uint64_t cycles = 0;
104
+ cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
105
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
106
107
- if (env->cp15.c9_pmcr & PMCRD) {
108
- /* Increment once every 64 processor clock cycles */
109
- temp_ticks /= 64;
110
- }
111
-
112
if (arm_ccnt_enabled(env)) {
113
- env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
114
+ uint64_t eff_cycles = cycles;
115
+ if (env->cp15.c9_pmcr & PMCRD) {
116
+ /* Increment once every 64 processor clock cycles */
117
+ eff_cycles /= 64;
118
+ }
119
+
67
+
120
+ env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
68
+#include "hw/sysbus.h"
121
}
122
+ env->cp15.c15_ccnt_delta = cycles;
123
+}
124
+
69
+
125
+/*
70
+/*
126
+ * If PMCCNTR is enabled, recalculate the delta between the clock and the
71
+ * State for each output signal of internal combiner
127
+ * guest-visible count. A call to pmccntr_op_finish should follow every call to
128
+ * pmccntr_op_start.
129
+ */
72
+ */
130
+void pmccntr_op_finish(CPUARMState *env)
73
+typedef struct CombinerGroupState {
131
+{
74
+ uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
132
+ if (arm_ccnt_enabled(env)) {
75
+ uint8_t src_pending; /* Pending source interrupts before masking */
133
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
76
+} CombinerGroupState;
134
+
77
+
135
+ if (env->cp15.c9_pmcr & PMCRD) {
78
+#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
136
+ /* Increment once every 64 processor clock cycles */
79
+OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
137
+ prev_cycles /= 64;
138
+ }
139
+
80
+
140
+ env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
81
+/* Number of groups and total number of interrupts for the internal combiner */
141
+ }
82
+#define IIC_NGRP 64
142
+}
83
+#define IIC_NIRQ (IIC_NGRP * 8)
84
+#define IIC_REGSET_SIZE 0x41
143
+
85
+
144
+void pmu_op_start(CPUARMState *env)
86
+struct Exynos4210CombinerState {
145
+{
87
+ SysBusDevice parent_obj;
146
+ pmccntr_op_start(env);
147
+}
148
+
88
+
149
+void pmu_op_finish(CPUARMState *env)
89
+ MemoryRegion iomem;
150
+{
90
+
151
+ pmccntr_op_finish(env);
91
+ struct CombinerGroupState group[IIC_NGRP];
92
+ uint32_t reg_set[IIC_REGSET_SIZE];
93
+ uint32_t icipsr[2];
94
+ uint32_t external; /* 1 means that this combiner is external */
95
+
96
+ qemu_irq output_irq[IIC_NGRP];
97
+};
98
+
99
+#endif
100
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
101
index XXXXXXX..XXXXXXX 100644
102
--- a/hw/arm/exynos4210.c
103
+++ b/hw/arm/exynos4210.c
104
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
105
}
106
107
/* Internal Interrupt Combiner */
108
- dev = qdev_new("exynos4210.combiner");
109
- busdev = SYS_BUS_DEVICE(dev);
110
- sysbus_realize_and_unref(busdev, &error_fatal);
111
+ busdev = SYS_BUS_DEVICE(&s->int_combiner);
112
+ sysbus_realize(busdev, &error_fatal);
113
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
114
sysbus_connect_irq(busdev, n,
115
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
116
}
117
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
118
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
119
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
120
121
/* External Interrupt Combiner */
122
- dev = qdev_new("exynos4210.combiner");
123
- qdev_prop_set_uint32(dev, "external", 1);
124
- busdev = SYS_BUS_DEVICE(dev);
125
- sysbus_realize_and_unref(busdev, &error_fatal);
126
+ qdev_prop_set_uint32(DEVICE(&s->ext_combiner), "external", 1);
127
+ busdev = SYS_BUS_DEVICE(&s->ext_combiner);
128
+ sysbus_realize(busdev, &error_fatal);
129
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
130
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
131
}
132
- exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
133
+ exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
134
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
135
136
/* Initialize board IRQs. */
137
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init(Object *obj)
138
139
object_initialize_child(obj, "a9mpcore", &s->a9mpcore, TYPE_A9MPCORE_PRIV);
140
object_initialize_child(obj, "ext-gic", &s->ext_gic, TYPE_EXYNOS4210_GIC);
141
+ object_initialize_child(obj, "int-combiner", &s->int_combiner,
142
+ TYPE_EXYNOS4210_COMBINER);
143
+ object_initialize_child(obj, "ext-combiner", &s->ext_combiner,
144
+ TYPE_EXYNOS4210_COMBINER);
152
}
145
}
153
146
154
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
147
static void exynos4210_class_init(ObjectClass *klass, void *data)
155
uint64_t value)
148
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
156
{
149
index XXXXXXX..XXXXXXX 100644
157
- pmccntr_sync(env);
150
--- a/hw/intc/exynos4210_combiner.c
158
+ pmu_op_start(env);
151
+++ b/hw/intc/exynos4210_combiner.c
159
152
@@ -XXX,XX +XXX,XX @@
160
if (value & PMCRC) {
153
#include "hw/sysbus.h"
161
/* The counter has been reset */
154
#include "migration/vmstate.h"
162
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
155
#include "qemu/module.h"
163
env->cp15.c9_pmcr &= ~0x39;
164
env->cp15.c9_pmcr |= (value & 0x39);
165
166
- pmccntr_sync(env);
167
+ pmu_op_finish(env);
168
}
169
170
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
171
{
172
- uint64_t total_ticks;
173
-
156
-
174
- if (!arm_ccnt_enabled(env)) {
157
+#include "hw/intc/exynos4210_combiner.h"
175
- /* Counter is disabled, do not change value */
158
#include "hw/arm/exynos4210.h"
176
- return env->cp15.c15_ccnt;
159
#include "hw/hw.h"
177
- }
160
#include "hw/irq.h"
161
@@ -XXX,XX +XXX,XX @@
162
#define DPRINTF(fmt, ...) do {} while (0)
163
#endif
164
165
-#define IIC_NGRP 64 /* Internal Interrupt Combiner
166
- Groups number */
167
-#define IIC_NIRQ (IIC_NGRP * 8)/* Internal Interrupt Combiner
168
- Interrupts number */
169
#define IIC_REGION_SIZE 0x108 /* Size of memory mapped region */
170
-#define IIC_REGSET_SIZE 0x41
178
-
171
-
179
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
172
-/*
180
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
173
- * State for each output signal of internal combiner
174
- */
175
-typedef struct CombinerGroupState {
176
- uint8_t src_mask; /* 1 - source enabled, 0 - disabled */
177
- uint8_t src_pending; /* Pending source interrupts before masking */
178
-} CombinerGroupState;
181
-
179
-
182
- if (env->cp15.c9_pmcr & PMCRD) {
180
-#define TYPE_EXYNOS4210_COMBINER "exynos4210.combiner"
183
- /* Increment once every 64 processor clock cycles */
181
-OBJECT_DECLARE_SIMPLE_TYPE(Exynos4210CombinerState, EXYNOS4210_COMBINER)
184
- total_ticks /= 64;
185
- }
186
- return total_ticks - env->cp15.c15_ccnt;
187
+ uint64_t ret;
188
+ pmccntr_op_start(env);
189
+ ret = env->cp15.c15_ccnt;
190
+ pmccntr_op_finish(env);
191
+ return ret;
192
}
193
194
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
195
@@ -XXX,XX +XXX,XX @@ static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
197
uint64_t value)
198
{
199
- uint64_t total_ticks;
200
-
182
-
201
- if (!arm_ccnt_enabled(env)) {
183
-struct Exynos4210CombinerState {
202
- /* Counter is disabled, set the absolute value */
184
- SysBusDevice parent_obj;
203
- env->cp15.c15_ccnt = value;
204
- return;
205
- }
206
-
185
-
207
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
186
- MemoryRegion iomem;
208
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
209
-
187
-
210
- if (env->cp15.c9_pmcr & PMCRD) {
188
- struct CombinerGroupState group[IIC_NGRP];
211
- /* Increment once every 64 processor clock cycles */
189
- uint32_t reg_set[IIC_REGSET_SIZE];
212
- total_ticks /= 64;
190
- uint32_t icipsr[2];
213
- }
191
- uint32_t external; /* 1 means that this combiner is external */
214
- env->cp15.c15_ccnt = total_ticks - value;
192
-
215
+ pmccntr_op_start(env);
193
- qemu_irq output_irq[IIC_NGRP];
216
+ env->cp15.c15_ccnt = value;
194
-};
217
+ pmccntr_op_finish(env);
195
218
}
196
static const VMStateDescription vmstate_exynos4210_combiner_group_state = {
219
197
.name = "exynos4210.combiner.groupstate",
220
static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
221
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
222
223
#else /* CONFIG_USER_ONLY */
224
225
-void pmccntr_sync(CPUARMState *env)
226
+void pmccntr_op_start(CPUARMState *env)
227
+{
228
+}
229
+
230
+void pmccntr_op_finish(CPUARMState *env)
231
+{
232
+}
233
+
234
+void pmu_op_start(CPUARMState *env)
235
+{
236
+}
237
+
238
+void pmu_op_finish(CPUARMState *env)
239
{
240
}
241
242
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env)
243
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
244
uint64_t value)
245
{
246
- pmccntr_sync(env);
247
+ pmccntr_op_start(env);
248
env->cp15.pmccfiltr_el0 = value & 0xfc000000;
249
- pmccntr_sync(env);
250
+ pmccntr_op_finish(env);
251
}
252
253
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
254
--
198
--
255
2.20.1
199
2.25.1
256
257
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The only time we use the int_combiner_irq[] and ext_combiner_irq[]
2
arrays in the Exynos4210Irq struct is during realize of the SoC -- we
3
initialize them with the input IRQs of the combiner devices, and then
4
connect those to outputs of other devices in
5
exynos4210_init_board_irqs(). Now that the combiner objects are
6
easily accessible as s->int_combiner and s->ext_combiner we can make
7
the connections directly from one device to the other without going
8
via these arrays.
2
9
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Since these are the only two remaining elements of Exynos4210Irq,
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
we can remove that struct entirely.
5
Message-id: 20190108223129.5570-29-richard.henderson@linaro.org
12
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20220404154658.565020-19-peter.maydell@linaro.org
7
---
16
---
8
target/arm/helper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
17
include/hw/arm/exynos4210.h | 6 ------
9
1 file changed, 70 insertions(+)
18
hw/arm/exynos4210.c | 34 ++++++++--------------------------
19
2 files changed, 8 insertions(+), 32 deletions(-)
10
20
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
12
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
23
--- a/include/hw/arm/exynos4210.h
14
+++ b/target/arm/helper.c
24
+++ b/include/hw/arm/exynos4210.h
15
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
25
@@ -XXX,XX +XXX,XX @@
16
return access_lor_ns(env);
26
*/
17
}
27
#define EXYNOS4210_NUM_SPLITTERS (EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ + 38)
18
28
19
+#ifdef TARGET_AARCH64
29
-typedef struct Exynos4210Irq {
20
+static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
30
- qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
21
+ bool isread)
31
- qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
22
+{
32
-} Exynos4210Irq;
23
+ int el = arm_current_el(env);
33
-
24
+
34
struct Exynos4210State {
25
+ if (el < 2 &&
35
/*< private >*/
26
+ arm_feature(env, ARM_FEATURE_EL2) &&
36
SysBusDevice parent_obj;
27
+ !(arm_hcr_el2_eff(env) & HCR_APK)) {
37
/*< public >*/
28
+ return CP_ACCESS_TRAP_EL2;
38
ARMCPU *cpu[EXYNOS4210_NCPUS];
29
+ }
39
- Exynos4210Irq irqs;
30
+ if (el < 3 &&
40
qemu_irq irq_table[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
31
+ arm_feature(env, ARM_FEATURE_EL3) &&
41
32
+ !(env->cp15.scr_el3 & SCR_APK)) {
42
MemoryRegion chipid_mem;
33
+ return CP_ACCESS_TRAP_EL3;
43
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
34
+ }
44
index XXXXXXX..XXXXXXX 100644
35
+ return CP_ACCESS_OK;
45
--- a/hw/arm/exynos4210.c
36
+}
46
+++ b/hw/arm/exynos4210.c
37
+
47
@@ -XXX,XX +XXX,XX @@ static int mapline_size(const int *mapline)
38
+static const ARMCPRegInfo pauth_reginfo[] = {
48
static void exynos4210_init_board_irqs(Exynos4210State *s)
39
+ { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
40
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
41
+ .access = PL1_RW, .accessfn = access_pauth,
42
+ .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
43
+ { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
45
+ .access = PL1_RW, .accessfn = access_pauth,
46
+ .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
47
+ { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
48
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
49
+ .access = PL1_RW, .accessfn = access_pauth,
50
+ .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
51
+ { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
52
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
53
+ .access = PL1_RW, .accessfn = access_pauth,
54
+ .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
55
+ { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
56
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
57
+ .access = PL1_RW, .accessfn = access_pauth,
58
+ .fieldoffset = offsetof(CPUARMState, apga_key.lo) },
59
+ { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
60
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
61
+ .access = PL1_RW, .accessfn = access_pauth,
62
+ .fieldoffset = offsetof(CPUARMState, apga_key.hi) },
63
+ { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
65
+ .access = PL1_RW, .accessfn = access_pauth,
66
+ .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
67
+ { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
68
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
69
+ .access = PL1_RW, .accessfn = access_pauth,
70
+ .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
71
+ { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
72
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
73
+ .access = PL1_RW, .accessfn = access_pauth,
74
+ .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
75
+ { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
76
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
77
+ .access = PL1_RW, .accessfn = access_pauth,
78
+ .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
79
+ REGINFO_SENTINEL
80
+};
81
+#endif
82
+
83
void register_cp_regs_for_features(ARMCPU *cpu)
84
{
49
{
85
/* Register all the coprocessor registers based on feature bits */
50
uint32_t grp, bit, irq_id, n;
86
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
51
- Exynos4210Irq *is = &s->irqs;
87
define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
52
DeviceState *extgicdev = DEVICE(&s->ext_gic);
53
+ DeviceState *intcdev = DEVICE(&s->int_combiner);
54
+ DeviceState *extcdev = DEVICE(&s->ext_combiner);
55
int splitcount = 0;
56
DeviceState *splitter;
57
const int *mapline;
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
59
splitin = 0;
60
for (;;) {
61
s->irq_table[in] = qdev_get_gpio_in(splitter, 0);
62
- qdev_connect_gpio_out(splitter, splitin, is->int_combiner_irq[in]);
63
- qdev_connect_gpio_out(splitter, splitin + 1, is->ext_combiner_irq[in]);
64
+ qdev_connect_gpio_out(splitter, splitin,
65
+ qdev_get_gpio_in(intcdev, in));
66
+ qdev_connect_gpio_out(splitter, splitin + 1,
67
+ qdev_get_gpio_in(extcdev, in));
68
splitin += 2;
69
if (!mapline) {
70
break;
71
@@ -XXX,XX +XXX,XX @@ static void exynos4210_init_board_irqs(Exynos4210State *s)
72
qdev_realize(splitter, NULL, &error_abort);
73
splitcount++;
74
s->irq_table[n] = qdev_get_gpio_in(splitter, 0);
75
- qdev_connect_gpio_out(splitter, 0, is->int_combiner_irq[n]);
76
+ qdev_connect_gpio_out(splitter, 0, qdev_get_gpio_in(intcdev, n));
77
qdev_connect_gpio_out(splitter, 1,
78
qdev_get_gpio_in(extgicdev, irq_id - 32));
79
} else {
80
- s->irq_table[n] = is->int_combiner_irq[n];
81
+ s->irq_table[n] = qdev_get_gpio_in(intcdev, n);
88
}
82
}
89
}
83
}
90
+
84
/*
91
+#ifdef TARGET_AARCH64
85
@@ -XXX,XX +XXX,XX @@ uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit)
92
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
86
return EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit);
93
+ define_arm_cp_regs(cpu, pauth_reginfo);
94
+ }
95
+#endif
96
}
87
}
97
88
98
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
89
-/*
90
- * Get Combiner input GPIO into irqs structure
91
- */
92
-static void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs,
93
- DeviceState *dev, int ext)
94
-{
95
- int n;
96
- int max;
97
- qemu_irq *irq;
98
-
99
- max = ext ? EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ :
100
- EXYNOS4210_MAX_INT_COMBINER_IN_IRQ;
101
- irq = ext ? irqs->ext_combiner_irq : irqs->int_combiner_irq;
102
-
103
- for (n = 0; n < max; n++) {
104
- irq[n] = qdev_get_gpio_in(dev, n);
105
- }
106
-}
107
-
108
static uint8_t chipid_and_omr[] = { 0x11, 0x02, 0x21, 0x43,
109
0x09, 0x00, 0x00, 0x00 };
110
111
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
112
sysbus_connect_irq(busdev, n,
113
qdev_get_gpio_in(DEVICE(&s->a9mpcore), n));
114
}
115
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->int_combiner), 0);
116
sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
117
118
/* External Interrupt Combiner */
119
@@ -XXX,XX +XXX,XX @@ static void exynos4210_realize(DeviceState *socdev, Error **errp)
120
for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
121
sysbus_connect_irq(busdev, n, qdev_get_gpio_in(DEVICE(&s->ext_gic), n));
122
}
123
- exynos4210_combiner_get_gpioin(&s->irqs, DEVICE(&s->ext_combiner), 1);
124
sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
125
126
/* Initialize board IRQs. */
99
--
127
--
100
2.20.1
128
2.25.1
101
102
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220324181557.203805-2-zongyuan.li@smartx.com
6
Message-id: 20181211151945.29137-6-aaron@os.amperecomputing.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
7
---
9
target/arm/helper.c | 27 ++++++++++++++++++++++++++-
8
hw/arm/realview.c | 33 ++++++++++++++++++++++++---------
10
1 file changed, 26 insertions(+), 1 deletion(-)
9
1 file changed, 24 insertions(+), 9 deletions(-)
11
10
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
13
--- a/hw/arm/realview.c
15
+++ b/target/arm/helper.c
14
+++ b/hw/arm/realview.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
15
@@ -XXX,XX +XXX,XX @@
17
PMXEVTYPER_M | PMXEVTYPER_MT | \
16
#include "hw/sysbus.h"
18
PMXEVTYPER_EVTCOUNT)
17
#include "hw/arm/boot.h"
19
18
#include "hw/arm/primecell.h"
20
+#define PMCCFILTR 0xf8000000
19
+#include "hw/core/split-irq.h"
21
+#define PMCCFILTR_M PMXEVTYPER_M
20
#include "hw/net/lan9118.h"
22
+#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
21
#include "hw/net/smc91c111.h"
22
#include "hw/pci/pci.h"
23
+#include "hw/qdev-core.h"
24
#include "net/net.h"
25
#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
@@ -XXX,XX +XXX,XX @@ static const int realview_board_id[] = {
28
0x76d
29
};
30
31
+static void split_irq_from_named(DeviceState *src, const char* outname,
32
+ qemu_irq out1, qemu_irq out2) {
33
+ DeviceState *splitter = qdev_new(TYPE_SPLIT_IRQ);
23
+
34
+
24
static inline uint32_t pmu_num_counters(CPUARMState *env)
35
+ qdev_prop_set_uint32(splitter, "num-lines", 2);
25
{
36
+
26
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
37
+ qdev_realize_and_unref(splitter, NULL, &error_fatal);
27
@@ -XXX,XX +XXX,XX @@ static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
38
+
28
uint64_t value)
39
+ qdev_connect_gpio_out(splitter, 0, out1);
29
{
40
+ qdev_connect_gpio_out(splitter, 1, out2);
30
pmccntr_op_start(env);
41
+ qdev_connect_gpio_out_named(src, outname, 0,
31
- env->cp15.pmccfiltr_el0 = value & 0xfc000000;
42
+ qdev_get_gpio_in(splitter, 0));
32
+ env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
33
pmccntr_op_finish(env);
34
}
35
36
+static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
37
+ uint64_t value)
38
+{
39
+ pmccntr_op_start(env);
40
+ /* M is not accessible from AArch32 */
41
+ env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
42
+ (value & PMCCFILTR);
43
+ pmccntr_op_finish(env);
44
+}
43
+}
45
+
44
+
46
+static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
45
static void realview_init(MachineState *machine,
47
+{
46
enum realview_board_type board_type)
48
+ /* M is not visible in AArch32 */
47
{
49
+ return env->cp15.pmccfiltr_el0 & PMCCFILTR;
48
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
50
+}
49
DeviceState *dev, *sysctl, *gpio2, *pl041;
50
SysBusDevice *busdev;
51
qemu_irq pic[64];
52
- qemu_irq mmc_irq[2];
53
PCIBus *pci_bus = NULL;
54
NICInfo *nd;
55
DriveInfo *dinfo;
56
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
57
* and the PL061 has them the other way about. Also the card
58
* detect line is inverted.
59
*/
60
- mmc_irq[0] = qemu_irq_split(
61
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
62
- qdev_get_gpio_in(gpio2, 1));
63
- mmc_irq[1] = qemu_irq_split(
64
- qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
65
- qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
66
- qdev_connect_gpio_out_named(dev, "card-read-only", 0, mmc_irq[0]);
67
- qdev_connect_gpio_out_named(dev, "card-inserted", 0, mmc_irq[1]);
68
+ split_irq_from_named(dev, "card-read-only",
69
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),
70
+ qdev_get_gpio_in(gpio2, 1));
51
+
71
+
52
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
+ split_irq_from_named(dev, "card-inserted",
53
uint64_t value)
73
+ qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),
54
{
74
+ qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));
55
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
75
+
56
.readfn = pmccntr_read, .writefn = pmccntr_write,
76
dinfo = drive_get(IF_SD, 0, 0);
57
.raw_readfn = raw_read, .raw_writefn = raw_write, },
77
if (dinfo) {
58
#endif
78
DeviceState *card;
59
+ { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
60
+ .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
61
+ .access = PL0_RW, .accessfn = pmreg_access,
62
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
63
+ .resetvalue = 0, },
64
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
65
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
66
.writefn = pmccfiltr_write, .raw_writefn = raw_write,
67
--
79
--
68
2.20.1
80
2.25.1
69
70
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
Add 4 attributes that controls the EL1 enable bits, as we may not
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
always want to turn on pointer authentication with -cpu max.
5
However, by default they are enabled.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-31-richard.henderson@linaro.org
5
Message-id: 20220324181557.203805-3-zongyuan.li@smartx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
target/arm/cpu.c | 3 +++
8
hw/arm/stellaris.c | 15 +++++++++++++--
13
target/arm/cpu64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 13 insertions(+), 2 deletions(-)
14
2 files changed, 63 insertions(+)
15
10
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.c
13
--- a/hw/arm/stellaris.c
19
+++ b/target/arm/cpu.c
14
+++ b/hw/arm/stellaris.c
20
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
15
@@ -XXX,XX +XXX,XX @@
21
env->pstate = PSTATE_MODE_EL0t;
16
22
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
17
#include "qemu/osdep.h"
23
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
18
#include "qapi/error.h"
24
+ /* Enable all PAC instructions */
19
+#include "hw/core/split-irq.h"
25
+ env->cp15.hcr_el2 |= HCR_API;
20
#include "hw/sysbus.h"
26
+ env->cp15.scr_el3 |= SCR_API;
21
#include "hw/sd/sd.h"
27
/* and to the FP/Neon instructions */
22
#include "hw/ssi/ssi.h"
28
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
23
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
29
/* and to the SVE instructions */
24
DeviceState *ssddev;
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
25
DriveInfo *dinfo;
31
index XXXXXXX..XXXXXXX 100644
26
DeviceState *carddev;
32
--- a/target/arm/cpu64.c
27
+ DeviceState *gpio_d_splitter;
33
+++ b/target/arm/cpu64.c
28
BlockBackend *blk;
34
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
29
35
error_propagate(errp, err);
30
/*
36
}
31
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
37
32
&error_fatal);
38
+#ifdef CONFIG_USER_ONLY
33
39
+static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
34
ssddev = ssi_create_peripheral(bus, "ssd0323");
40
+ void *opaque, Error **errp)
35
- gpio_out[GPIO_D][0] = qemu_irq_split(
41
+{
36
- qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0),
42
+ ARMCPU *cpu = ARM_CPU(obj);
43
+ const uint64_t *bit = opaque;
44
+ bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
45
+
37
+
46
+ visit_type_bool(v, name, &enabled, errp);
38
+ gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
47
+}
39
+ qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
40
+ qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
41
+ qdev_connect_gpio_out(
42
+ gpio_d_splitter, 0,
43
+ qdev_get_gpio_in_named(sddev, SSI_GPIO_CS, 0));
44
+ qdev_connect_gpio_out(
45
+ gpio_d_splitter, 1,
46
qdev_get_gpio_in_named(ssddev, SSI_GPIO_CS, 0));
47
+ gpio_out[GPIO_D][0] = qdev_get_gpio_in(gpio_d_splitter, 0);
48
+
48
+
49
+static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
49
gpio_out[GPIO_C][7] = qdev_get_gpio_in(ssddev, 0);
50
+ void *opaque, Error **errp)
50
51
+{
51
/* Make sure the select pin is high. */
52
+ ARMCPU *cpu = ARM_CPU(obj);
53
+ Error *err = NULL;
54
+ const uint64_t *bit = opaque;
55
+ bool enabled;
56
+
57
+ visit_type_bool(v, name, &enabled, errp);
58
+
59
+ if (!err) {
60
+ if (enabled) {
61
+ cpu->env.cp15.sctlr_el[1] |= *bit;
62
+ } else {
63
+ cpu->env.cp15.sctlr_el[1] &= ~*bit;
64
+ }
65
+ }
66
+ error_propagate(errp, err);
67
+}
68
+#endif
69
+
70
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
71
* otherwise, a CPU with as many features enabled as our emulation supports.
72
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
73
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
74
*/
75
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
76
cpu->dcz_blocksize = 7; /* 512 bytes */
77
+
78
+ /*
79
+ * Note that Linux will enable enable all of the keys at once.
80
+ * But doing it this way will allow experimentation beyond that.
81
+ */
82
+ {
83
+ static const uint64_t apia_bit = SCTLR_EnIA;
84
+ static const uint64_t apib_bit = SCTLR_EnIB;
85
+ static const uint64_t apda_bit = SCTLR_EnDA;
86
+ static const uint64_t apdb_bit = SCTLR_EnDB;
87
+
88
+ object_property_add(obj, "apia", "bool", cpu_max_get_packey,
89
+ cpu_max_set_packey, NULL,
90
+ (void *)&apia_bit, &error_fatal);
91
+ object_property_add(obj, "apib", "bool", cpu_max_get_packey,
92
+ cpu_max_set_packey, NULL,
93
+ (void *)&apib_bit, &error_fatal);
94
+ object_property_add(obj, "apda", "bool", cpu_max_get_packey,
95
+ cpu_max_set_packey, NULL,
96
+ (void *)&apda_bit, &error_fatal);
97
+ object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
98
+ cpu_max_set_packey, NULL,
99
+ (void *)&apdb_bit, &error_fatal);
100
+
101
+ /* Enable all PAC keys by default. */
102
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
103
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
104
+ }
105
#endif
106
107
cpu->sve_max_vq = ARM_MAX_VQ;
108
--
52
--
109
2.20.1
53
2.25.1
110
111
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zongyuan Li <zongyuan.li@smartx.com>
2
2
3
The arm_regime_tbi{0,1} functions are replacable with the new function
3
Signed-off-by: Zongyuan Li <zongyuan.li@smartx.com>
4
by giving the lowest and highest address.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20220324181557.203805-5-zongyuan.li@smartx.com
8
Message-id: 20190108223129.5570-24-richard.henderson@linaro.org
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/811
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
target/arm/cpu.h | 35 -----------------------
9
include/hw/irq.h | 5 -----
12
target/arm/helper.c | 70 ++++++++++++++++-----------------------------
10
hw/core/irq.c | 15 ---------------
13
2 files changed, 24 insertions(+), 81 deletions(-)
11
2 files changed, 20 deletions(-)
14
12
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/include/hw/irq.h b/include/hw/irq.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
15
--- a/include/hw/irq.h
18
+++ b/target/arm/cpu.h
16
+++ b/include/hw/irq.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
17
@@ -XXX,XX +XXX,XX @@ void qemu_free_irq(qemu_irq irq);
18
/* Returns a new IRQ with opposite polarity. */
19
qemu_irq qemu_irq_invert(qemu_irq irq);
20
21
-/* Returns a new IRQ which feeds into both the passed IRQs.
22
- * It's probably better to use the TYPE_SPLIT_IRQ device instead.
23
- */
24
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
25
-
26
/* For internal use in qtest. Similar to qemu_irq_split, but operating
27
on an existing vector of qemu_irq. */
28
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
29
diff --git a/hw/core/irq.c b/hw/core/irq.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/core/irq.c
32
+++ b/hw/core/irq.c
33
@@ -XXX,XX +XXX,XX @@ qemu_irq qemu_irq_invert(qemu_irq irq)
34
return qemu_allocate_irq(qemu_notirq, irq, 0);
20
}
35
}
21
#endif
36
22
37
-static void qemu_splitirq(void *opaque, int line, int level)
23
-#ifndef CONFIG_USER_ONLY
24
-/**
25
- * arm_regime_tbi0:
26
- * @env: CPUARMState
27
- * @mmu_idx: MMU index indicating required translation regime
28
- *
29
- * Extracts the TBI0 value from the appropriate TCR for the current EL
30
- *
31
- * Returns: the TBI0 value.
32
- */
33
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
34
-
35
-/**
36
- * arm_regime_tbi1:
37
- * @env: CPUARMState
38
- * @mmu_idx: MMU index indicating required translation regime
39
- *
40
- * Extracts the TBI1 value from the appropriate TCR for the current EL
41
- *
42
- * Returns: the TBI1 value.
43
- */
44
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
45
-#else
46
-/* We can't handle tagged addresses properly in user-only mode */
47
-static inline uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
48
-{
38
-{
49
- return 0;
39
- struct IRQState **irq = opaque;
40
- irq[0]->handler(irq[0]->opaque, irq[0]->n, level);
41
- irq[1]->handler(irq[1]->opaque, irq[1]->n, level);
50
-}
42
-}
51
-
43
-
52
-static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
44
-qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2)
53
-{
45
-{
54
- return 0;
46
- qemu_irq *s = g_new0(qemu_irq, 2);
55
-}
47
- s[0] = irq1;
56
-#endif
48
- s[1] = irq2;
57
-
49
- return qemu_allocate_irq(qemu_splitirq, s, 0);
58
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
59
target_ulong *cs_base, uint32_t *flags);
60
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
66
return mmu_idx;
67
}
68
69
-/* Returns TBI0 value for current regime el */
70
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
71
-{
72
- TCR *tcr;
73
- uint32_t el;
74
-
75
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
76
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
77
- */
78
- mmu_idx = stage_1_mmu_idx(mmu_idx);
79
-
80
- tcr = regime_tcr(env, mmu_idx);
81
- el = regime_el(env, mmu_idx);
82
-
83
- if (el > 1) {
84
- return extract64(tcr->raw_tcr, 20, 1);
85
- } else {
86
- return extract64(tcr->raw_tcr, 37, 1);
87
- }
88
-}
50
-}
89
-
51
-
90
-/* Returns TBI1 value for current regime el */
52
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n)
91
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
53
{
92
-{
54
int i;
93
- TCR *tcr;
94
- uint32_t el;
95
-
96
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
97
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
98
- */
99
- mmu_idx = stage_1_mmu_idx(mmu_idx);
100
-
101
- tcr = regime_tcr(env, mmu_idx);
102
- el = regime_el(env, mmu_idx);
103
-
104
- if (el > 1) {
105
- return 0;
106
- } else {
107
- return extract64(tcr->raw_tcr, 38, 1);
108
- }
109
-}
110
-
111
/* Return the TTBR associated with this translation regime */
112
static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
113
int ttbrn)
114
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
115
116
*pc = env->pc;
117
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
118
- /* Get control bits for tagged addresses */
119
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
120
- (arm_regime_tbi1(env, mmu_idx) << 1) |
121
- arm_regime_tbi0(env, mmu_idx));
122
+
123
+#ifndef CONFIG_USER_ONLY
124
+ /*
125
+ * Get control bits for tagged addresses. Note that the
126
+ * translator only uses this for instruction addresses.
127
+ */
128
+ {
129
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
130
+ ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
131
+ int tbii, tbid;
132
+
133
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
134
+ if (regime_el(env, stage1) < 2) {
135
+ ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
136
+ tbid = (p1.tbi << 1) | p0.tbi;
137
+ tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
138
+ } else {
139
+ tbid = p0.tbi;
140
+ tbii = tbid & !p0.tbid;
141
+ }
142
+
143
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
144
+ }
145
+#endif
146
147
if (cpu_isar_feature(aa64_sve, cpu)) {
148
int sve_el = sve_exception_el(env, current_el);
149
--
55
--
150
2.20.1
56
2.25.1
151
152
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
2
2
3
Describe that the gic-version influences the maximum number of CPUs.
4
5
Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
6
Message-id: 20220413231456.35811-1-heinrich.schuchardt@canonical.com
7
[PMM: minor punctuation tweaks]
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-30-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/cpu64.c | 4 ++++
11
docs/system/arm/virt.rst | 4 ++--
9
1 file changed, 4 insertions(+)
12
1 file changed, 2 insertions(+), 2 deletions(-)
10
13
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
16
--- a/docs/system/arm/virt.rst
14
+++ b/target/arm/cpu64.c
17
+++ b/docs/system/arm/virt.rst
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ gic-version
16
19
Valid values are:
17
t = cpu->isar.id_aa64isar1;
20
18
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
21
``2``
19
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
22
- GICv2
20
+ t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
23
+ GICv2. Note that this limits the number of CPUs to 8.
21
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
24
``3``
22
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
25
- GICv3
23
cpu->isar.id_aa64isar1 = t;
26
+ GICv3. This allows up to 512 CPUs.
24
27
``host``
25
t = cpu->isar.id_aa64pfr0;
28
Use the same GIC version the host provides, when using KVM
29
``max``
26
--
30
--
27
2.20.1
31
2.25.1
28
29
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This path uses cpu_loop_exit_restore to unwind current processor state.
3
Similar to the Aspeed code in include/misc/aspeed_scu.h, we define
4
the PWRON STRAP fields in their corresponding module for NPCM7XX.
4
5
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-2-wuhaotsh@google.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-5-richard.henderson@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
target/arm/internals.h | 7 +++++++
12
include/hw/misc/npcm7xx_gcr.h | 30 ++++++++++++++++++++++++++++++
12
target/arm/op_helper.c | 19 +++++++++++++++++--
13
1 file changed, 30 insertions(+)
13
2 files changed, 24 insertions(+), 2 deletions(-)
14
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
diff --git a/include/hw/misc/npcm7xx_gcr.h b/include/hw/misc/npcm7xx_gcr.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
17
--- a/include/hw/misc/npcm7xx_gcr.h
18
+++ b/target/arm/internals.h
18
+++ b/include/hw/misc/npcm7xx_gcr.h
19
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_EXCRET, RES1, 7, 25) /* including the must-be-1 prefix */
19
@@ -XXX,XX +XXX,XX @@
20
void QEMU_NORETURN raise_exception(CPUARMState *env, uint32_t excp,
20
#include "exec/memory.h"
21
uint32_t syndrome, uint32_t target_el);
21
#include "hw/sysbus.h"
22
22
23
+/*
23
+/*
24
+ * Similarly, but also use unwinding to restore cpu state.
24
+ * NPCM7XX PWRON STRAP bit fields
25
+ * 12: SPI0 powered by VSBV3 at 1.8V
26
+ * 11: System flash attached to BMC
27
+ * 10: BSP alternative pins.
28
+ * 9:8: Flash UART command route enabled.
29
+ * 7: Security enabled.
30
+ * 6: HI-Z state control.
31
+ * 5: ECC disabled.
32
+ * 4: Reserved
33
+ * 3: JTAG2 enabled.
34
+ * 2:0: CPU and DRAM clock frequency.
25
+ */
35
+ */
26
+void QEMU_NORETURN raise_exception_ra(CPUARMState *env, uint32_t excp,
36
+#define NPCM7XX_PWRON_STRAP_SPI0F18 BIT(12)
27
+ uint32_t syndrome, uint32_t target_el,
37
+#define NPCM7XX_PWRON_STRAP_SFAB BIT(11)
28
+ uintptr_t ra);
38
+#define NPCM7XX_PWRON_STRAP_BSPA BIT(10)
39
+#define NPCM7XX_PWRON_STRAP_FUP(x) ((x) << 8)
40
+#define FUP_NORM_UART2 3
41
+#define FUP_PROG_UART3 2
42
+#define FUP_PROG_UART2 1
43
+#define FUP_NORM_UART3 0
44
+#define NPCM7XX_PWRON_STRAP_SECEN BIT(7)
45
+#define NPCM7XX_PWRON_STRAP_HIZ BIT(6)
46
+#define NPCM7XX_PWRON_STRAP_ECC BIT(5)
47
+#define NPCM7XX_PWRON_STRAP_RESERVE1 BIT(4)
48
+#define NPCM7XX_PWRON_STRAP_J2EN BIT(3)
49
+#define NPCM7XX_PWRON_STRAP_CKFRQ(x) (x)
50
+#define CKFRQ_SKIPINIT 0x000
51
+#define CKFRQ_DEFAULT 0x111
29
+
52
+
30
/*
53
/*
31
* For AArch64, map a given EL to an index in the banked_spsr array.
54
* Number of registers in our device state structure. Don't change this without
32
* Note that this mapping and the AArch32 mapping defined in bank_number()
55
* incrementing the version_id in the vmstate.
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@
38
#define SIGNBIT (uint32_t)0x80000000
39
#define SIGNBIT64 ((uint64_t)1 << 63)
40
41
-void raise_exception(CPUARMState *env, uint32_t excp,
42
- uint32_t syndrome, uint32_t target_el)
43
+static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
44
+ uint32_t syndrome, uint32_t target_el)
45
{
46
CPUState *cs = CPU(arm_env_get_cpu(env));
47
48
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
49
cs->exception_index = excp;
50
env->exception.syndrome = syndrome;
51
env->exception.target_el = target_el;
52
+
53
+ return cs;
54
+}
55
+
56
+void raise_exception(CPUARMState *env, uint32_t excp,
57
+ uint32_t syndrome, uint32_t target_el)
58
+{
59
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
60
cpu_loop_exit(cs);
61
}
62
63
+void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
64
+ uint32_t target_el, uintptr_t ra)
65
+{
66
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
67
+ cpu_loop_exit_restore(cs, ra);
68
+}
69
+
70
static int exception_target_el(CPUARMState *env)
71
{
72
int target_el = MAX(1, arm_current_el(env));
73
--
56
--
74
2.20.1
57
2.25.1
75
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Hao Wu <wuhaotsh@google.com>
2
2
3
This patch uses the defined fields to describe PWRON STRAPs for
4
better readability.
5
6
Signed-off-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Patrick Venture <venture@google.com>
8
Message-id: 20220411165842.3912945-3-wuhaotsh@google.com
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/translate-a64.c | 93 +++++++++++++++++++++++++++++++++-----
12
hw/arm/npcm7xx_boards.c | 24 +++++++++++++++++++-----
9
1 file changed, 81 insertions(+), 12 deletions(-)
13
1 file changed, 19 insertions(+), 5 deletions(-)
10
14
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
17
--- a/hw/arm/npcm7xx_boards.c
14
+++ b/target/arm/translate-a64.c
18
+++ b/hw/arm/npcm7xx_boards.c
15
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
19
@@ -XXX,XX +XXX,XX @@
16
}
20
#include "sysemu/sysemu.h"
17
21
#include "sysemu/block-backend.h"
18
switch (selector) {
22
19
- case 0: /* NOP */
23
-#define NPCM750_EVB_POWER_ON_STRAPS 0x00001ff7
20
- return;
24
-#define QUANTA_GSJ_POWER_ON_STRAPS 0x00001fff
21
- case 3: /* WFI */
25
-#define QUANTA_GBS_POWER_ON_STRAPS 0x000017ff
22
+ case 0b00000: /* NOP */
26
-#define KUDO_BMC_POWER_ON_STRAPS 0x00001fff
23
+ break;
27
-#define MORI_BMC_POWER_ON_STRAPS 0x00001fff
24
+ case 0b00011: /* WFI */
28
+#define NPCM7XX_POWER_ON_STRAPS_DEFAULT ( \
25
s->base.is_jmp = DISAS_WFI;
29
+ NPCM7XX_PWRON_STRAP_SPI0F18 | \
26
- return;
30
+ NPCM7XX_PWRON_STRAP_SFAB | \
27
+ break;
31
+ NPCM7XX_PWRON_STRAP_BSPA | \
28
+ case 0b00001: /* YIELD */
32
+ NPCM7XX_PWRON_STRAP_FUP(FUP_NORM_UART2) | \
29
/* When running in MTTCG we don't generate jumps to the yield and
33
+ NPCM7XX_PWRON_STRAP_SECEN | \
30
* WFE helpers as it won't affect the scheduling of other vCPUs.
34
+ NPCM7XX_PWRON_STRAP_HIZ | \
31
* If we wanted to more completely model WFE/SEV so we don't busy
35
+ NPCM7XX_PWRON_STRAP_ECC | \
32
* spin unnecessarily we would need to do something more involved.
36
+ NPCM7XX_PWRON_STRAP_RESERVE1 | \
33
*/
37
+ NPCM7XX_PWRON_STRAP_J2EN | \
34
- case 1: /* YIELD */
38
+ NPCM7XX_PWRON_STRAP_CKFRQ(CKFRQ_DEFAULT))
35
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
39
+
36
s->base.is_jmp = DISAS_YIELD;
40
+#define NPCM750_EVB_POWER_ON_STRAPS ( \
37
}
41
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_J2EN)
38
- return;
42
+#define QUANTA_GSJ_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
39
- case 2: /* WFE */
43
+#define QUANTA_GBS_POWER_ON_STRAPS ( \
40
+ break;
44
+ NPCM7XX_POWER_ON_STRAPS_DEFAULT & ~NPCM7XX_PWRON_STRAP_SFAB)
41
+ case 0b00010: /* WFE */
45
+#define KUDO_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
42
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
46
+#define MORI_BMC_POWER_ON_STRAPS NPCM7XX_POWER_ON_STRAPS_DEFAULT
43
s->base.is_jmp = DISAS_WFE;
47
44
}
48
static const char npcm7xx_default_bootrom[] = "npcm7xx_bootrom.bin";
45
- return;
46
- case 4: /* SEV */
47
- case 5: /* SEVL */
48
+ break;
49
+ case 0b00100: /* SEV */
50
+ case 0b00101: /* SEVL */
51
/* we treat all as NOP at least for now */
52
- return;
53
+ break;
54
+ case 0b00111: /* XPACLRI */
55
+ if (s->pauth_active) {
56
+ gen_helper_xpaci(cpu_X[30], cpu_env, cpu_X[30]);
57
+ }
58
+ break;
59
+ case 0b01000: /* PACIA1716 */
60
+ if (s->pauth_active) {
61
+ gen_helper_pacia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
62
+ }
63
+ break;
64
+ case 0b01010: /* PACIB1716 */
65
+ if (s->pauth_active) {
66
+ gen_helper_pacib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
67
+ }
68
+ break;
69
+ case 0b01100: /* AUTIA1716 */
70
+ if (s->pauth_active) {
71
+ gen_helper_autia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
72
+ }
73
+ break;
74
+ case 0b01110: /* AUTIB1716 */
75
+ if (s->pauth_active) {
76
+ gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
77
+ }
78
+ break;
79
+ case 0b11000: /* PACIAZ */
80
+ if (s->pauth_active) {
81
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
82
+ new_tmp_a64_zero(s));
83
+ }
84
+ break;
85
+ case 0b11001: /* PACIASP */
86
+ if (s->pauth_active) {
87
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
88
+ }
89
+ break;
90
+ case 0b11010: /* PACIBZ */
91
+ if (s->pauth_active) {
92
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30],
93
+ new_tmp_a64_zero(s));
94
+ }
95
+ break;
96
+ case 0b11011: /* PACIBSP */
97
+ if (s->pauth_active) {
98
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
99
+ }
100
+ break;
101
+ case 0b11100: /* AUTIAZ */
102
+ if (s->pauth_active) {
103
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30],
104
+ new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case 0b11101: /* AUTIASP */
108
+ if (s->pauth_active) {
109
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
110
+ }
111
+ break;
112
+ case 0b11110: /* AUTIBZ */
113
+ if (s->pauth_active) {
114
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30],
115
+ new_tmp_a64_zero(s));
116
+ }
117
+ break;
118
+ case 0b11111: /* AUTIBSP */
119
+ if (s->pauth_active) {
120
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
121
+ }
122
+ break;
123
default:
124
/* default specified as NOP equivalent */
125
- return;
126
+ break;
127
}
128
}
129
49
130
--
50
--
131
2.20.1
51
2.25.1
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 146 +++++++++++++++++++++++++++++++++++++
9
1 file changed, 146 insertions(+)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
16
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
17
{
18
unsigned int sf, opcode, opcode2, rn, rd;
19
+ TCGv_i64 tcg_rd;
20
21
if (extract32(insn, 29, 1)) {
22
unallocated_encoding(s);
23
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
24
case MAP(1, 0x00, 0x05):
25
handle_cls(s, sf, rn, rd);
26
break;
27
+ case MAP(1, 0x01, 0x00): /* PACIA */
28
+ if (s->pauth_active) {
29
+ tcg_rd = cpu_reg(s, rd);
30
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
31
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
32
+ goto do_unallocated;
33
+ }
34
+ break;
35
+ case MAP(1, 0x01, 0x01): /* PACIB */
36
+ if (s->pauth_active) {
37
+ tcg_rd = cpu_reg(s, rd);
38
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
39
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
40
+ goto do_unallocated;
41
+ }
42
+ break;
43
+ case MAP(1, 0x01, 0x02): /* PACDA */
44
+ if (s->pauth_active) {
45
+ tcg_rd = cpu_reg(s, rd);
46
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
47
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
48
+ goto do_unallocated;
49
+ }
50
+ break;
51
+ case MAP(1, 0x01, 0x03): /* PACDB */
52
+ if (s->pauth_active) {
53
+ tcg_rd = cpu_reg(s, rd);
54
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
55
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
56
+ goto do_unallocated;
57
+ }
58
+ break;
59
+ case MAP(1, 0x01, 0x04): /* AUTIA */
60
+ if (s->pauth_active) {
61
+ tcg_rd = cpu_reg(s, rd);
62
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
63
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
64
+ goto do_unallocated;
65
+ }
66
+ break;
67
+ case MAP(1, 0x01, 0x05): /* AUTIB */
68
+ if (s->pauth_active) {
69
+ tcg_rd = cpu_reg(s, rd);
70
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
71
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
72
+ goto do_unallocated;
73
+ }
74
+ break;
75
+ case MAP(1, 0x01, 0x06): /* AUTDA */
76
+ if (s->pauth_active) {
77
+ tcg_rd = cpu_reg(s, rd);
78
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
79
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
80
+ goto do_unallocated;
81
+ }
82
+ break;
83
+ case MAP(1, 0x01, 0x07): /* AUTDB */
84
+ if (s->pauth_active) {
85
+ tcg_rd = cpu_reg(s, rd);
86
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
87
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
88
+ goto do_unallocated;
89
+ }
90
+ break;
91
+ case MAP(1, 0x01, 0x08): /* PACIZA */
92
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
93
+ goto do_unallocated;
94
+ } else if (s->pauth_active) {
95
+ tcg_rd = cpu_reg(s, rd);
96
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
97
+ }
98
+ break;
99
+ case MAP(1, 0x01, 0x09): /* PACIZB */
100
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
101
+ goto do_unallocated;
102
+ } else if (s->pauth_active) {
103
+ tcg_rd = cpu_reg(s, rd);
104
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case MAP(1, 0x01, 0x0a): /* PACDZA */
108
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
109
+ goto do_unallocated;
110
+ } else if (s->pauth_active) {
111
+ tcg_rd = cpu_reg(s, rd);
112
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
113
+ }
114
+ break;
115
+ case MAP(1, 0x01, 0x0b): /* PACDZB */
116
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
117
+ goto do_unallocated;
118
+ } else if (s->pauth_active) {
119
+ tcg_rd = cpu_reg(s, rd);
120
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
121
+ }
122
+ break;
123
+ case MAP(1, 0x01, 0x0c): /* AUTIZA */
124
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
125
+ goto do_unallocated;
126
+ } else if (s->pauth_active) {
127
+ tcg_rd = cpu_reg(s, rd);
128
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
129
+ }
130
+ break;
131
+ case MAP(1, 0x01, 0x0d): /* AUTIZB */
132
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
133
+ goto do_unallocated;
134
+ } else if (s->pauth_active) {
135
+ tcg_rd = cpu_reg(s, rd);
136
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
137
+ }
138
+ break;
139
+ case MAP(1, 0x01, 0x0e): /* AUTDZA */
140
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
141
+ goto do_unallocated;
142
+ } else if (s->pauth_active) {
143
+ tcg_rd = cpu_reg(s, rd);
144
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
145
+ }
146
+ break;
147
+ case MAP(1, 0x01, 0x0f): /* AUTDZB */
148
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
149
+ goto do_unallocated;
150
+ } else if (s->pauth_active) {
151
+ tcg_rd = cpu_reg(s, rd);
152
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
153
+ }
154
+ break;
155
+ case MAP(1, 0x01, 0x10): /* XPACI */
156
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
157
+ goto do_unallocated;
158
+ } else if (s->pauth_active) {
159
+ tcg_rd = cpu_reg(s, rd);
160
+ gen_helper_xpaci(tcg_rd, cpu_env, tcg_rd);
161
+ }
162
+ break;
163
+ case MAP(1, 0x01, 0x11): /* XPACD */
164
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
165
+ goto do_unallocated;
166
+ } else if (s->pauth_active) {
167
+ tcg_rd = cpu_reg(s, rd);
168
+ gen_helper_xpacd(tcg_rd, cpu_env, tcg_rd);
169
+ }
170
+ break;
171
default:
172
+ do_unallocated:
173
unallocated_encoding(s);
174
break;
175
}
176
--
177
2.20.1
178
179
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 8 ++++++++
9
1 file changed, 8 insertions(+)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
16
case 11: /* RORV */
17
handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
18
break;
19
+ case 12: /* PACGA */
20
+ if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) {
21
+ goto do_unallocated;
22
+ }
23
+ gen_helper_pacga(cpu_reg(s, rd), cpu_env,
24
+ cpu_reg(s, rn), cpu_reg_sp(s, rm));
25
+ break;
26
case 16:
27
case 17:
28
case 18:
29
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
30
break;
31
}
32
default:
33
+ do_unallocated:
34
unallocated_encoding(s);
35
break;
36
}
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This will enable PAuth decode in a subsequent patch.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190108223129.5570-13-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 47 +++++++++++++++++++++++++++++---------
11
1 file changed, 36 insertions(+), 11 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
18
rn = extract32(insn, 5, 5);
19
op4 = extract32(insn, 0, 5);
20
21
- if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
22
- unallocated_encoding(s);
23
- return;
24
+ if (op2 != 0x1f) {
25
+ goto do_unallocated;
26
}
27
28
switch (opc) {
29
case 0: /* BR */
30
case 1: /* BLR */
31
case 2: /* RET */
32
- gen_a64_set_pc(s, cpu_reg(s, rn));
33
+ switch (op3) {
34
+ case 0:
35
+ if (op4 != 0) {
36
+ goto do_unallocated;
37
+ }
38
+ dst = cpu_reg(s, rn);
39
+ break;
40
+
41
+ default:
42
+ goto do_unallocated;
43
+ }
44
+
45
+ gen_a64_set_pc(s, dst);
46
/* BLR also needs to load return address */
47
if (opc == 1) {
48
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
49
}
50
break;
51
+
52
case 4: /* ERET */
53
if (s->current_el == 0) {
54
- unallocated_encoding(s);
55
- return;
56
+ goto do_unallocated;
57
+ }
58
+ switch (op3) {
59
+ case 0:
60
+ if (op4 != 0) {
61
+ goto do_unallocated;
62
+ }
63
+ dst = tcg_temp_new_i64();
64
+ tcg_gen_ld_i64(dst, cpu_env,
65
+ offsetof(CPUARMState, elr_el[s->current_el]));
66
+ break;
67
+
68
+ default:
69
+ goto do_unallocated;
70
}
71
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
72
gen_io_start();
73
}
74
- dst = tcg_temp_new_i64();
75
- tcg_gen_ld_i64(dst, cpu_env,
76
- offsetof(CPUARMState, elr_el[s->current_el]));
77
+
78
gen_helper_exception_return(cpu_env, dst);
79
tcg_temp_free_i64(dst);
80
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
/* Must exit loop to check un-masked IRQs */
83
s->base.is_jmp = DISAS_EXIT;
84
return;
85
+
86
case 5: /* DRPS */
87
- if (rn != 0x1f) {
88
- unallocated_encoding(s);
89
+ if (op3 != 0 || op4 != 0 || rn != 0x1f) {
90
+ goto do_unallocated;
91
} else {
92
unsupported_encoding(s, insn);
93
}
94
return;
95
+
96
default:
97
+ do_unallocated:
98
unallocated_encoding(s);
99
return;
100
}
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The pattern
4
5
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
6
7
is computing the full ARMMMUIdx, stripping off the ARM bits,
8
and then putting them back.
9
10
Avoid the extra two steps with the appropriate helper function.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190108223129.5570-17-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/cpu.h | 9 ++++++++-
18
target/arm/internals.h | 8 ++++++++
19
target/arm/helper.c | 27 ++++++++++++++++-----------
20
3 files changed, 32 insertions(+), 12 deletions(-)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
27
/* Return the MMU index for a v7M CPU in the specified security state */
28
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
29
30
-/* Determine the current mmu_idx to use for normal loads/stores */
31
+/**
32
+ * cpu_mmu_index:
33
+ * @env: The cpu environment
34
+ * @ifetch: True for code access, false for data access.
35
+ *
36
+ * Return the core mmu index for the current translation regime.
37
+ * This function is used by generic TCG code paths.
38
+ */
39
int cpu_mmu_index(CPUARMState *env, bool ifetch);
40
41
/* Indexes used when registering address spaces with cpu_address_space_init */
42
diff --git a/target/arm/internals.h b/target/arm/internals.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/internals.h
45
+++ b/target/arm/internals.h
46
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
47
*/
48
void arm_cpu_update_vfiq(ARMCPU *cpu);
49
50
+/**
51
+ * arm_mmu_idx:
52
+ * @env: The cpu environment
53
+ *
54
+ * Return the full ARMMMUIdx for the current translation regime.
55
+ */
56
+ARMMMUIdx arm_mmu_idx(CPUARMState *env);
57
+
58
#endif
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
64
limit = env->v7m.msplim[M_REG_S];
65
}
66
} else {
67
- mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
68
+ mmu_idx = arm_mmu_idx(env);
69
frame_sp_p = &env->regs[13];
70
limit = v7m_sp_limit(env);
71
}
72
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
73
CPUARMState *env = &cpu->env;
74
uint32_t xpsr = xpsr_read(env);
75
uint32_t frameptr = env->regs[13];
76
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
77
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
78
79
/* Align stack pointer if the guest wants that */
80
if ((frameptr & 4) &&
81
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
82
int prot;
83
bool ret;
84
ARMMMUFaultInfo fi = {};
85
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
86
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
87
88
*attrs = (MemTxAttrs) {};
89
90
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
91
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
92
}
93
94
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
95
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
96
{
97
- int el = arm_current_el(env);
98
+ int el;
99
100
if (arm_feature(env, ARM_FEATURE_M)) {
101
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
102
-
103
- return arm_to_core_mmu_idx(mmu_idx);
104
+ return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
105
}
106
107
+ el = arm_current_el(env);
108
if (el < 2 && arm_is_secure_below_el3(env)) {
109
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
110
+ return ARMMMUIdx_S1SE0 + el;
111
+ } else {
112
+ return ARMMMUIdx_S12NSE0 + el;
113
}
114
- return el;
115
+}
116
+
117
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
118
+{
119
+ return arm_to_core_mmu_idx(arm_mmu_idx(env));
120
}
121
122
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
123
target_ulong *cs_base, uint32_t *pflags)
124
{
125
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
126
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
127
int current_el = arm_current_el(env);
128
int fp_el = fp_exception_el(env, current_el);
129
uint32_t flags = 0;
130
--
131
2.20.1
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
While we could expose stage_1_mmu_idx, the combination is
4
probably going to be more useful.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-18-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 15 +++++++++++++++
12
target/arm/helper.c | 7 +++++++
13
2 files changed, 22 insertions(+)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu);
20
*/
21
ARMMMUIdx arm_mmu_idx(CPUARMState *env);
22
23
+/**
24
+ * arm_stage1_mmu_idx:
25
+ * @env: The cpu environment
26
+ *
27
+ * Return the ARMMMUIdx for the stage1 traversal for the current regime.
28
+ */
29
+#ifdef CONFIG_USER_ONLY
30
+static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
31
+{
32
+ return ARMMMUIdx_S1NSE0;
33
+}
34
+#else
35
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
36
+#endif
37
+
38
#endif
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ int cpu_mmu_index(CPUARMState *env, bool ifetch)
44
return arm_to_core_mmu_idx(arm_mmu_idx(env));
45
}
46
47
+#ifndef CONFIG_USER_ONLY
48
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
49
+{
50
+ return stage_1_mmu_idx(arm_mmu_idx(env));
51
+}
52
+#endif
53
+
54
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
55
target_ulong *cs_base, uint32_t *pflags)
56
{
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We will shortly want to talk about TBI as it relates to data.
4
Passing around a pair of variables is less convenient than a
5
single variable.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-20-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 3 +--
13
target/arm/translate.h | 3 +--
14
target/arm/helper.c | 5 ++---
15
target/arm/translate-a64.c | 13 +++++++------
16
4 files changed, 11 insertions(+), 13 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, HANDLER, 21, 1)
23
FIELD(TBFLAG_A32, STACKCHECK, 22, 1)
24
25
/* Bit usage when in AArch64 state */
26
-FIELD(TBFLAG_A64, TBI0, 0, 1)
27
-FIELD(TBFLAG_A64, TBI1, 1, 1)
28
+FIELD(TBFLAG_A64, TBII, 0, 2)
29
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
30
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
31
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.h
35
+++ b/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
int user;
38
#endif
39
ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
40
- bool tbi0; /* TBI0 for EL0/1 or TBI for EL2/3 */
41
- bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
42
+ uint8_t tbii; /* TBI1|TBI0 for EL0/1 or TBI for EL2/3 */
43
bool ns; /* Use non-secure CPREG bank on access */
44
int fp_excp_el; /* FP exception EL or 0 if enabled */
45
int sve_excp_el; /* SVE exception EL or 0 if enabled */
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/helper.c
49
+++ b/target/arm/helper.c
50
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
51
*pc = env->pc;
52
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
53
/* Get control bits for tagged addresses */
54
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI0,
55
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
56
+ (arm_regime_tbi1(env, mmu_idx) << 1) |
57
arm_regime_tbi0(env, mmu_idx));
58
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI1,
59
- arm_regime_tbi1(env, mmu_idx));
60
61
if (cpu_isar_feature(aa64_sve, cpu)) {
62
int sve_el = sve_exception_el(env, current_el);
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-a64.c
66
+++ b/target/arm/translate-a64.c
67
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
68
*/
69
static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
70
{
71
+ /* Note that TBII is TBI1:TBI0. */
72
+ int tbi = s->tbii;
73
74
if (s->current_el <= 1) {
75
/* Test if NEITHER or BOTH TBI values are set. If so, no need to
76
* examine bit 55 of address, can just generate code.
77
* If mixed, then test via generated code
78
*/
79
- if (s->tbi0 && s->tbi1) {
80
+ if (tbi == 3) {
81
TCGv_i64 tmp_reg = tcg_temp_new_i64();
82
/* Both bits set, sign extension from bit 55 into [63:56] will
83
* cover both cases
84
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
85
tcg_gen_shli_i64(tmp_reg, src, 8);
86
tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
87
tcg_temp_free_i64(tmp_reg);
88
- } else if (!s->tbi0 && !s->tbi1) {
89
+ } else if (tbi == 0) {
90
/* Neither bit set, just load it as-is */
91
tcg_gen_mov_i64(cpu_pc, src);
92
} else {
93
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
94
95
tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
96
97
- if (s->tbi0) {
98
+ if (tbi == 1) {
99
/* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
100
tcg_gen_andi_i64(tcg_tmpval, src,
101
0x00FFFFFFFFFFFFFFull);
102
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
103
tcg_temp_free_i64(tcg_tmpval);
104
}
105
} else { /* EL > 1 */
106
- if (s->tbi0) {
107
+ if (tbi != 0) {
108
/* Force tag byte to all zero */
109
tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
110
} else {
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
112
dc->condexec_cond = 0;
113
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
114
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
115
- dc->tbi0 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI0);
116
- dc->tbi1 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI1);
117
+ dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
118
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
119
#if !defined(CONFIG_USER_ONLY)
120
dc->user = (dc->current_el == 0);
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We need to reuse this from helper-a64.c. Provide a stub
4
definition for CONFIG_USER_ONLY. This matches the stub
5
definitions that we removed for arm_regime_tbi{0,1} before.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-21-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/internals.h | 17 +++++++++++++++++
13
target/arm/helper.c | 4 ++--
14
2 files changed, 19 insertions(+), 2 deletions(-)
15
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
21
bool using64k : 1;
22
} ARMVAParameters;
23
24
+#ifdef CONFIG_USER_ONLY
25
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
26
+ uint64_t va,
27
+ ARMMMUIdx mmu_idx, bool data)
28
+{
29
+ return (ARMVAParameters) {
30
+ /* 48-bit address space */
31
+ .tsz = 16,
32
+ /* We can't handle tagged addresses properly in user-only mode */
33
+ .tbi = false,
34
+ };
35
+}
36
+#else
37
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data);
39
+#endif
40
+
41
#endif
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
45
+++ b/target/arm/helper.c
46
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
47
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
48
}
49
50
-static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
51
- ARMMMUIdx mmu_idx, bool data)
52
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
53
+ ARMMMUIdx mmu_idx, bool data)
54
{
55
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
56
uint32_t el = regime_el(env, mmu_idx);
57
--
58
2.20.1
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We will want to check TBI for I and D simultaneously.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190108223129.5570-22-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/internals.h | 15 ++++++++++++---
11
target/arm/helper.c | 10 ++++++++--
12
2 files changed, 20 insertions(+), 5 deletions(-)
13
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
19
} ARMVAParameters;
20
21
#ifdef CONFIG_USER_ONLY
22
-static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
23
- uint64_t va,
24
- ARMMMUIdx mmu_idx, bool data)
25
+static inline ARMVAParameters aa64_va_parameters_both(CPUARMState *env,
26
+ uint64_t va,
27
+ ARMMMUIdx mmu_idx)
28
{
29
return (ARMVAParameters) {
30
/* 48-bit address space */
31
@@ -XXX,XX +XXX,XX @@ static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
32
.tbi = false,
33
};
34
}
35
+
36
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
37
+ uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data)
39
+{
40
+ return aa64_va_parameters_both(env, va, mmu_idx);
41
+}
42
#else
43
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
44
+ ARMMMUIdx mmu_idx);
45
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
ARMMMUIdx mmu_idx, bool data);
47
#endif
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
53
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
54
}
55
56
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
57
- ARMMMUIdx mmu_idx, bool data)
58
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
59
+ ARMMMUIdx mmu_idx)
60
{
61
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
62
uint32_t el = regime_el(env, mmu_idx);
63
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
64
};
65
}
66
67
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
68
+ ARMMMUIdx mmu_idx, bool data)
69
+{
70
+ return aa64_va_parameters_both(env, va, mmu_idx);
71
+}
72
+
73
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
74
ARMMMUIdx mmu_idx)
75
{
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Use TBID in aa64_va_parameters depending on the data parameter.
4
This automatically updates all existing users of the function.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-23-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 1 +
12
target/arm/helper.c | 14 +++++++++++---
13
2 files changed, 12 insertions(+), 3 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
20
unsigned tsz : 8;
21
unsigned select : 1;
22
bool tbi : 1;
23
+ bool tbid : 1;
24
bool epd : 1;
25
bool hpd : 1;
26
bool using16k : 1;
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
30
+++ b/target/arm/helper.c
31
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
32
{
33
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
34
uint32_t el = regime_el(env, mmu_idx);
35
- bool tbi, epd, hpd, using16k, using64k;
36
+ bool tbi, tbid, epd, hpd, using16k, using64k;
37
int select, tsz;
38
39
/*
40
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
41
using16k = extract32(tcr, 15, 1);
42
if (mmu_idx == ARMMMUIdx_S2NS) {
43
/* VTCR_EL2 */
44
- tbi = hpd = false;
45
+ tbi = tbid = hpd = false;
46
} else {
47
tbi = extract32(tcr, 20, 1);
48
hpd = extract32(tcr, 24, 1);
49
+ tbid = extract32(tcr, 29, 1);
50
}
51
epd = false;
52
} else if (!select) {
53
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
54
using16k = extract32(tcr, 15, 1);
55
tbi = extract64(tcr, 37, 1);
56
hpd = extract64(tcr, 41, 1);
57
+ tbid = extract64(tcr, 51, 1);
58
} else {
59
int tg = extract32(tcr, 30, 2);
60
using16k = tg == 1;
61
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
62
epd = extract32(tcr, 23, 1);
63
tbi = extract64(tcr, 38, 1);
64
hpd = extract64(tcr, 42, 1);
65
+ tbid = extract64(tcr, 52, 1);
66
}
67
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
68
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
70
.tsz = tsz,
71
.select = select,
72
.tbi = tbi,
73
+ .tbid = tbid,
74
.epd = epd,
75
.hpd = hpd,
76
.using16k = using16k,
77
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
78
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
ARMMMUIdx mmu_idx, bool data)
80
{
81
- return aa64_va_parameters_both(env, va, mmu_idx);
82
+ ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
83
+
84
+ /* Present TBI as a composite with TBID. */
85
+ ret.tbi &= (data || !ret.tbid);
86
+ return ret;
87
}
88
89
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
90
--
91
2.20.1
92
93
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Stripping out the authentication data does not require any crypto,
4
it merely requires the virtual address parameters.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-25-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 14 +++++++++++++-
12
1 file changed, 13 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
19
g_assert_not_reached(); /* FIXME */
20
}
21
22
+static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
23
+{
24
+ uint64_t extfield = -param.select;
25
+ int bot_pac_bit = 64 - param.tsz;
26
+ int top_pac_bit = 64 - 8 * param.tbi;
27
+
28
+ return deposit64(ptr, bot_pac_bit, top_pac_bit - bot_pac_bit, extfield);
29
+}
30
+
31
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
32
ARMPACKey *key, bool data, int keynumber)
33
{
34
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
35
36
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
37
{
38
- g_assert_not_reached(); /* FIXME */
39
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
40
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
41
+
42
+ return pauth_original_ptr(ptr, param);
43
}
44
45
static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is not really functional yet, because the crypto is not yet
4
implemented. This, however follows the Auth pseudo function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-26-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 21 ++++++++++++++++++++-
12
1 file changed, 20 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
19
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
20
ARMPACKey *key, bool data, int keynumber)
21
{
22
- g_assert_not_reached(); /* FIXME */
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
25
+ int bot_bit, top_bit;
26
+ uint64_t pac, orig_ptr, test;
27
+
28
+ orig_ptr = pauth_original_ptr(ptr, param);
29
+ pac = pauth_computepac(orig_ptr, modifier, *key);
30
+ bot_bit = 64 - param.tsz;
31
+ top_bit = 64 - 8 * param.tbi;
32
+
33
+ test = (pac ^ ptr) & ~MAKE_64BIT_MASK(55, 1);
34
+ if (unlikely(extract64(test, bot_bit, top_bit - bot_bit))) {
35
+ int error_code = (keynumber << 1) | (keynumber ^ 1);
36
+ if (param.tbi) {
37
+ return deposit64(ptr, 53, 2, error_code);
38
+ } else {
39
+ return deposit64(ptr, 61, 2, error_code);
40
+ }
41
+ }
42
+ return orig_ptr;
43
}
44
45
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is not really functional yet, because the crypto is not yet
4
implemented. This, however follows the AddPAC pseudo function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-27-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 42 ++++++++++++++++++++++++++++++++++++++-
12
1 file changed, 41 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
19
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
20
ARMPACKey *key, bool data)
21
{
22
- g_assert_not_reached(); /* FIXME */
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
25
+ uint64_t pac, ext_ptr, ext, test;
26
+ int bot_bit, top_bit;
27
+
28
+ /* If tagged pointers are in use, use ptr<55>, otherwise ptr<63>. */
29
+ if (param.tbi) {
30
+ ext = sextract64(ptr, 55, 1);
31
+ } else {
32
+ ext = sextract64(ptr, 63, 1);
33
+ }
34
+
35
+ /* Build a pointer with known good extension bits. */
36
+ top_bit = 64 - 8 * param.tbi;
37
+ bot_bit = 64 - param.tsz;
38
+ ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext);
39
+
40
+ pac = pauth_computepac(ext_ptr, modifier, *key);
41
+
42
+ /*
43
+ * Check if the ptr has good extension bits and corrupt the
44
+ * pointer authentication code if not.
45
+ */
46
+ test = sextract64(ptr, bot_bit, top_bit - bot_bit);
47
+ if (test != 0 && test != -1) {
48
+ pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
49
+ }
50
+
51
+ /*
52
+ * Preserve the determination between upper and lower at bit 55,
53
+ * and insert pointer authentication code.
54
+ */
55
+ if (param.tbi) {
56
+ ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
57
+ pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
58
+ } else {
59
+ ptr &= MAKE_64BIT_MASK(0, bot_bit);
60
+ pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
61
+ }
62
+ ext &= MAKE_64BIT_MASK(55, 1);
63
+ return pac | ext | ptr;
64
}
65
66
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is the main crypto routine, an implementation of QARMA.
4
This matches, as much as possible, ARM pseudocode.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-28-richard.henderson@linaro.org
9
[PMM: fixed minor checkpatch nits]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/pauth_helper.c | 242 +++++++++++++++++++++++++++++++++++++-
13
1 file changed, 241 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/pauth_helper.c
18
+++ b/target/arm/pauth_helper.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "tcg/tcg-gvec-desc.h"
21
22
23
+static uint64_t pac_cell_shuffle(uint64_t i)
24
+{
25
+ uint64_t o = 0;
26
+
27
+ o |= extract64(i, 52, 4);
28
+ o |= extract64(i, 24, 4) << 4;
29
+ o |= extract64(i, 44, 4) << 8;
30
+ o |= extract64(i, 0, 4) << 12;
31
+
32
+ o |= extract64(i, 28, 4) << 16;
33
+ o |= extract64(i, 48, 4) << 20;
34
+ o |= extract64(i, 4, 4) << 24;
35
+ o |= extract64(i, 40, 4) << 28;
36
+
37
+ o |= extract64(i, 32, 4) << 32;
38
+ o |= extract64(i, 12, 4) << 36;
39
+ o |= extract64(i, 56, 4) << 40;
40
+ o |= extract64(i, 20, 4) << 44;
41
+
42
+ o |= extract64(i, 8, 4) << 48;
43
+ o |= extract64(i, 36, 4) << 52;
44
+ o |= extract64(i, 16, 4) << 56;
45
+ o |= extract64(i, 60, 4) << 60;
46
+
47
+ return o;
48
+}
49
+
50
+static uint64_t pac_cell_inv_shuffle(uint64_t i)
51
+{
52
+ uint64_t o = 0;
53
+
54
+ o |= extract64(i, 12, 4);
55
+ o |= extract64(i, 24, 4) << 4;
56
+ o |= extract64(i, 48, 4) << 8;
57
+ o |= extract64(i, 36, 4) << 12;
58
+
59
+ o |= extract64(i, 56, 4) << 16;
60
+ o |= extract64(i, 44, 4) << 20;
61
+ o |= extract64(i, 4, 4) << 24;
62
+ o |= extract64(i, 16, 4) << 28;
63
+
64
+ o |= i & MAKE_64BIT_MASK(32, 4);
65
+ o |= extract64(i, 52, 4) << 36;
66
+ o |= extract64(i, 28, 4) << 40;
67
+ o |= extract64(i, 8, 4) << 44;
68
+
69
+ o |= extract64(i, 20, 4) << 48;
70
+ o |= extract64(i, 0, 4) << 52;
71
+ o |= extract64(i, 40, 4) << 56;
72
+ o |= i & MAKE_64BIT_MASK(60, 4);
73
+
74
+ return o;
75
+}
76
+
77
+static uint64_t pac_sub(uint64_t i)
78
+{
79
+ static const uint8_t sub[16] = {
80
+ 0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
81
+ 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa,
82
+ };
83
+ uint64_t o = 0;
84
+ int b;
85
+
86
+ for (b = 0; b < 64; b += 16) {
87
+ o |= (uint64_t)sub[(i >> b) & 0xf] << b;
88
+ }
89
+ return o;
90
+}
91
+
92
+static uint64_t pac_inv_sub(uint64_t i)
93
+{
94
+ static const uint8_t inv_sub[16] = {
95
+ 0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
96
+ 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3,
97
+ };
98
+ uint64_t o = 0;
99
+ int b;
100
+
101
+ for (b = 0; b < 64; b += 16) {
102
+ o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
103
+ }
104
+ return o;
105
+}
106
+
107
+static int rot_cell(int cell, int n)
108
+{
109
+ /* 4-bit rotate left by n. */
110
+ cell |= cell << 4;
111
+ return extract32(cell, 4 - n, 4);
112
+}
113
+
114
+static uint64_t pac_mult(uint64_t i)
115
+{
116
+ uint64_t o = 0;
117
+ int b;
118
+
119
+ for (b = 0; b < 4 * 4; b += 4) {
120
+ int i0, i4, i8, ic, t0, t1, t2, t3;
121
+
122
+ i0 = extract64(i, b, 4);
123
+ i4 = extract64(i, b + 4 * 4, 4);
124
+ i8 = extract64(i, b + 8 * 4, 4);
125
+ ic = extract64(i, b + 12 * 4, 4);
126
+
127
+ t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1);
128
+ t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2);
129
+ t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1);
130
+ t3 = rot_cell(ic, 1) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1);
131
+
132
+ o |= (uint64_t)t3 << b;
133
+ o |= (uint64_t)t2 << (b + 4 * 4);
134
+ o |= (uint64_t)t1 << (b + 8 * 4);
135
+ o |= (uint64_t)t0 << (b + 12 * 4);
136
+ }
137
+ return o;
138
+}
139
+
140
+static uint64_t tweak_cell_rot(uint64_t cell)
141
+{
142
+ return (cell >> 1) | (((cell ^ (cell >> 1)) & 1) << 3);
143
+}
144
+
145
+static uint64_t tweak_shuffle(uint64_t i)
146
+{
147
+ uint64_t o = 0;
148
+
149
+ o |= extract64(i, 16, 4) << 0;
150
+ o |= extract64(i, 20, 4) << 4;
151
+ o |= tweak_cell_rot(extract64(i, 24, 4)) << 8;
152
+ o |= extract64(i, 28, 4) << 12;
153
+
154
+ o |= tweak_cell_rot(extract64(i, 44, 4)) << 16;
155
+ o |= extract64(i, 8, 4) << 20;
156
+ o |= extract64(i, 12, 4) << 24;
157
+ o |= tweak_cell_rot(extract64(i, 32, 4)) << 28;
158
+
159
+ o |= extract64(i, 48, 4) << 32;
160
+ o |= extract64(i, 52, 4) << 36;
161
+ o |= extract64(i, 56, 4) << 40;
162
+ o |= tweak_cell_rot(extract64(i, 60, 4)) << 44;
163
+
164
+ o |= tweak_cell_rot(extract64(i, 0, 4)) << 48;
165
+ o |= extract64(i, 4, 4) << 52;
166
+ o |= tweak_cell_rot(extract64(i, 40, 4)) << 56;
167
+ o |= tweak_cell_rot(extract64(i, 36, 4)) << 60;
168
+
169
+ return o;
170
+}
171
+
172
+static uint64_t tweak_cell_inv_rot(uint64_t cell)
173
+{
174
+ return ((cell << 1) & 0xf) | ((cell & 1) ^ (cell >> 3));
175
+}
176
+
177
+static uint64_t tweak_inv_shuffle(uint64_t i)
178
+{
179
+ uint64_t o = 0;
180
+
181
+ o |= tweak_cell_inv_rot(extract64(i, 48, 4));
182
+ o |= extract64(i, 52, 4) << 4;
183
+ o |= extract64(i, 20, 4) << 8;
184
+ o |= extract64(i, 24, 4) << 12;
185
+
186
+ o |= extract64(i, 0, 4) << 16;
187
+ o |= extract64(i, 4, 4) << 20;
188
+ o |= tweak_cell_inv_rot(extract64(i, 8, 4)) << 24;
189
+ o |= extract64(i, 12, 4) << 28;
190
+
191
+ o |= tweak_cell_inv_rot(extract64(i, 28, 4)) << 32;
192
+ o |= tweak_cell_inv_rot(extract64(i, 60, 4)) << 36;
193
+ o |= tweak_cell_inv_rot(extract64(i, 56, 4)) << 40;
194
+ o |= tweak_cell_inv_rot(extract64(i, 16, 4)) << 44;
195
+
196
+ o |= extract64(i, 32, 4) << 48;
197
+ o |= extract64(i, 36, 4) << 52;
198
+ o |= extract64(i, 40, 4) << 56;
199
+ o |= tweak_cell_inv_rot(extract64(i, 44, 4)) << 60;
200
+
201
+ return o;
202
+}
203
+
204
static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
205
ARMPACKey key)
206
{
207
- g_assert_not_reached(); /* FIXME */
208
+ static const uint64_t RC[5] = {
209
+ 0x0000000000000000ull,
210
+ 0x13198A2E03707344ull,
211
+ 0xA4093822299F31D0ull,
212
+ 0x082EFA98EC4E6C89ull,
213
+ 0x452821E638D01377ull,
214
+ };
215
+ const uint64_t alpha = 0xC0AC29B7C97C50DDull;
216
+ /*
217
+ * Note that in the ARM pseudocode, key0 contains bits <127:64>
218
+ * and key1 contains bits <63:0> of the 128-bit key.
219
+ */
220
+ uint64_t key0 = key.hi, key1 = key.lo;
221
+ uint64_t workingval, runningmod, roundkey, modk0;
222
+ int i;
223
+
224
+ modk0 = (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63));
225
+ runningmod = modifier;
226
+ workingval = data ^ key0;
227
+
228
+ for (i = 0; i <= 4; ++i) {
229
+ roundkey = key1 ^ runningmod;
230
+ workingval ^= roundkey;
231
+ workingval ^= RC[i];
232
+ if (i > 0) {
233
+ workingval = pac_cell_shuffle(workingval);
234
+ workingval = pac_mult(workingval);
235
+ }
236
+ workingval = pac_sub(workingval);
237
+ runningmod = tweak_shuffle(runningmod);
238
+ }
239
+ roundkey = modk0 ^ runningmod;
240
+ workingval ^= roundkey;
241
+ workingval = pac_cell_shuffle(workingval);
242
+ workingval = pac_mult(workingval);
243
+ workingval = pac_sub(workingval);
244
+ workingval = pac_cell_shuffle(workingval);
245
+ workingval = pac_mult(workingval);
246
+ workingval ^= key1;
247
+ workingval = pac_cell_inv_shuffle(workingval);
248
+ workingval = pac_inv_sub(workingval);
249
+ workingval = pac_mult(workingval);
250
+ workingval = pac_cell_inv_shuffle(workingval);
251
+ workingval ^= key0;
252
+ workingval ^= runningmod;
253
+ for (i = 0; i <= 4; ++i) {
254
+ workingval = pac_inv_sub(workingval);
255
+ if (i < 4) {
256
+ workingval = pac_mult(workingval);
257
+ workingval = pac_cell_inv_shuffle(workingval);
258
+ }
259
+ runningmod = tweak_inv_shuffle(runningmod);
260
+ roundkey = key1 ^ runningmod;
261
+ workingval ^= RC[4 - i];
262
+ workingval ^= roundkey;
263
+ workingval ^= alpha;
264
+ }
265
+ workingval ^= modk0;
266
+
267
+ return workingval;
268
}
269
270
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
271
--
272
2.20.1
273
274
diff view generated by jsdifflib