xref: /kvm-unit-tests/lib/arm/asm/gic-v3.h (revision 80374e12c3efa647e186efc4f5573669951c4f11)
1 /*
2  * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h
3  *
4  * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
5  *
6  * This work is licensed under the terms of the GNU LGPL, version 2.
7  */
8 #ifndef _ASMARM_GIC_V3_H_
9 #define _ASMARM_GIC_V3_H_
10 
11 #ifndef _ASMARM_GIC_H_
12 #error Do not directly include <asm/gic-v3.h>. Include <asm/gic.h>
13 #endif
14 
15 /*
16  * Distributor registers
17  *
18  * We expect to be run in Non-secure mode, thus we define the
19  * group1 enable bits with respect to that view.
20  */
21 #define GICD_CTLR			0x0000
22 #define GICD_CTLR_RWP			(1U << 31)
23 #define GICD_CTLR_ARE_NS		(1U << 4)
24 #define GICD_CTLR_ENABLE_G1A		(1U << 1)
25 #define GICD_CTLR_ENABLE_G1		(1U << 0)
26 
27 /* Re-Distributor registers, offsets from RD_base */
28 #define GICR_TYPER			0x0008
29 
30 #define GICR_TYPER_LAST			(1U << 4)
31 
32 /* Re-Distributor registers, offsets from SGI_base */
33 #define GICR_IGROUPR0			GICD_IGROUPR
34 #define GICR_ISENABLER0			GICD_ISENABLER
35 #define GICR_ICENABLER0			GICD_ICENABLER
36 #define GICR_ISPENDR0			GICD_ISPENDR
37 #define GICR_ICPENDR0			GICD_ICPENDR
38 #define GICR_ISACTIVER0			GICD_ISACTIVER
39 #define GICR_ICACTIVER0			GICD_ICACTIVER
40 #define GICR_IPRIORITYR0		GICD_IPRIORITYR
41 
42 #define GICR_PROPBASER			0x0070
43 #define GICR_PENDBASER			0x0078
44 #define GICR_CTLR			GICD_CTLR
45 #define GICR_CTLR_ENABLE_LPIS		(1UL << 0)
46 
47 #define ICC_SGI1R_AFFINITY_1_SHIFT	16
48 #define ICC_SGI1R_AFFINITY_2_SHIFT	32
49 #define ICC_SGI1R_AFFINITY_3_SHIFT	48
50 #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) \
51 	(MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT)
52 
53 #define GICR_PENDBASER_PTZ		BIT_ULL(62)
54 
55 #define LPI_PROP_GROUP1			(1 << 1)
56 #define LPI_PROP_ENABLED		(1 << 0)
57 #define LPI_PROP_DEFAULT_PRIO		0xa0
58 #define LPI_PROP_DEFAULT		(LPI_PROP_DEFAULT_PRIO | LPI_PROP_GROUP1 | LPI_PROP_ENABLED)
59 
60 #define LPI_ID_BASE			8192
61 #define LPI(lpi)			((lpi) + LPI_ID_BASE)
62 #define LPI_OFFSET(intid)		((intid) - LPI_ID_BASE)
63 
64 #include <asm/arch_gicv3.h>
65 
66 #ifndef __ASSEMBLY__
67 #include <asm/setup.h>
68 #include <asm/processor.h>
69 #include <asm/delay.h>
70 #include <asm/cpumask.h>
71 #include <asm/smp.h>
72 #include <asm/io.h>
73 
74 #define GICV3_NR_REDISTS 8
75 
76 struct gicv3_data {
77 	void *dist_base;
78 	void *redist_bases[GICV3_NR_REDISTS];
79 	void *redist_base[NR_CPUS];
80 	u8 *lpi_prop;
81 	void *lpi_pend[NR_CPUS];
82 	unsigned int irq_nr;
83 };
84 extern struct gicv3_data gicv3_data;
85 
86 #define gicv3_dist_base()		(gicv3_data.dist_base)
87 #define gicv3_redist_base()		(gicv3_data.redist_base[smp_processor_id()])
88 #define gicv3_sgi_base()		(gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
89 
90 extern int gicv3_init(void);
91 extern void gicv3_enable_defaults(void);
92 extern u32 gicv3_read_iar(void);
93 extern u32 gicv3_iar_irqnr(u32 iar);
94 extern void gicv3_write_eoir(u32 irqstat);
95 extern void gicv3_ipi_send_single(int irq, int cpu);
96 extern void gicv3_ipi_send_mask(int irq, const cpumask_t *dest);
97 extern void gicv3_set_redist_base(size_t stride);
98 extern void gicv3_lpi_set_clr_pending(int rdist, int n, bool set);
99 extern void gicv3_lpi_alloc_tables(void);
100 extern void gicv3_lpi_rdist_enable(int redist);
101 extern void gicv3_lpi_rdist_disable(int redist);
102 
103 static inline void gicv3_do_wait_for_rwp(void *base)
104 {
105 	int count = 100000;	/* 1s */
106 
107 	while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) {
108 		if (!--count) {
109 			printf("GICv3: RWP timeout!\n");
110 			abort();
111 		}
112 		cpu_relax();
113 		udelay(10);
114 	};
115 }
116 
117 static inline void gicv3_dist_wait_for_rwp(void)
118 {
119 	gicv3_do_wait_for_rwp(gicv3_dist_base());
120 }
121 
122 static inline void gicv3_redist_wait_for_uwp(void)
123 {
124 	/*
125 	 * We can build on gic_do_wait_for_rwp, which uses GICD_ registers
126 	 * because GICD_CTLR == GICR_CTLR and GICD_CTLR_RWP == GICR_CTLR_UWP
127 	 */
128 	gicv3_do_wait_for_rwp(gicv3_redist_base());
129 }
130 
131 static inline u32 mpidr_compress(u64 mpidr)
132 {
133 	u64 compressed = mpidr & MPIDR_HWID_BITMASK;
134 
135 	compressed = (((compressed >> 32) & 0xff) << 24) | compressed;
136 	return compressed;
137 }
138 
139 static inline u64 mpidr_uncompress(u32 compressed)
140 {
141 	u64 mpidr = ((u64)compressed >> 24) << 32;
142 
143 	mpidr |= compressed & MPIDR_HWID_BITMASK;
144 	return mpidr;
145 }
146 
147 #define gicv3_lpi_set_config(intid, value) ({		\
148 	gicv3_data.lpi_prop[LPI_OFFSET(intid)] = value;	\
149 })
150 
151 #define gicv3_lpi_get_config(intid) (gicv3_data.lpi_prop[LPI_OFFSET(intid)])
152 
153 #endif /* !__ASSEMBLY__ */
154 #endif /* _ASMARM_GIC_V3_H_ */
155