xref: /kvm-unit-tests/lib/arm/asm/gic-v3.h (revision a5a2d35cba2e4b99ef5dfa77d220a28a7d0159cd)
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_RWP			(1U << 31)
22 #define GICD_CTLR_ARE_NS		(1U << 4)
23 #define GICD_CTLR_ENABLE_G1A		(1U << 1)
24 #define GICD_CTLR_ENABLE_G1		(1U << 0)
25 
26 /* Re-Distributor registers, offsets from RD_base */
27 #define GICR_TYPER			0x0008
28 
29 #define GICR_TYPER_LAST			(1U << 4)
30 
31 /* Re-Distributor registers, offsets from SGI_base */
32 #define GICR_IGROUPR0			GICD_IGROUPR
33 #define GICR_ISENABLER0			GICD_ISENABLER
34 #define GICR_IPRIORITYR0		GICD_IPRIORITYR
35 
36 #define ICC_SGI1R_AFFINITY_1_SHIFT	16
37 #define ICC_SGI1R_AFFINITY_2_SHIFT	32
38 #define ICC_SGI1R_AFFINITY_3_SHIFT	48
39 #define MPIDR_TO_SGI_AFFINITY(cluster_id, level) \
40 	(MPIDR_AFFINITY_LEVEL(cluster_id, level) << ICC_SGI1R_AFFINITY_## level ## _SHIFT)
41 
42 #include <asm/arch_gicv3.h>
43 
44 #ifndef __ASSEMBLY__
45 #include <asm/setup.h>
46 #include <asm/processor.h>
47 #include <asm/delay.h>
48 #include <asm/cpumask.h>
49 #include <asm/smp.h>
50 #include <asm/io.h>
51 
52 #define GICV3_NR_REDISTS 8
53 
54 struct gicv3_data {
55 	void *dist_base;
56 	void *redist_bases[GICV3_NR_REDISTS];
57 	void *redist_base[NR_CPUS];
58 	unsigned int irq_nr;
59 };
60 extern struct gicv3_data gicv3_data;
61 
62 #define gicv3_dist_base()		(gicv3_data.dist_base)
63 #define gicv3_redist_base()		(gicv3_data.redist_base[smp_processor_id()])
64 #define gicv3_sgi_base()		(gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
65 
66 extern int gicv3_init(void);
67 extern void gicv3_enable_defaults(void);
68 extern u32 gicv3_read_iar(void);
69 extern u32 gicv3_iar_irqnr(u32 iar);
70 extern void gicv3_write_eoir(u32 irqstat);
71 extern void gicv3_ipi_send_single(int irq, int cpu);
72 extern void gicv3_ipi_send_mask(int irq, const cpumask_t *dest);
73 extern void gicv3_set_redist_base(size_t stride);
74 
75 static inline void gicv3_do_wait_for_rwp(void *base)
76 {
77 	int count = 100000;	/* 1s */
78 
79 	while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) {
80 		if (!--count) {
81 			printf("GICv3: RWP timeout!\n");
82 			abort();
83 		}
84 		cpu_relax();
85 		udelay(10);
86 	};
87 }
88 
89 static inline void gicv3_dist_wait_for_rwp(void)
90 {
91 	gicv3_do_wait_for_rwp(gicv3_dist_base());
92 }
93 
94 static inline void gicv3_redist_wait_for_uwp(void)
95 {
96 	/*
97 	 * We can build on gic_do_wait_for_rwp, which uses GICD_ registers
98 	 * because GICD_CTLR == GICR_CTLR and GICD_CTLR_RWP == GICR_CTLR_UWP
99 	 */
100 	gicv3_do_wait_for_rwp(gicv3_redist_base());
101 }
102 
103 static inline u32 mpidr_compress(u64 mpidr)
104 {
105 	u64 compressed = mpidr & MPIDR_HWID_BITMASK;
106 
107 	compressed = (((compressed >> 32) & 0xff) << 24) | compressed;
108 	return compressed;
109 }
110 
111 static inline u64 mpidr_uncompress(u32 compressed)
112 {
113 	u64 mpidr = ((u64)compressed >> 24) << 32;
114 
115 	mpidr |= compressed & MPIDR_HWID_BITMASK;
116 	return mpidr;
117 }
118 
119 #endif /* !__ASSEMBLY__ */
120 #endif /* _ASMARM_GIC_V3_H_ */
121