stkarm/src/gic.cpp

42 lines
1.4 KiB
C++

#include <gic.h>
#include <dbg.h>
namespace GIC {
/* This code (correctly) assumes that initial registers' values are 0x0,
* thus does not work (read: correctly overwrite) with subsequent changes,
* but since GIC is prepared at system startup and then never touched again,
* this should not be a problem */
void enableInterrupt(const uint16_t m, const TargetCPU target, const Sensitivity sensitivity) {
/* register offset (used in an uint32_t array, so no need to multiply by 4) */
uint16_t n;
/* Enable interrupt m */
n = m / 32;
distributor[GICD_ISENABLER + n] = distributor[GICD_ISENABLER + n] | (1 << (m % 32));
/* Set target CPU */
n = m / 4;
distributor[GICD_ITARGETSR + n] = distributor[GICD_ITARGETSR + n] | (target << ((m % 4) * 8));
/* Edge or level triggered? */
n = m / 16;
distributor[GICD_ICFGR + n] = distributor[GICD_ICFGR + n] | (sensitivity << (2 * (m % 16) + 1));
/* Enable all priorities */
cpuInterface[1] = 0xff;
}
void enable(void) {
/* Enable distributor and CPU interfaces
* Call this function always at the end,
* since writing on GIC registers is not allowed when it is enabled */
distributor[0] = distributor[GICD_CTLR] | 0x1;
cpuInterface[0] = cpuInterface[GICC_CTLR] | 0x1;
}
}