1 /* 2 * ARM Generic Interrupt Controller support 3 * 4 * Tim Deegan <tim@xen.org> 5 * Copyright (c) 2011 Citrix Systems. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 */ 17 18 #ifndef __ASM_ARM_GIC_H__ 19 #define __ASM_ARM_GIC_H__ 20 21 #define NR_GIC_LOCAL_IRQS NR_LOCAL_IRQS 22 #define NR_GIC_SGI 16 23 24 #define GICD_CTLR (0x000) 25 #define GICD_TYPER (0x004) 26 #define GICD_IIDR (0x008) 27 #define GICD_IGROUPR (0x080) 28 #define GICD_IGROUPRN (0x0FC) 29 #define GICD_ISENABLER (0x100) 30 #define GICD_ISENABLERN (0x17C) 31 #define GICD_ICENABLER (0x180) 32 #define GICD_ICENABLERN (0x1fC) 33 #define GICD_ISPENDR (0x200) 34 #define GICD_ISPENDRN (0x27C) 35 #define GICD_ICPENDR (0x280) 36 #define GICD_ICPENDRN (0x2FC) 37 #define GICD_ISACTIVER (0x300) 38 #define GICD_ISACTIVERN (0x37C) 39 #define GICD_ICACTIVER (0x380) 40 #define GICD_ICACTIVERN (0x3FC) 41 #define GICD_IPRIORITYR (0x400) 42 #define GICD_IPRIORITYRN (0x7F8) 43 #define GICD_ITARGETSR (0x800) 44 #define GICD_ITARGETSR7 (0x81C) 45 #define GICD_ITARGETSR8 (0x820) 46 #define GICD_ITARGETSRN (0xBF8) 47 #define GICD_ICFGR (0xC00) 48 #define GICD_ICFGR1 (0xC04) 49 #define GICD_ICFGR2 (0xC08) 50 #define GICD_ICFGRN (0xCFC) 51 #define GICD_NSACR (0xE00) 52 #define GICD_NSACRN (0xEFC) 53 #define GICD_SGIR (0xF00) 54 #define GICD_CPENDSGIR (0xF10) 55 #define GICD_CPENDSGIRN (0xF1C) 56 #define GICD_SPENDSGIR (0xF20) 57 #define GICD_SPENDSGIRN (0xF2C) 58 #define GICD_ICPIDR2 (0xFE8) 59 60 #define GICD_SGI_TARGET_LIST_SHIFT (24) 61 #define GICD_SGI_TARGET_LIST_MASK (0x3UL << GICD_SGI_TARGET_LIST_SHIFT) 62 #define GICD_SGI_TARGET_LIST (0UL<<GICD_SGI_TARGET_LIST_SHIFT) 63 #define GICD_SGI_TARGET_LIST_VAL (0) 64 #define GICD_SGI_TARGET_OTHERS (1UL<<GICD_SGI_TARGET_LIST_SHIFT) 65 #define GICD_SGI_TARGET_OTHERS_VAL (1) 66 #define GICD_SGI_TARGET_SELF (2UL<<GICD_SGI_TARGET_LIST_SHIFT) 67 #define GICD_SGI_TARGET_SELF_VAL (2) 68 #define GICD_SGI_TARGET_SHIFT (16) 69 #define GICD_SGI_TARGET_MASK (0xFFUL<<GICD_SGI_TARGET_SHIFT) 70 #define GICD_SGI_GROUP1 (1UL<<15) 71 #define GICD_SGI_INTID_MASK (0xFUL) 72 73 #define GICC_CTLR (0x0000) 74 #define GICC_PMR (0x0004) 75 #define GICC_BPR (0x0008) 76 #define GICC_IAR (0x000C) 77 #define GICC_EOIR (0x0010) 78 #define GICC_RPR (0x0014) 79 #define GICC_HPPIR (0x0018) 80 #define GICC_APR (0x00D0) 81 #define GICC_NSAPR (0x00E0) 82 #define GICC_IIDR (0x00FC) 83 #define GICC_DIR (0x1000) 84 85 #define GICH_HCR (0x00) 86 #define GICH_VTR (0x04) 87 #define GICH_VMCR (0x08) 88 #define GICH_MISR (0x10) 89 #define GICH_EISR0 (0x20) 90 #define GICH_EISR1 (0x24) 91 #define GICH_ELSR0 (0x30) 92 #define GICH_ELSR1 (0x34) 93 #define GICH_APR (0xF0) 94 #define GICH_LR (0x100) 95 96 /* Register bits */ 97 #define GICD_CTL_ENABLE 0x1 98 99 #define GICD_TYPE_LINES 0x01f 100 #define GICD_TYPE_CPUS_SHIFT 5 101 #define GICD_TYPE_CPUS 0x0e0 102 #define GICD_TYPE_SEC 0x400 103 #define GICD_TYPER_DVIS (1U << 18) 104 105 #define GICC_CTL_ENABLE 0x1 106 #define GICC_CTL_EOI (0x1 << 9) 107 108 #define GICC_IA_IRQ 0x03ff 109 #define GICC_IA_CPU_MASK 0x1c00 110 #define GICC_IA_CPU_SHIFT 10 111 112 #define GICH_HCR_EN (1 << 0) 113 #define GICH_HCR_UIE (1 << 1) 114 #define GICH_HCR_LRENPIE (1 << 2) 115 #define GICH_HCR_NPIE (1 << 3) 116 #define GICH_HCR_VGRP0EIE (1 << 4) 117 #define GICH_HCR_VGRP0DIE (1 << 5) 118 #define GICH_HCR_VGRP1EIE (1 << 6) 119 #define GICH_HCR_VGRP1DIE (1 << 7) 120 121 #define GICH_MISR_EOI (1 << 0) 122 #define GICH_MISR_U (1 << 1) 123 #define GICH_MISR_LRENP (1 << 2) 124 #define GICH_MISR_NP (1 << 3) 125 #define GICH_MISR_VGRP0E (1 << 4) 126 #define GICH_MISR_VGRP0D (1 << 5) 127 #define GICH_MISR_VGRP1E (1 << 6) 128 #define GICH_MISR_VGRP1D (1 << 7) 129 130 /* 131 * The minimum GICC_BPR is required to be in the range 0-3. We set 132 * GICC_BPR to 0 but we must expect that it might be 3. This means we 133 * can rely on premption between the following ranges: 134 * 0xf0..0xff 135 * 0xe0..0xdf 136 * 0xc0..0xcf 137 * 0xb0..0xbf 138 * 0xa0..0xaf 139 * 0x90..0x9f 140 * 0x80..0x8f 141 * 142 * Priorities within a range will not preempt each other. 143 * 144 * A GIC must support a mimimum of 16 priority levels. 145 */ 146 #define GIC_PRI_LOWEST 0xf0 147 #define GIC_PRI_IRQ 0xa0 148 #define GIC_PRI_IPI 0x90 /* IPIs must preempt normal interrupts */ 149 #define GIC_PRI_HIGHEST 0x80 /* Higher priorities belong to Secure-World */ 150 #define GIC_PRI_TO_GUEST(pri) (pri >> 3) /* GICH_LR and GICH_VMCR only support 151 5 bits for guest irq priority */ 152 153 #define GICH_LR_PENDING 1 154 #define GICH_LR_ACTIVE 2 155 156 #ifndef __ASSEMBLY__ 157 #include <xen/device_tree.h> 158 #include <xen/irq.h> 159 #include <asm-arm/vgic.h> 160 161 #define DT_COMPAT_GIC_CORTEX_A15 "arm,cortex-a15-gic" 162 163 #define DT_MATCH_GIC_V2 \ 164 DT_MATCH_COMPATIBLE(DT_COMPAT_GIC_CORTEX_A15), \ 165 DT_MATCH_COMPATIBLE("arm,cortex-a7-gic"), \ 166 DT_MATCH_COMPATIBLE("arm,gic-400") 167 168 #define DT_MATCH_GIC_V3 DT_MATCH_COMPATIBLE("arm,gic-v3") 169 170 #ifdef CONFIG_HAS_GICV3 171 /* 172 * GICv3 registers that needs to be saved/restored 173 */ 174 struct gic_v3 { 175 uint32_t hcr, vmcr, sre_el1; 176 uint32_t apr0[4]; 177 uint32_t apr1[4]; 178 uint64_t lr[16]; 179 }; 180 #endif 181 182 /* 183 * GICv2 register that needs to be saved/restored 184 * on VCPU context switch 185 */ 186 struct gic_v2 { 187 uint32_t hcr; 188 uint32_t vmcr; 189 uint32_t apr; 190 uint32_t lr[64]; 191 }; 192 193 /* 194 * Union to hold underlying hw version context information 195 */ 196 union gic_state_data { 197 struct gic_v2 v2; 198 #ifdef CONFIG_HAS_GICV3 199 struct gic_v3 v3; 200 #endif 201 }; 202 203 /* 204 * Decode LR register content. 205 * The LR register format is different for GIC HW version 206 */ 207 struct gic_lr { 208 /* Physical IRQ */ 209 uint32_t pirq; 210 /* Virtual IRQ */ 211 uint32_t virq; 212 uint8_t priority; 213 uint8_t state; 214 uint8_t hw_status; 215 uint8_t grp; 216 }; 217 218 enum gic_version { 219 GIC_V2, 220 GIC_V3, 221 }; 222 223 extern enum gic_version gic_hw_version(void); 224 225 /* Program the IRQ type into the GIC */ 226 void gic_set_irq_type(struct irq_desc *desc, unsigned int type); 227 228 /* Program the GIC to route an interrupt */ 229 extern void gic_route_irq_to_xen(struct irq_desc *desc, unsigned int priority); 230 extern int gic_route_irq_to_guest(struct domain *, unsigned int virq, 231 struct irq_desc *desc, 232 unsigned int priority); 233 234 /* Remove an IRQ passthrough to a guest */ 235 int gic_remove_irq_from_guest(struct domain *d, unsigned int virq, 236 struct irq_desc *desc); 237 238 extern void gic_inject(void); 239 extern void gic_clear_pending_irqs(struct vcpu *v); 240 extern int gic_events_need_delivery(void); 241 242 extern void init_maintenance_interrupt(void); 243 extern void gic_raise_guest_irq(struct vcpu *v, unsigned int irq, 244 unsigned int priority); 245 extern void gic_raise_inflight_irq(struct vcpu *v, unsigned int virtual_irq); 246 extern void gic_remove_from_lr_pending(struct vcpu *v, struct pending_irq *p); 247 extern void gic_remove_irq_from_queues(struct vcpu *v, struct pending_irq *p); 248 249 /* Accept an interrupt from the GIC and dispatch its handler */ 250 extern void gic_interrupt(struct cpu_user_regs *regs, int is_fiq); 251 /* Find the interrupt controller and set up the callback to translate 252 * device tree IRQ. 253 */ 254 extern void gic_preinit(void); 255 /* Bring up the interrupt controller, and report # cpus attached */ 256 extern void gic_init(void); 257 /* Bring up a secondary CPU's per-CPU GIC interface */ 258 extern void gic_init_secondary_cpu(void); 259 /* Take down a CPU's per-CPU GIC interface */ 260 extern void gic_disable_cpu(void); 261 /* setup the gic virtual interface for a guest */ 262 extern int gicv_setup(struct domain *d); 263 264 /* Context switch */ 265 extern void gic_save_state(struct vcpu *v); 266 extern void gic_restore_state(struct vcpu *v); 267 268 /* SGI (AKA IPIs) */ 269 enum gic_sgi { 270 GIC_SGI_EVENT_CHECK = 0, 271 GIC_SGI_DUMP_STATE = 1, 272 GIC_SGI_CALL_FUNCTION = 2, 273 }; 274 275 /* SGI irq mode types */ 276 enum gic_sgi_mode { 277 SGI_TARGET_LIST, 278 SGI_TARGET_OTHERS, 279 SGI_TARGET_SELF, 280 }; 281 282 extern void send_SGI_mask(const cpumask_t *cpumask, enum gic_sgi sgi); 283 extern void send_SGI_one(unsigned int cpu, enum gic_sgi sgi); 284 extern void send_SGI_self(enum gic_sgi sgi); 285 extern void send_SGI_allbutself(enum gic_sgi sgi); 286 287 /* print useful debug info */ 288 extern void gic_dump_info(struct vcpu *v); 289 290 /* Number of interrupt lines */ 291 extern unsigned int gic_number_lines(void); 292 293 /* IRQ translation function for the device tree */ 294 int gic_irq_xlate(const u32 *intspec, unsigned int intsize, 295 unsigned int *out_hwirq, unsigned int *out_type); 296 void gic_clear_lrs(struct vcpu *v); 297 298 struct gic_info { 299 /* GIC version */ 300 enum gic_version hw_version; 301 /* Number of GIC lines supported */ 302 unsigned int nr_lines; 303 /* Number of LR registers */ 304 uint8_t nr_lrs; 305 /* Maintenance irq number */ 306 unsigned int maintenance_irq; 307 /* Pointer to the device tree node representing the interrupt controller */ 308 const struct dt_device_node *node; 309 }; 310 311 struct gic_hw_operations { 312 /* Hold GIC HW information */ 313 const struct gic_info *info; 314 /* Initialize the GIC and the boot CPU */ 315 int (*init)(void); 316 /* Save GIC registers */ 317 void (*save_state)(struct vcpu *); 318 /* Restore GIC registers */ 319 void (*restore_state)(const struct vcpu *); 320 /* Dump GIC LR register information */ 321 void (*dump_state)(const struct vcpu *); 322 323 /* hw_irq_controller to enable/disable/eoi host irq */ 324 hw_irq_controller *gic_host_irq_type; 325 326 /* hw_irq_controller to enable/disable/eoi guest irq */ 327 hw_irq_controller *gic_guest_irq_type; 328 329 /* End of Interrupt */ 330 void (*eoi_irq)(struct irq_desc *irqd); 331 /* Deactivate/reduce priority of irq */ 332 void (*deactivate_irq)(struct irq_desc *irqd); 333 /* Read IRQ id and Ack */ 334 unsigned int (*read_irq)(void); 335 /* Set IRQ type */ 336 void (*set_irq_type)(struct irq_desc *desc, unsigned int type); 337 /* Set IRQ priority */ 338 void (*set_irq_priority)(struct irq_desc *desc, unsigned int priority); 339 /* Send SGI */ 340 void (*send_SGI)(enum gic_sgi sgi, enum gic_sgi_mode irqmode, 341 const cpumask_t *online_mask); 342 /* Disable CPU physical and virtual interfaces */ 343 void (*disable_interface)(void); 344 /* Update LR register with state and priority */ 345 void (*update_lr)(int lr, const struct pending_irq *pending_irq, 346 unsigned int state); 347 /* Update HCR status register */ 348 void (*update_hcr_status)(uint32_t flag, bool set); 349 /* Clear LR register */ 350 void (*clear_lr)(int lr); 351 /* Read LR register and populate gic_lr structure */ 352 void (*read_lr)(int lr, struct gic_lr *); 353 /* Write LR register from gic_lr structure */ 354 void (*write_lr)(int lr, const struct gic_lr *); 355 /* Read VMCR priority */ 356 unsigned int (*read_vmcr_priority)(void); 357 /* Read APRn register */ 358 unsigned int (*read_apr)(int apr_reg); 359 /* Secondary CPU init */ 360 int (*secondary_init)(void); 361 /* Create GIC node for the hardware domain */ 362 int (*make_hwdom_dt_node)(const struct domain *d, 363 const struct dt_device_node *gic, void *fdt); 364 /* Create MADT table for the hardware domain */ 365 int (*make_hwdom_madt)(const struct domain *d, u32 offset); 366 /* Map extra GIC MMIO, irqs and other hw stuffs to the hardware domain. */ 367 int (*map_hwdom_extra_mappings)(struct domain *d); 368 /* Query the size of hardware domain madt table */ 369 unsigned long (*get_hwdom_extra_madt_size)(const struct domain *d); 370 /* Deny access to GIC regions */ 371 int (*iomem_deny_access)(const struct domain *d); 372 /* Handle LPIs, which require special handling */ 373 void (*do_LPI)(unsigned int lpi); 374 }; 375 376 void register_gic_ops(const struct gic_hw_operations *ops); 377 int gic_make_hwdom_dt_node(const struct domain *d, 378 const struct dt_device_node *gic, 379 void *fdt); 380 int gic_make_hwdom_madt(const struct domain *d, u32 offset); 381 unsigned long gic_get_hwdom_madt_size(const struct domain *d); 382 int gic_map_hwdom_extra_mappings(struct domain *d); 383 int gic_iomem_deny_access(const struct domain *d); 384 385 #endif /* __ASSEMBLY__ */ 386 #endif 387 388 /* 389 * Local variables: 390 * mode: C 391 * c-file-style: "BSD" 392 * c-basic-offset: 4 393 * indent-tabs-mode: nil 394 * End: 395 */ 396