github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/arm/gic.go (about) 1 // ARM processor support 2 // https://github.com/f-secure-foundry/tamago 3 // 4 // Copyright (c) F-Secure Corporation 5 // https://foundry.f-secure.com 6 // 7 // Use of this source code is governed by the license 8 // that can be found in the LICENSE file. 9 10 package arm 11 12 import ( 13 "github.com/f-secure-foundry/tamago/internal/reg" 14 ) 15 16 const ( 17 // GIC offsets in Cortex-A7 18 // (p178, Table 8-1, Cortex-A7 MPCore Technical Reference Manual). 19 GICD_OFF = 0x1000 20 GICC_OFF = 0x2000 21 22 // Distributor register map 23 // (p75, Table 4-1, ARM Generic Interrupt Controller Architecture Specification). 24 GICD_CTLR = 0 25 GICD_CTLR_ENABLEGRP1 = 1 26 GICD_CTLR_ENABLEGRP0 = 0 27 28 GICD_TYPER = 0x4 29 GICD_TYPER_ITLINES = 0 30 31 GICD_IGROUPR = 0x080 32 GICD_ICENABLER = 0x180 33 GICD_ICPENDR = 0x280 34 35 // CPU interface register map 36 // (p76, Table 4-2, ARM Generic Interrupt Controller Architecture Specification). 37 GICC_CTLR = 0 38 GICC_CTLR_FIQEN = 3 39 GICC_CTLR_ENABLEGRP1 = 1 40 GICC_CTLR_ENABLEGRP0 = 0 41 42 GICC_PMR = 0x4 43 GICC_PMR_PRIORITY = 0 44 ) 45 46 // InitGIC initializes the ARM Generic Interrupt Controller (GIC). 47 func InitGIC(base uint32) { 48 gicd := base + GICD_OFF 49 gicc := base + GICC_OFF 50 51 // Get the maximum number of external interrupt lines 52 itLinesNum := reg.Get(gicd+GICD_TYPER, GICD_TYPER_ITLINES, 0x1f) 53 54 // Add a line for the 32 internal interrupts 55 itLinesNum += 1 56 57 for i := uint32(0); i < itLinesNum; i++ { 58 // Disable interrupts 59 addr := gicd + GICD_ICENABLER + 4*i 60 reg.Write(addr, 0xffffffff) 61 62 // Clear pending interrupts 63 addr = gicd + GICD_ICPENDR + 4*i 64 reg.Write(addr, 0xffffffff) 65 66 // Assign all interrupts to Non-Secure 67 addr = gicd + GICD_IGROUPR + 4*i 68 reg.Write(addr, 0xffffffff) 69 } 70 71 // Set priority mask to allow Non-Secure world to use the lower half 72 // of the priority range. 73 reg.Write(gicc+GICC_PMR, 0x80) 74 75 // Enable GIC 76 reg.Write(gicc+GICC_CTLR, GICC_CTLR_ENABLEGRP1|GICC_CTLR_ENABLEGRP0|GICC_CTLR_FIQEN) 77 reg.Set(gicd+GICD_CTLR, GICD_CTLR_ENABLEGRP1) 78 reg.Set(gicd+GICD_CTLR, GICD_CTLR_ENABLEGRP0) 79 }