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 + 4) 50 mov w9, #~0 /* Config SPIs as Grp1 */ 510: str w9, [x11], #0x4 52 sub w10, w10, #0x1 53 cbnz w10, 0b 54#endif 551: 56 ret 57ENDPROC(gic_init_secure) 58 59 60/************************************************************************* 61 * For Gicv2: 62 * void gic_init_secure_percpu(DistributorBase, CpuInterfaceBase); 63 * For Gicv3: 64 * void gic_init_secure_percpu(ReDistributorBase); 65 * 66 * Initialize secure copy of GIC at EL3. 67 * 68 *************************************************************************/ 69ENTRY(gic_init_secure_percpu) 70#if defined(CONFIG_GICV3) 71 /* 72 * Initialize ReDistributor 73 * x0: ReDistributor Base 74 */ 75 mrs x10, mpidr_el1 76 lsr x9, x10, #32 77 bfi x10, x9, #24, #8 /* w10 is aff3:aff2:aff1:aff0 */ 78 mov x9, x0 791: ldr x11, [x9, GICR_TYPER] 80 lsr x11, x11, #32 /* w11 is aff3:aff2:aff1:aff0 */ 81 cmp w10, w11 82 b.eq 2f 83 add x9, x9, #(2 << 16) 84 b 1b 85 86 /* x9: ReDistributor Base Address of Current CPU */ 872: mov w10, #~0x2 88 ldr w11, [x9, GICR_WAKER] 89 and w11, w11, w10 /* Clear ProcessorSleep */ 90 str w11, [x9, GICR_WAKER] 91 dsb st 92 isb 933: ldr w10, [x9, GICR_WAKER] 94 tbnz w10, #2, 3b /* Wait Children be Alive */ 95 96 add x10, x9, #(1 << 16) /* SGI_Base */ 97 mov w11, #~0 98 str w11, [x10, GICR_IGROUPRn] 99 str wzr, [x10, GICR_IGROUPMODRn] /* SGIs|PPIs Group1NS */ 100 mov w11, #0x1 /* Enable SGI 0 */ 101 str w11, [x10, GICR_ISENABLERn] 102 103 /* Initialize Cpu Interface */ 104 mrs x10, ICC_SRE_EL3 105 orr x10, x10, #0xf /* SRE & Disable IRQ/FIQ Bypass & */ 106 /* Allow EL2 access to ICC_SRE_EL2 */ 107 msr ICC_SRE_EL3, x10 108 isb 109 110 mrs x10, ICC_SRE_EL2 111 orr x10, x10, #0xf /* SRE & Disable IRQ/FIQ Bypass & */ 112 /* Allow EL1 access to ICC_SRE_EL1 */ 113 msr ICC_SRE_EL2, x10 114 isb 115 116 mov x10, #0x3 /* EnableGrp1NS | EnableGrp1S */ 117 msr ICC_IGRPEN1_EL3, x10 118 isb 119 120 msr ICC_CTLR_EL3, xzr 121 isb 122 123 msr ICC_CTLR_EL1, xzr /* NonSecure ICC_CTLR_EL1 */ 124 isb 125 126 mov x10, #0x1 << 7 /* Non-Secure access to ICC_PMR_EL1 */ 127 msr ICC_PMR_EL1, x10 128 isb 129#elif defined(CONFIG_GICV2) 130 /* 131 * Initialize SGIs and PPIs 132 * x0: Distributor Base 133 * x1: Cpu Interface Base 134 */ 135 mov w9, #~0 /* Config SGIs and PPIs as Grp1 */ 136 str w9, [x0, GICD_IGROUPRn] /* GICD_IGROUPR0 */ 137 mov w9, #0x1 /* Enable SGI 0 */ 138 str w9, [x0, GICD_ISENABLERn] 139 140 /* Initialize Cpu Interface */ 141 mov w9, #0x1e7 /* Disable IRQ/FIQ Bypass & */ 142 /* Enable Ack Group1 Interrupt & */ 143 /* EnableGrp0 & EnableGrp1 */ 144 str w9, [x1, GICC_CTLR] /* Secure GICC_CTLR */ 145 146 mov w9, #0x1 << 7 /* Non-Secure access to GICC_PMR */ 147 str w9, [x1, GICC_PMR] 148#endif 149 ret 150ENDPROC(gic_init_secure_percpu) 151 152 153/************************************************************************* 154 * For Gicv2: 155 * void gic_kick_secondary_cpus(DistributorBase); 156 * For Gicv3: 157 * void gic_kick_secondary_cpus(void); 158 * 159 *************************************************************************/ 160ENTRY(gic_kick_secondary_cpus) 161#if defined(CONFIG_GICV3) 162 mov x9, #(1 << 40) 163 msr ICC_ASGI1R_EL1, x9 164 isb 165#elif defined(CONFIG_GICV2) 166 mov w9, #0x8000 167 movk w9, #0x100, lsl #16 168 str w9, [x0, GICD_SGIR] 169#endif 170 ret 171ENDPROC(gic_kick_secondary_cpus) 172 173 174/************************************************************************* 175 * For Gicv2: 176 * void gic_wait_for_interrupt(CpuInterfaceBase); 177 * For Gicv3: 178 * void gic_wait_for_interrupt(void); 179 * 180 * Wait for SGI 0 from master. 181 * 182 *************************************************************************/ 183ENTRY(gic_wait_for_interrupt) 184#if defined(CONFIG_GICV3) 185 gic_wait_for_interrupt_m x9 186#elif defined(CONFIG_GICV2) 187 gic_wait_for_interrupt_m x0, w9 188#endif 189 ret 190ENDPROC(gic_wait_for_interrupt) 191