1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __SELFTESTS_GIC_V5_H
#define __SELFTESTS_GIC_V5_H
#include <asm/barrier.h>
#include <asm/sysreg.h>
#include <linux/bitfield.h>
#include "processor.h"
/* GIC component base address is guest PA space */
#define GICV5_IRS_CONFIG_BASE_GPA 0x8000000ULL
#define GICV5_IRS_CONFIG_BASE_GVA ((volatile void *)GICV5_IRS_CONFIG_BASE_GPA)
#define GICV5_IRS_SIZE 0x20000
#define GICV5_IRS_ALIGN 0x10000
/*
* IRS register offsets. Keep this selftest copy scoped to the offsets and
* fields exercised by the userspace API tests.
*/
#define GICV5_IRS_IDR0 0x0000
#define GICV5_IRS_IDR1 0x0004
#define GICV5_IRS_IDR2 0x0008
#define GICV5_IRS_IDR3 0x000c
#define GICV5_IRS_IDR4 0x0010
#define GICV5_IRS_IDR5 0x0014
#define GICV5_IRS_IDR6 0x0018
#define GICV5_IRS_IDR7 0x001c
#define GICV5_IRS_IIDR 0x0040
#define GICV5_IRS_AIDR 0x0044
#define GICV5_IRS_CR0 0x0080
#define GICV5_IRS_CR1 0x0084
#define GICV5_IRS_SYNCR 0x00c0
#define GICV5_IRS_SYNC_STATUSR 0x00c4
#define GICV5_IRS_SPI_VMR 0x0100
#define GICV5_IRS_SPI_SELR 0x0108
#define GICV5_IRS_SPI_DOMAINR 0x010c
#define GICV5_IRS_SPI_RESAMPLER 0x0110
#define GICV5_IRS_SPI_CFGR 0x0114
#define GICV5_IRS_SPI_STATUSR 0x0118
#define GICV5_IRS_PE_SELR 0x0140
#define GICV5_IRS_PE_STATUSR 0x0144
#define GICV5_IRS_PE_CR0 0x0148
#define GICV5_IRS_IST_BASER 0x0180
#define GICV5_IRS_IST_CFGR 0x0190
#define GICV5_IRS_IST_STATUSR 0x0194
#define GICV5_IRS_MAP_L2_ISTR 0x01c0
#define GICV5_IRS_VMT_BASER 0x0200
#define GICV5_IRS_VMT_CFGR 0x0210
#define GICV5_IRS_VMT_STATUSR 0x0214
#define GICV5_IRS_VPE_SELR 0x0240
#define GICV5_IRS_VPE_DBR 0x0248
#define GICV5_IRS_VPE_HPPIR 0x0250
#define GICV5_IRS_VPE_CR0 0x0258
#define GICV5_IRS_VPE_STATUSR 0x025c
#define GICV5_IRS_VM_DBR 0x0280
#define GICV5_IRS_VM_SELR 0x0288
#define GICV5_IRS_VM_STATUSR 0x028c
#define GICV5_IRS_VMAP_L2_VMTR 0x02c0
#define GICV5_IRS_VMAP_VMR 0x02c8
#define GICV5_IRS_VMAP_VISTR 0x02d0
#define GICV5_IRS_VMAP_L2_VISTR 0x02d8
#define GICV5_IRS_VMAP_VPER 0x02e0
#define GICV5_IRS_SAVE_VMR 0x0300
#define GICV5_IRS_SAVE_VM_STATUSR 0x0308
#define GICV5_IRS_MEC_IDR 0x0340
#define GICV5_IRS_MEC_MECID_R 0x0344
#define GICV5_IRS_MPAM_IDR 0x0380
#define GICV5_IRS_MPAM_PARTID_R 0x0384
#define GICV5_IRS_SWERR_STATUSR 0x03c0
#define GICV5_IRS_SWERR_SYNDROMER0 0x03c8
#define GICV5_IRS_SWERR_SYNDROMER1 0x03d0
#define GICV5_IRS_IDR0_SETLPI BIT(9)
#define GICV5_IRS_IDR0_INT_DOM GENMASK(1, 0)
#define GICV5_IRS_IDR0_INT_DOM_SECURE 0b00
#define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20)
#define GICV5_IRS_IDR2_ISTMD_SZ GENMASK(19, 15)
#define GICV5_IRS_IDR2_ISTMD BIT(14)
#define GICV5_IRS_IDR2_IST_L2SZ GENMASK(13, 11)
#define GICV5_IRS_IDR2_IST_LEVELS BIT(10)
#define GICV5_IRS_IDR2_MIN_LPI_ID_BITS GENMASK(9, 6)
#define GICV5_IRS_IDR2_LPI BIT(5)
#define GICV5_IRS_IDR2_ID_BITS GENMASK(4, 0)
#define GICV5_IRS_CR0_IDLE BIT(1)
#define GICV5_IRS_CR0_IRSEN BIT(0)
#define GICV5_IRS_SPI_SELR_ID GENMASK(23, 0)
#define GICV5_IRS_SPI_CFGR_TM BIT(0)
#define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0)
#define GICV5_IRS_SPI_STATUSR_IDLE BIT(0)
#define GICV5_IRS_PE_STATUSR_IDLE BIT(0)
#define GICV5_IRS_IST_STATUSR_IDLE BIT(0)
#define GICV5_IRS_IST_BASER_ADDR_MASK GENMASK_ULL(55, 6)
#define GICV5_IRS_IST_BASER_VALID BIT_ULL(0)
#define GICV5_IRS_IST_BASER_ADDR_SHIFT 6ULL
#define GICV5_IRS_IST_CFGR_STRUCTURE BIT(16)
#define GICV5_IRS_IST_CFGR_ISTSZ GENMASK(8, 7)
#define GICV5_IRS_IST_CFGR_L2SZ GENMASK(6, 5)
#define GICV5_IRS_IST_CFGR_LPI_ID_BITS GENMASK(4, 0)
#define GICV5_IRS_IST_CFGR_ISTSZ_4 0b00
#define GICV5_IRS_IST_CFGR_ISTSZ_8 0b01
#define GICV5_IRS_IST_CFGR_ISTSZ_16 0b10
/*
* Definitions for GICv5 instructions for the Current Domain
*/
#define GICV5_OP_GIC_CDAFF sys_insn(1, 0, 12, 1, 3)
#define GICV5_OP_GIC_CDDI sys_insn(1, 0, 12, 2, 0)
#define GICV5_OP_GIC_CDDIS sys_insn(1, 0, 12, 1, 0)
#define GICV5_OP_GIC_CDHM sys_insn(1, 0, 12, 2, 1)
#define GICV5_OP_GIC_CDEN sys_insn(1, 0, 12, 1, 1)
#define GICV5_OP_GIC_CDEOI sys_insn(1, 0, 12, 1, 7)
#define GICV5_OP_GIC_CDPEND sys_insn(1, 0, 12, 1, 4)
#define GICV5_OP_GIC_CDPRI sys_insn(1, 0, 12, 1, 2)
#define GICV5_OP_GIC_CDRCFG sys_insn(1, 0, 12, 1, 5)
#define GICV5_OP_GICR_CDIA sys_insn(1, 0, 12, 3, 0)
#define GICV5_OP_GICR_CDNMIA sys_insn(1, 0, 12, 3, 1)
/* Definitions for GIC CDAFF */
#define GICV5_GIC_CDAFF_IAFFID_MASK GENMASK_ULL(47, 32)
#define GICV5_GIC_CDAFF_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDAFF_IRM_MASK BIT_ULL(28)
#define GICV5_GIC_CDAFF_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDDI */
#define GICV5_GIC_CDDI_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDDI_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDDIS */
#define GICV5_GIC_CDDIS_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDDIS_TYPE(r) FIELD_GET(GICV5_GIC_CDDIS_TYPE_MASK, r)
#define GICV5_GIC_CDDIS_ID_MASK GENMASK_ULL(23, 0)
#define GICV5_GIC_CDDIS_ID(r) FIELD_GET(GICV5_GIC_CDDIS_ID_MASK, r)
/* Definitions for GIC CDEN */
#define GICV5_GIC_CDEN_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDEN_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDHM */
#define GICV5_GIC_CDHM_HM_MASK BIT_ULL(32)
#define GICV5_GIC_CDHM_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDHM_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDPEND */
#define GICV5_GIC_CDPEND_PENDING_MASK BIT_ULL(32)
#define GICV5_GIC_CDPEND_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDPEND_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDPRI */
#define GICV5_GIC_CDPRI_PRIORITY_MASK GENMASK_ULL(39, 35)
#define GICV5_GIC_CDPRI_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDPRI_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GIC CDRCFG */
#define GICV5_GIC_CDRCFG_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GIC_CDRCFG_ID_MASK GENMASK_ULL(23, 0)
/* Definitions for GICR CDIA */
#define GICV5_GICR_CDIA_VALID_MASK BIT_ULL(32)
#define GICV5_GICR_CDIA_VALID(r) FIELD_GET(GICV5_GICR_CDIA_VALID_MASK, r)
#define GICV5_GICR_CDIA_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GICR_CDIA_ID_MASK GENMASK_ULL(23, 0)
#define GICV5_GICR_CDIA_INTID GENMASK_ULL(31, 0)
/* Definitions for GICR CDNMIA */
#define GICV5_GICR_CDNMIA_VALID_MASK BIT_ULL(32)
#define GICV5_GICR_CDNMIA_VALID(r) FIELD_GET(GICV5_GICR_CDNMIA_VALID_MASK, r)
#define GICV5_GICR_CDNMIA_TYPE_MASK GENMASK_ULL(31, 29)
#define GICV5_GICR_CDNMIA_ID_MASK GENMASK_ULL(23, 0)
#define GICV5_HWIRQ_TYPE GENMASK_ULL(31, 29)
#define GICV5_HWIRQ_ID GENMASK_ULL(23, 0)
#define GICV5_HWIRQ_TYPE_LPI 0x2
#define GICV5_HWIRQ_TYPE_SPI 0x3
#define gicr_insn(insn) read_sysreg_s(GICV5_OP_GICR_##insn)
#define gic_insn(v, insn) write_sysreg_s(v, GICV5_OP_GIC_##insn)
#define __GIC_BARRIER_INSN(op0, op1, CRn, CRm, op2, Rt) \
__emit_inst(0xd5000000 | \
sys_insn((op0), (op1), (CRn), (CRm), (op2)) | \
((Rt) & 0x1f))
#define GSB_SYS_BARRIER_INSN __GIC_BARRIER_INSN(1, 0, 12, 0, 0, 31)
#define GSB_ACK_BARRIER_INSN __GIC_BARRIER_INSN(1, 0, 12, 0, 1, 31)
#define gsb_ack() asm volatile(GSB_ACK_BARRIER_INSN : : : "memory")
#define gsb_sys() asm volatile(GSB_SYS_BARRIER_INSN : : : "memory")
#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
#define GICV5_IRQ_DEFAULT_PRI 0b10000
#define GICV5_ARCH_PPI_SW_PPI 0x3
void gicv5_ppi_priority_init(void)
{
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR0_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR1_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR2_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR3_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR4_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR5_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR6_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR7_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR8_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR9_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR10_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR11_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR12_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR13_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR14_EL1);
write_sysreg_s(REPEAT_BYTE(GICV5_IRQ_DEFAULT_PRI), SYS_ICC_PPI_PRIORITYR15_EL1);
/*
* Context syncronization required to make sure system register writes
* effects are synchronised.
*/
isb();
}
void gicv5_cpu_disable_interrupts(void)
{
u64 cr0;
cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 0);
write_sysreg_s(cr0, SYS_ICC_CR0_EL1);
}
void gicv5_cpu_enable_interrupts(void)
{
u64 cr0, pcr;
write_sysreg_s(0, SYS_ICC_PPI_ENABLER0_EL1);
write_sysreg_s(0, SYS_ICC_PPI_ENABLER1_EL1);
gicv5_ppi_priority_init();
pcr = FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_DEFAULT_PRI);
write_sysreg_s(pcr, SYS_ICC_PCR_EL1);
cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 1);
write_sysreg_s(cr0, SYS_ICC_CR0_EL1);
}
#endif
|