syspage(2)-intrinfo

intrinfo is automatically filled in by init_intrinfo()

Note:

  1. struct startup_intrinfo is defined and used by startup code. the public definition is in sys/syspage.h.
  2. Each group of callouts (i.e. id, eoi, mask, unmask) for each level of interrupt controller deals with a set of interrupt vectors that start at 0 (zero-based). Interrupt vector numbers are passed without offset to the callout routines. The association between the zero-based interrupt vectors the callouts use and the system-wide interrupt vectors is configured within the startup-intrinfo structures.
  3. flags:
    • INTR_GENFLAG_LOAD_SYSPAGE 
      • Before the interrupt id or eoi code sequence is generated, a piece of code needs to be inserted to fetch the system page pointer into a register so that it’s usable within the id code sequence.
    • INTR_GENFLAG_LOAD_INTRMASK
      • Used only by EOI routines for hardware that doesn’t automatically mask at the chip level.
      • When the EOI routine is about to reenable interrupts, it should reenable only those interrupts that are actually enabled at the user level (e.g. managed by the functions InterruptMask() and InterruptUnmask()). When this flag is set, the existing interrupt mask is stored in a register for access by the EOI routine. A zero in the register indicates that the interrupt should be unmasked; a nonzero indicates it should remain masked.
struct intrinfo_entry {
	_Uint32t vector_base; // base number of the logical interrupt/vector numbers(IRQs) that programs will use
	_Uint32t num_vectors; // the number of the vectors
	_Uint32t cascade_vector;// the logical IRQ number for cascaded interrupts
	_Uint32t cpu_intr_base;
	_Uint16t cpu_intr_stride;
	_Uint16t flags;
	struct __intrgen_data	id;
	struct __intrgen_data	eoi;
	_SPFPTR(int, mask, (struct syspage_entry *, int));
	_SPFPTR(int, unmask, (struct syspage_entry *, int));
	_SPFPTR(unsigned, config, (struct syspage_entry *, struct intrinfo_entry *, int));
	_Uint32t				spare[4];
};

A piece of sample code:

// Adding main ARM GIC Controller
const static struct startup_intrinfo intrs[] =
{
    {
        .vector_base      = _NTO_INTR_CLASS_EXTERNAL, // (0x0000UL << 16)
        .num_vectors      = 32+192, // including SGIs, PPIs, SPIs
        .cascade_vector   = _NTO_INTR_SPARE, // (0x7FFFFUL << 16) | 0xFFFF
        .cpu_intr_base    = 0,
        .cpu_intr_stride  = 0,
        .flags            = 0,
        .id               = { INTR_GENFLAG_LOAD_SYSPAGE, 0, &interrupt_id_gic},
        .eoi              = { INTR_GENFLAG_LOAD_SYSPAGE | INTR_GENFLAG_LOAD_INTRMASK, 0, &interrupt_eoi_gic},
        .mask             = &interrupt_mask_gic,
        .unmask           = &interrupt_unmask_gic,
        .config           = &interrupt_config_gic,
        .patch_data       = NULL,
    }
};
// Adding System DMA interrupt cascaded into OMAP54XX_SDMA_IRQ_0 only
static struct startup_intrinfo sdmaintrs[] = 
{
    {
        .vector_base      = 256,
        .num_vectors      = 32,
        .cascade_vector   = OMAP54XX_SDMA_IRQ_0,
        .cpu_intr_base    = 0,
        .cpu_intr_stride  = 0,
        .flags            = 0,
        .id               = { 0, 0, &interrupt_id_omap4_sdma },
        .eoi              = { INTR_GENFLAG_LOAD_INTRMASK, 0, &interrupt_eoi_omap4_sdma },
        .mask             = &interrupt_mask_omap4_sdma,
        .unmask           = &interrupt_unmask_omap4_sdma,
        .config           = 0,
        .patch_data       = &sdma_base,
    },
};
init_intrinfo()
{
    initialize the interrupt controller; // See the sample code in Interrupt(2): ARM Interrupt Controller
    add_interrupt_array(intrs, sizeof(intrs));
    disable all SDMA channel interrupts, and clear all channel statuses; 
    add_interrupt_array(sdmaintrs, sizeof(sdmaintrs));
}

2 thoughts on “syspage(2)-intrinfo”

Leave a comment