/******************************************************************************* * Helper function to configure secure G0 SGIs and PPIs. ******************************************************************************/ void gicv2_secure_ppi_sgi_setup(uintptr_t gicd_base, unsigned int num_ints, const unsigned int *sec_intr_list) { unsigned int index, irq_num, sec_ppi_sgi_mask = 0; /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ assert(num_ints ? (uintptr_t)sec_intr_list : 1); /* * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a * more scalable approach as it avoids clearing the enable bits in the * GICD_CTLR. */ gicd_write_icenabler(gicd_base, 0, ~0); /* Setup the default PPI/SGI priorities doing four at a time */ for (index = 0; index < MIN_SPI_ID; index += 4) gicd_write_ipriorityr(gicd_base, index, GICD_IPRIORITYR_DEF_VAL); for (index = 0; index < num_ints; index++) { irq_num = sec_intr_list[index]; if (irq_num < MIN_SPI_ID) { /* We have an SGI or a PPI. They are Group0 at reset */ sec_ppi_sgi_mask |= 1U << irq_num; /* Set the priority of this interrupt */ gicd_write_ipriorityr(gicd_base, irq_num, GIC_HIGHEST_SEC_PRIORITY); } } /* * Invert the bitmask to create a mask for non-secure PPIs and * SGIs. Program the GICD_IGROUPR0 with this bit mask. */ gicd_write_igroupr(gicd_base, 0, ~sec_ppi_sgi_mask); /* Enable the Group 0 SGIs and PPIs */ gicd_write_isenabler(gicd_base, 0, sec_ppi_sgi_mask); }
void gicd_set_icenabler(uintptr_t base, unsigned int id) { unsigned bit_num = id & ((1 << ICENABLER_SHIFT) - 1); gicd_write_icenabler(base, id, (1 << bit_num)); }