xref: /kvm-unit-tests/lib/arm/asm/gic-v3.h (revision 91a6c3cead72494724d563c19c6aebd2efd14d4e)
1*91a6c3ceSAndrew Jones /*
2*91a6c3ceSAndrew Jones  * All GIC* defines are lifted from include/linux/irqchip/arm-gic-v3.h
3*91a6c3ceSAndrew Jones  *
4*91a6c3ceSAndrew Jones  * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
5*91a6c3ceSAndrew Jones  *
6*91a6c3ceSAndrew Jones  * This work is licensed under the terms of the GNU LGPL, version 2.
7*91a6c3ceSAndrew Jones  */
8*91a6c3ceSAndrew Jones #ifndef _ASMARM_GIC_V3_H_
9*91a6c3ceSAndrew Jones #define _ASMARM_GIC_V3_H_
10*91a6c3ceSAndrew Jones 
11*91a6c3ceSAndrew Jones #ifndef _ASMARM_GIC_H_
12*91a6c3ceSAndrew Jones #error Do not directly include <asm/gic-v3.h>. Include <asm/gic.h>
13*91a6c3ceSAndrew Jones #endif
14*91a6c3ceSAndrew Jones 
15*91a6c3ceSAndrew Jones /*
16*91a6c3ceSAndrew Jones  * Distributor registers
17*91a6c3ceSAndrew Jones  *
18*91a6c3ceSAndrew Jones  * We expect to be run in Non-secure mode, thus we define the
19*91a6c3ceSAndrew Jones  * group1 enable bits with respect to that view.
20*91a6c3ceSAndrew Jones  */
21*91a6c3ceSAndrew Jones #define GICD_CTLR_RWP			(1U << 31)
22*91a6c3ceSAndrew Jones #define GICD_CTLR_ARE_NS		(1U << 4)
23*91a6c3ceSAndrew Jones #define GICD_CTLR_ENABLE_G1A		(1U << 1)
24*91a6c3ceSAndrew Jones #define GICD_CTLR_ENABLE_G1		(1U << 0)
25*91a6c3ceSAndrew Jones 
26*91a6c3ceSAndrew Jones /* Re-Distributor registers, offsets from RD_base */
27*91a6c3ceSAndrew Jones #define GICR_TYPER			0x0008
28*91a6c3ceSAndrew Jones 
29*91a6c3ceSAndrew Jones #define GICR_TYPER_LAST			(1U << 4)
30*91a6c3ceSAndrew Jones 
31*91a6c3ceSAndrew Jones /* Re-Distributor registers, offsets from SGI_base */
32*91a6c3ceSAndrew Jones #define GICR_IGROUPR0			GICD_IGROUPR
33*91a6c3ceSAndrew Jones #define GICR_ISENABLER0			GICD_ISENABLER
34*91a6c3ceSAndrew Jones #define GICR_IPRIORITYR0		GICD_IPRIORITYR
35*91a6c3ceSAndrew Jones 
36*91a6c3ceSAndrew Jones #include <asm/arch_gicv3.h>
37*91a6c3ceSAndrew Jones 
38*91a6c3ceSAndrew Jones #ifndef __ASSEMBLY__
39*91a6c3ceSAndrew Jones #include <asm/setup.h>
40*91a6c3ceSAndrew Jones #include <asm/processor.h>
41*91a6c3ceSAndrew Jones #include <asm/delay.h>
42*91a6c3ceSAndrew Jones #include <asm/smp.h>
43*91a6c3ceSAndrew Jones #include <asm/io.h>
44*91a6c3ceSAndrew Jones 
45*91a6c3ceSAndrew Jones struct gicv3_data {
46*91a6c3ceSAndrew Jones 	void *dist_base;
47*91a6c3ceSAndrew Jones 	void *redist_base[NR_CPUS];
48*91a6c3ceSAndrew Jones 	unsigned int irq_nr;
49*91a6c3ceSAndrew Jones };
50*91a6c3ceSAndrew Jones extern struct gicv3_data gicv3_data;
51*91a6c3ceSAndrew Jones 
52*91a6c3ceSAndrew Jones #define gicv3_dist_base()		(gicv3_data.dist_base)
53*91a6c3ceSAndrew Jones #define gicv3_redist_base()		(gicv3_data.redist_base[smp_processor_id()])
54*91a6c3ceSAndrew Jones #define gicv3_sgi_base()		(gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
55*91a6c3ceSAndrew Jones 
56*91a6c3ceSAndrew Jones extern int gicv3_init(void);
57*91a6c3ceSAndrew Jones extern void gicv3_enable_defaults(void);
58*91a6c3ceSAndrew Jones extern void gicv3_set_redist_base(size_t stride);
59*91a6c3ceSAndrew Jones 
60*91a6c3ceSAndrew Jones static inline void gicv3_do_wait_for_rwp(void *base)
61*91a6c3ceSAndrew Jones {
62*91a6c3ceSAndrew Jones 	int count = 100000;	/* 1s */
63*91a6c3ceSAndrew Jones 
64*91a6c3ceSAndrew Jones 	while (readl(base + GICD_CTLR) & GICD_CTLR_RWP) {
65*91a6c3ceSAndrew Jones 		if (!--count) {
66*91a6c3ceSAndrew Jones 			printf("GICv3: RWP timeout!\n");
67*91a6c3ceSAndrew Jones 			abort();
68*91a6c3ceSAndrew Jones 		}
69*91a6c3ceSAndrew Jones 		cpu_relax();
70*91a6c3ceSAndrew Jones 		udelay(10);
71*91a6c3ceSAndrew Jones 	};
72*91a6c3ceSAndrew Jones }
73*91a6c3ceSAndrew Jones 
74*91a6c3ceSAndrew Jones static inline void gicv3_dist_wait_for_rwp(void)
75*91a6c3ceSAndrew Jones {
76*91a6c3ceSAndrew Jones 	gicv3_do_wait_for_rwp(gicv3_dist_base());
77*91a6c3ceSAndrew Jones }
78*91a6c3ceSAndrew Jones 
79*91a6c3ceSAndrew Jones static inline void gicv3_redist_wait_for_uwp(void)
80*91a6c3ceSAndrew Jones {
81*91a6c3ceSAndrew Jones 	/*
82*91a6c3ceSAndrew Jones 	 * We can build on gic_do_wait_for_rwp, which uses GICD_ registers
83*91a6c3ceSAndrew Jones 	 * because GICD_CTLR == GICR_CTLR and GICD_CTLR_RWP == GICR_CTLR_UWP
84*91a6c3ceSAndrew Jones 	 */
85*91a6c3ceSAndrew Jones 	gicv3_do_wait_for_rwp(gicv3_redist_base());
86*91a6c3ceSAndrew Jones }
87*91a6c3ceSAndrew Jones 
88*91a6c3ceSAndrew Jones static inline u32 mpidr_compress(u64 mpidr)
89*91a6c3ceSAndrew Jones {
90*91a6c3ceSAndrew Jones 	u64 compressed = mpidr & MPIDR_HWID_BITMASK;
91*91a6c3ceSAndrew Jones 
92*91a6c3ceSAndrew Jones 	compressed = (((compressed >> 32) & 0xff) << 24) | compressed;
93*91a6c3ceSAndrew Jones 	return compressed;
94*91a6c3ceSAndrew Jones }
95*91a6c3ceSAndrew Jones 
96*91a6c3ceSAndrew Jones static inline u64 mpidr_uncompress(u32 compressed)
97*91a6c3ceSAndrew Jones {
98*91a6c3ceSAndrew Jones 	u64 mpidr = ((u64)compressed >> 24) << 32;
99*91a6c3ceSAndrew Jones 
100*91a6c3ceSAndrew Jones 	mpidr |= compressed & MPIDR_HWID_BITMASK;
101*91a6c3ceSAndrew Jones 	return mpidr;
102*91a6c3ceSAndrew Jones }
103*91a6c3ceSAndrew Jones 
104*91a6c3ceSAndrew Jones #endif /* !__ASSEMBLY__ */
105*91a6c3ceSAndrew Jones #endif /* _ASMARM_GIC_V3_H_ */
106