1/* 2 * GIC Initialization Routines. 3 * 4 * (C) Copyright 2013 5 * David Feng <fenghua@phytium.com.cn> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10#include <asm-offsets.h> 11#include <config.h> 12#include <linux/linkage.h> 13#include <asm/gic.h> 14#include <asm/macro.h> 15 16 17/************************************************************************* 18 * 19 * void gic_init_secure(DistributorBase); 20 * 21 * Initialize secure copy of GIC at EL3. 22 * 23 *************************************************************************/ 24ENTRY(gic_init_secure) 25 /* 26 * Initialize Distributor 27 * x0: Distributor Base 28 */ 29#if defined(CONFIG_GICV3) 30 mov w9, #0x37 /* EnableGrp0 | EnableGrp1NS */ 31 /* EnableGrp1S | ARE_S | ARE_NS */ 32 str w9, [x0, GICD_CTLR] /* Secure GICD_CTLR */ 33 ldr w9, [x0, GICD_TYPER] 34 and w10, w9, #0x1f /* ITLinesNumber */ 35 cbz w10, 1f /* No SPIs */ 36 add x11, x0, (GICD_IGROUPRn + 4) 37 add x12, x0, (GICD_IGROUPMODRn + 4) 38 mov w9, #~0 390: str w9, [x11], #0x4 40 str wzr, [x12], #0x4 /* Config SPIs as Group1NS */ 41 sub w10, w10, #0x1 42 cbnz w10, 0b 43#elif defined(CONFIG_GICV2) 44 mov w9, #0x3 /* EnableGrp0 | EnableGrp1 */ 45 str w9, [x0, GICD_CTLR] /* Secure GICD_CTLR */ 46 ldr w9, [x0, GICD_TYPER] 47 and w10, w9, #0x1f /* ITLinesNumber */ 48 cbz w10, 1f /* No SPIs */ 49 add x11, x0, GICD_IGROUPRn 50 mov w9, #~0 /* Config SPIs as Grp1 */ 51 str w9, [x11], #0x4 520: str w9, [x11], #0x4 53 sub w10, w10, #0x1 54 cbnz w10, 0b 55 56 ldr x1, =GICC_BASE /* GICC_CTLR */ 57 mov w0, #3 /* EnableGrp0 | EnableGrp1 */ 58 str w0, [x1] 59 60 mov w0, #1 << 7 /* allow NS access to GICC_PMR */ 61 str w0, [x1, #4] /* GICC_PMR */ 62#endif 631: 64 ret 65ENDPROC(gic_init_secure) 66 67 68/************************************************************************* 69 * For Gicv2: 70 * void gic_init_secure_percpu(DistributorBase, CpuInterfaceBase); 71 * For Gicv3: 72 * void gic_init_secure_percpu(ReDistributorBase); 73 * 74 * Initialize secure copy of GIC at EL3. 75 * 76 *************************************************************************/ 77ENTRY(gic_init_secure_percpu) 78#if defined(CONFIG_GICV3) 79 /* 80 * Initialize ReDistributor 81 * x0: ReDistributor Base 82 */ 83 mrs x10, mpidr_el1 84 lsr x9, x10, #32 85 bfi x10, x9, #24, #8 /* w10 is aff3:aff2:aff1:aff0 */ 86 mov x9, x0 871: ldr x11, [x9, GICR_TYPER] 88 lsr x11, x11, #32 /* w11 is aff3:aff2:aff1:aff0 */ 89 cmp w10, w11 90 b.eq 2f 91 add x9, x9, #(2 << 16) 92 b 1b 93 94 /* x9: ReDistributor Base Address of Current CPU */ 952: mov w10, #~0x2 96 ldr w11, [x9, GICR_WAKER] 97 and w11, w11, w10 /* Clear ProcessorSleep */ 98 str w11, [x9, GICR_WAKER] 99 dsb st 100 isb 1013: ldr w10, [x9, GICR_WAKER] 102 tbnz w10, #2, 3b /* Wait Children be Alive */ 103 104 add x10, x9, #(1 << 16) /* SGI_Base */ 105 mov w11, #~0 106 str w11, [x10, GICR_IGROUPRn] 107 str wzr, [x10, GICR_IGROUPMODRn] /* SGIs|PPIs Group1NS */ 108 mov w11, #0x1 /* Enable SGI 0 */ 109 str w11, [x10, GICR_ISENABLERn] 110 111 /* Initialize Cpu Interface */ 112 mrs x10, ICC_SRE_EL3 113 orr x10, x10, #0xf /* SRE & Disable IRQ/FIQ Bypass & */ 114 /* Allow EL2 access to ICC_SRE_EL2 */ 115 msr ICC_SRE_EL3, x10 116 isb 117 118 mrs x10, ICC_SRE_EL2 119 orr x10, x10, #0xf /* SRE & Disable IRQ/FIQ Bypass & */ 120 /* Allow EL1 access to ICC_SRE_EL1 */ 121 msr ICC_SRE_EL2, x10 122 isb 123 124 mov x10, #0x3 /* EnableGrp1NS | EnableGrp1S */ 125 msr ICC_IGRPEN1_EL3, x10 126 isb 127 128 msr ICC_CTLR_EL3, xzr 129 isb 130 131 msr ICC_CTLR_EL1, xzr /* NonSecure ICC_CTLR_EL1 */ 132 isb 133 134 mov x10, #0x1 << 7 /* Non-Secure access to ICC_PMR_EL1 */ 135 msr ICC_PMR_EL1, x10 136 isb 137#elif defined(CONFIG_GICV2) 138 /* 139 * Initialize SGIs and PPIs 140 * x0: Distributor Base 141 * x1: Cpu Interface Base 142 */ 143 mov w9, #~0 /* Config SGIs and PPIs as Grp1 */ 144 str w9, [x0, GICD_IGROUPRn] /* GICD_IGROUPR0 */ 145 mov w9, #0x1 /* Enable SGI 0 */ 146 str w9, [x0, GICD_ISENABLERn] 147 148 /* Initialize Cpu Interface */ 149 mov w9, #0x1e7 /* Disable IRQ/FIQ Bypass & */ 150 /* Enable Ack Group1 Interrupt & */ 151 /* EnableGrp0 & EnableGrp1 */ 152 str w9, [x1, GICC_CTLR] /* Secure GICC_CTLR */ 153 154 mov w9, #0x1 << 7 /* Non-Secure access to GICC_PMR */ 155 str w9, [x1, GICC_PMR] 156#endif 157 ret 158ENDPROC(gic_init_secure_percpu) 159 160 161/************************************************************************* 162 * For Gicv2: 163 * void gic_kick_secondary_cpus(DistributorBase); 164 * For Gicv3: 165 * void gic_kick_secondary_cpus(void); 166 * 167 *************************************************************************/ 168ENTRY(gic_kick_secondary_cpus) 169#if defined(CONFIG_GICV3) 170 mov x9, #(1 << 40) 171 msr ICC_ASGI1R_EL1, x9 172 isb 173#elif defined(CONFIG_GICV2) 174 mov w9, #0x8000 175 movk w9, #0x100, lsl #16 176 str w9, [x0, GICD_SGIR] 177#endif 178 ret 179ENDPROC(gic_kick_secondary_cpus) 180 181 182/************************************************************************* 183 * For Gicv2: 184 * void gic_wait_for_interrupt(CpuInterfaceBase); 185 * For Gicv3: 186 * void gic_wait_for_interrupt(void); 187 * 188 * Wait for SGI 0 from master. 189 * 190 *************************************************************************/ 191ENTRY(gic_wait_for_interrupt) 192#if defined(CONFIG_GICV3) 193 gic_wait_for_interrupt_m x9 194#elif defined(CONFIG_GICV2) 195 gic_wait_for_interrupt_m x0, w9 196#endif 197 ret 198ENDPROC(gic_wait_for_interrupt) 199