10 * Interrupt Service Routine information, one for each interrupt that
11 * is known to the CPU. A single CPU-level interrupt is sometimes used
12 * for multiple interrupts. For example, all GPIO interrupts share a
13 * single "interrupt number" and all low frequency timers share a single
16 * Index into this table is a platform-dependent interrupt A_INUM_* number.
19 A_isr_t isr; /* function to call */
20 void *isr_arg; /* argument to pass */
21 } cmnos_isr_info[NUM_DIRECT_INTR];
25 //int cmnos_invalid_isr_count; /* Track these for debug purposes */
26 LOCAL uint32_t cmnos_enabled_interrupts = 0; /* Shadows enabled interrupts */
29 LOCAL uint32_t cmnos_intr_dummy(void *pParm)
31 // dummy function in case any intr coming calling the null and crash
36 * initialize all interrupt to diable, and setup all callback to dummy function
38 * p.s these are only level2 interrupt
45 // disable all at init
46 cmnos_enabled_interrupts = 0;
48 // install the dummy function
49 for(i=0; i<NUM_DIRECT_INTR; i++)
50 cmnos_isr_info[i].isr = cmnos_intr_dummy;
52 // set intrenable to disable all
53 A_INTR_SET_INTRENABLE(cmnos_enabled_interrupts);
59 cmnos_intr_mask_inum(uint32_t inum)
61 A_old_intr_t old_intr;
65 A_INTR_DISABLE(&old_intr);
66 oldval = A_INTR_GET_INTRENABLE();
67 cmnos_enabled_interrupts &= ~mask;
69 A_INTR_SET_INTRENABLE(oldval);
70 A_INTR_RESTORE(old_intr);
74 cmnos_intr_unmask_inum(uint32_t inum)
76 A_old_intr_t old_intr;
78 int unmask = 1 << inum;
80 A_INTR_DISABLE(&old_intr);
81 oldval = A_INTR_GET_INTRENABLE();
82 cmnos_enabled_interrupts |= unmask;
83 // if (!pending_dsr) {
86 A_INTR_SET_INTRENABLE(oldval);
87 A_INTR_RESTORE(old_intr);
92 cmnos_intr_attach_isr(uint32_t inum, A_isr_t isr, void *arg)
94 A_old_intr_t old_intr;
96 A_ASSERT(inum < NUM_DIRECT_INTR);
97 A_ASSERT(isr != NULL);
99 A_INTR_DISABLE(&old_intr);
101 cmnos_isr_info[inum].isr = isr;
102 cmnos_isr_info[inum].isr_arg = arg;
104 A_INTR_RESTORE(old_intr);
108 * Invoke the ISR corresponding to an interrupt number.
109 * Note that we expect interrupts for the given interrupt
110 * number to be blocked when this function is called. In
111 * fact, current ISRs assume that ALL non-fatal interrupts
112 * are blocked, and this allows the ISRs to avoid excessive
113 * calls to A_INTR_DISABLE/RESTORE which would otherwise be
114 * needed around calls to A_INTR_SET_INTRENABLE and such.
117 cmnos_intr_invoke_isr(uint32_t inum)
119 A_ASSERT(inum < NUM_DIRECT_INTR);
120 A_ASSERT(cmnos_isr_info[inum].isr != NULL);
122 // A_PRINTF("cmnos_intr_invoke_isr %d\n", inum);
124 return cmnos_isr_info[inum].isr(cmnos_isr_info[inum].isr_arg);
128 * NB: Whenever an "inum" is passed to an intr API, it is an A_INUM_*.
131 cmnos_intr_module_install(struct intr_api *tbl)
133 tbl->_intr_init = cmnos_intr_init;
134 tbl->_intr_invoke_isr = cmnos_intr_invoke_isr;
135 tbl->_intr_attach_isr = cmnos_intr_attach_isr;
136 tbl->_intr_mask_inum = cmnos_intr_mask_inum;
137 tbl->_intr_unmask_inum = cmnos_intr_unmask_inum;
140 * Note: These are all supplied elsewhere with platform-specific functions:
141 * tbl->_get_intrenable
142 * tbl->_set_intrenable
143 * tbl->_get_intrpending
144 * tbl->_unblock_all_intrlvl
149 #endif /* SYSTEM_MODULE_INTR */