rtems_status_code mpc83xx_ipic_set_mask( rtems_vector_number vector, rtems_vector_number mask_vector, bool mask ) { uint8_t pos = 0; mpc83xx_ipic_mask_t *mask_entry; uint32_t *mask_reg; rtems_interrupt_level level; /* Parameter check */ if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector) || !MPC83XX_IPIC_IS_VALID_VECTOR( mask_vector)) { return RTEMS_INVALID_NUMBER; } else if (vector == mask_vector) { return RTEMS_RESOURCE_IN_USE; } /* Position and mask entry */ pos = mpc83xx_ipic_mask_position_table [mask_vector]; mask_entry = &mpc83xx_ipic_prio2mask [vector]; /* Mask register and position */ if (pos < 32) { mask_reg = &mask_entry->simsr_mask [0]; } else if (pos < 64) { pos -= 32; mask_reg = &mask_entry->simsr_mask [1]; } else if (pos < 96) { pos -= 64; mask_reg = &mask_entry->semsr_mask; } else if (pos < 128) { pos -= 96; mask_reg = &mask_entry->sermr_mask; } else { return RTEMS_NOT_IMPLEMENTED; } /* Mask or unmask */ if (mask) { rtems_interrupt_disable( level); *mask_reg &= ~(1 << pos); rtems_interrupt_enable( level); } else { rtems_interrupt_disable( level); *mask_reg |= 1 << pos; rtems_interrupt_enable( level); } return RTEMS_SUCCESSFUL; }
rtems_status_code mpc83xx_ipic_set_highest_priority_interrupt( rtems_vector_number vector, int type) { rtems_interrupt_level level; uint32_t reg = 0; if (!MPC83XX_IPIC_IS_VALID_VECTOR( vector)) { return RTEMS_INVALID_NUMBER; } else if (type < 0 || type > MPC83XX_IPIC_INTERRUPT_CRITICAL) { return RTEMS_INVALID_NUMBER; } rtems_interrupt_disable( level); reg = mpc83xx.ipic.sicfr; mpc83xx.ipic.sicfr = (reg & ~0x7f000300) | (vector << 24) | (type << 8); rtems_interrupt_enable( level); return RTEMS_SUCCESSFUL; }
rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum) { rtems_vector_number vecnum = irqnum - BSP_IPIC_IRQ_LOWEST_OFFSET; const BSP_isrc_rsc_t *rsc_ptr; if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) { rsc_ptr = &mpc83xx_ipic_isrc_rsc [vecnum]; if (rsc_ptr->mask_reg != NULL) { uint32_t bit = 1U << (31 - rsc_ptr->bit_num); rtems_interrupt_level level; rtems_interrupt_disable(level); *(rsc_ptr->mask_reg) &= ~bit; rtems_interrupt_enable(level); } } return RTEMS_SUCCESSFUL; }
/* * IRQ Handler: this is called from the primary exception dispatcher */ static int BSP_irq_handle_at_ipic( unsigned excNum) { int32_t vecnum; mpc83xx_ipic_mask_t mask_save; const mpc83xx_ipic_mask_t *mask_ptr; uint32_t msr = 0; rtems_interrupt_level level; /* Get vector number */ switch (excNum) { case ASM_EXT_VECTOR: vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.sivcr); break; case ASM_E300_SYSMGMT_VECTOR: vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.smvcr); break; case ASM_E300_CRIT_VECTOR: vecnum = MPC83xx_VCR_TO_VEC( mpc83xx.ipic.scvcr); break; default: return 1; } /* * Check the vector number, mask lower priority interrupts, enable * exceptions and dispatch the handler. */ if (MPC83XX_IPIC_IS_VALID_VECTOR( vecnum)) { #ifdef GEN83XX_ENABLE_INTERRUPT_NESTING mask_ptr = &mpc83xx_ipic_prio2mask [vecnum]; rtems_interrupt_disable( level); /* Save current mask registers */ mask_save.simsr_mask [0] = mpc83xx.ipic.simsr [0]; mask_save.simsr_mask [1] = mpc83xx.ipic.simsr [1]; mask_save.semsr_mask = mpc83xx.ipic.semsr; mask_save.sermr_mask = mpc83xx.ipic.sermr; /* Mask all lower priority interrupts */ mpc83xx.ipic.simsr [0] &= mask_ptr->simsr_mask [0]; mpc83xx.ipic.simsr [1] &= mask_ptr->simsr_mask [1]; mpc83xx.ipic.semsr &= mask_ptr->semsr_mask; mpc83xx.ipic.sermr &= mask_ptr->sermr_mask; rtems_interrupt_enable( level); /* Enable all interrupts */ if (excNum != ASM_E300_CRIT_VECTOR) { msr = ppc_external_exceptions_enable(); } #endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */ /* Dispatch interrupt handlers */ bsp_interrupt_handler_dispatch( vecnum + BSP_IPIC_IRQ_LOWEST_OFFSET); #ifdef GEN83XX_ENABLE_INTERRUPT_NESTING /* Restore machine state */ if (excNum != ASM_E300_CRIT_VECTOR) { ppc_external_exceptions_disable( msr); } /* Restore initial masks */ rtems_interrupt_disable( level); mpc83xx.ipic.simsr [0] = mask_save.simsr_mask [0]; mpc83xx.ipic.simsr [1] = mask_save.simsr_mask [1]; mpc83xx.ipic.semsr = mask_save.semsr_mask; mpc83xx.ipic.sermr = mask_save.sermr_mask; rtems_interrupt_enable( level); #endif /* GEN83XX_ENABLE_INTERRUPT_NESTING */ } else { bsp_interrupt_handler_default( vecnum); } return 0; }