1 /* 2 * Copyright 2022, Adrien Destugues, pulkomandy@pulkomandy.tk 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <vm/vm.h> 7 8 #include "soc_sun4i.h" 9 10 11 #define SUN4I_INTC_PEND_REG0 0x10 12 #define SUN4I_INTC_PEND_REG1 0x14 13 #define SUN4I_INTC_PEND_REG2 0x18 14 #define SUN4I_INTC_MASK_REG0 0x50 15 #define SUN4I_INTC_MASK_REG1 0x54 16 #define SUN4I_INTC_MASK_REG2 0x58 17 18 19 void 20 Sun4iInterruptController::EnableInterrupt(int32 irq) 21 { 22 if (irq <= 31) { 23 fRegBase[SUN4I_INTC_MASK_REG0] |= 1 << irq; 24 return; 25 } 26 27 if (irq <= 63) { 28 fRegBase[SUN4I_INTC_MASK_REG1] |= 1 << (irq - 32); 29 return; 30 } 31 32 fRegBase[SUN4I_INTC_MASK_REG2] |= 1 << (irq - 64); 33 } 34 35 36 void 37 Sun4iInterruptController::DisableInterrupt(int irq) 38 { 39 if (irq <= 31) { 40 fRegBase[SUN4I_INTC_MASK_REG0] &= ~(1 << irq); 41 return; 42 } 43 44 if (irq <= 63) { 45 fRegBase[SUN4I_INTC_MASK_REG1] &= ~(1 << (irq - 32)); 46 return; 47 } 48 49 fRegBase[SUN4I_INTC_MASK_REG1] &= ~(1 << (irq - 64)); 50 } 51 52 53 void 54 Sun4iInterruptController::HandleInterrupt() 55 { 56 // FIXME can we use the hardware managed interrupt vector instead? 57 for (int i=0; i < 32; i++) { 58 if (fRegBase[SUN4I_INTC_PEND_REG0] & (1 << i)) 59 int_io_interrupt_handler(i, true); 60 } 61 62 for (int i=0; i < 32; i++) { 63 if (fRegBase[SUN4I_INTC_PEND_REG1] & (1 << i)) 64 int_io_interrupt_handler(i + 32, true); 65 } 66 67 for (int i=0; i < 32; i++) { 68 if (fRegBase[SUN4I_INTC_PEND_REG2] & (1 << i)) 69 int_io_interrupt_handler(i + 64, true); 70 } 71 } 72 73 74 Sun4iInterruptController::Sun4iInterruptController(uint32_t reg_base) 75 { 76 fRegArea = vm_map_physical_memory(B_SYSTEM_TEAM, "intc-sun4i", (void**)&fRegBase, 77 B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, 78 reg_base, false); 79 if (fRegArea < 0) 80 panic("Sun4iInterruptController: cannot map registers!"); 81 82 fRegBase[SUN4I_INTC_MASK_REG0] = 0; 83 fRegBase[SUN4I_INTC_MASK_REG1] = 0; 84 fRegBase[SUN4I_INTC_MASK_REG2] = 0; 85 } 86