| 1 | /*********************************************************************** |
|---|
| 2 | * |
|---|
| 3 | * MODULE: int1.c |
|---|
| 4 | * |
|---|
| 5 | * PURPOSE: CPU and External Level 1 Interrupt Handler for |
|---|
| 6 | * the BCM97038. |
|---|
| 7 | * |
|---|
| 8 | ***********************************************************************/ |
|---|
| 9 | #include "int1.h" |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | /*********************************************************************** |
|---|
| 13 | * Local data structures |
|---|
| 14 | ***********************************************************************/ |
|---|
| 15 | typedef struct |
|---|
| 16 | { |
|---|
| 17 | FN_L1_ISR isr; |
|---|
| 18 | void *param1; |
|---|
| 19 | int param2; |
|---|
| 20 | } Int1Vector; |
|---|
| 21 | |
|---|
| 22 | |
|---|
| 23 | /*********************************************************************** |
|---|
| 24 | * Local #define's |
|---|
| 25 | ***********************************************************************/ |
|---|
| 26 | #define INT1_GET_REG_NUM(id) ((((id)&0xe00) >> 9) | (((id)&0xe0) >> 5)) |
|---|
| 27 | #define INT1_GET_BIT_NUM(id) ((id)&0x1f) |
|---|
| 28 | #define INT1_MAX_VECTORS 96 |
|---|
| 29 | |
|---|
| 30 | |
|---|
| 31 | /*********************************************************************** |
|---|
| 32 | * Static variables |
|---|
| 33 | ***********************************************************************/ |
|---|
| 34 | static Int1Control *CpuInt1Control = CPUINT1C; |
|---|
| 35 | static Int1Vector CpuInt1VectorTable[INT1_MAX_VECTORS]; |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | /*********************************************************************** |
|---|
| 39 | * void CPUINT1_SetInt1Control() |
|---|
| 40 | * |
|---|
| 41 | * Set the interrupt control structure. Normally it is CPUINT1C. |
|---|
| 42 | * For linux user mode, it should be set to point to a user |
|---|
| 43 | * structure. If a NULL is passed to this function, it will |
|---|
| 44 | * use set the control structure to CPUINT1C. |
|---|
| 45 | ***********************************************************************/ |
|---|
| 46 | void CPUINT1_SetInt1Control(Int1Control *int1c) |
|---|
| 47 | { |
|---|
| 48 | if (int1c) |
|---|
| 49 | CpuInt1Control = int1c; |
|---|
| 50 | else CpuInt1Control = CPUINT1C; |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | |
|---|
| 54 | /*********************************************************************** |
|---|
| 55 | * void CPUINT1_SetInt1ControlAddr() |
|---|
| 56 | * |
|---|
| 57 | * Get the interrupt control structure address. |
|---|
| 58 | ***********************************************************************/ |
|---|
| 59 | unsigned long CPUINT1_GetInt1ControlAddr(void) |
|---|
| 60 | { |
|---|
| 61 | return (unsigned long) CpuInt1Control; |
|---|
| 62 | } |
|---|
| 63 | |
|---|
| 64 | |
|---|
| 65 | /*********************************************************************** |
|---|
| 66 | * void CPUINT1_Isr() |
|---|
| 67 | * |
|---|
| 68 | * Main interrupt handler: Handle all CPU L1 interrupts |
|---|
| 69 | ***********************************************************************/ |
|---|
| 70 | void CPUINT1_Isr(void) |
|---|
| 71 | { |
|---|
| 72 | unsigned long IntrW0Status; |
|---|
| 73 | unsigned long IntrW1Status; |
|---|
| 74 | unsigned long IntrW2Status; |
|---|
| 75 | unsigned long IntrW0MaskStatus; |
|---|
| 76 | unsigned long IntrW1MaskStatus; |
|---|
| 77 | unsigned long IntrW2MaskStatus; |
|---|
| 78 | Int1Vector *vec; |
|---|
| 79 | int i; |
|---|
| 80 | |
|---|
| 81 | if (((IntrW2Status=CpuInt1Control->IntrW2Status) |
|---|
| 82 | & ~(IntrW2MaskStatus=CpuInt1Control->IntrW2MaskStatus))) |
|---|
| 83 | { |
|---|
| 84 | IntrW2Status &= ~IntrW2MaskStatus; |
|---|
| 85 | |
|---|
| 86 | for (i = 64; i < 96; i++) |
|---|
| 87 | { |
|---|
| 88 | if (IntrW2Status & 0x1) |
|---|
| 89 | { |
|---|
| 90 | vec = &(CpuInt1VectorTable[i]); |
|---|
| 91 | if (vec->isr!=0) |
|---|
| 92 | vec->isr(vec->param1, vec->param2); |
|---|
| 93 | } |
|---|
| 94 | IntrW2Status >>= 1; |
|---|
| 95 | } |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | if (((IntrW1Status=CpuInt1Control->IntrW1Status) |
|---|
| 99 | & ~(IntrW1MaskStatus=CpuInt1Control->IntrW1MaskStatus))) |
|---|
| 100 | { |
|---|
| 101 | IntrW1Status &= ~IntrW1MaskStatus; |
|---|
| 102 | |
|---|
| 103 | for (i = 32; i < 64; i++) |
|---|
| 104 | { |
|---|
| 105 | if (IntrW1Status & 0x1) |
|---|
| 106 | { |
|---|
| 107 | vec = &(CpuInt1VectorTable[i]); |
|---|
| 108 | if (vec->isr!=0) |
|---|
| 109 | vec->isr(vec->param1, vec->param2); |
|---|
| 110 | } |
|---|
| 111 | IntrW1Status >>= 1; |
|---|
| 112 | } |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | if (((IntrW0Status=CpuInt1Control->IntrW0Status) |
|---|
| 116 | & ~(IntrW0MaskStatus=CpuInt1Control->IntrW0MaskStatus))) |
|---|
| 117 | { |
|---|
| 118 | IntrW0Status &= ~IntrW0MaskStatus; |
|---|
| 119 | |
|---|
| 120 | for (i = 0; i < 32; i++) |
|---|
| 121 | { |
|---|
| 122 | if (IntrW0Status & 0x1) |
|---|
| 123 | { |
|---|
| 124 | vec = &(CpuInt1VectorTable[i]); |
|---|
| 125 | if (vec->isr!=0) |
|---|
| 126 | vec->isr(vec->param1, vec->param2); |
|---|
| 127 | } |
|---|
| 128 | IntrW0Status >>= 1; |
|---|
| 129 | } |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | |
|---|
| 133 | |
|---|
| 134 | /*********************************************************************** |
|---|
| 135 | * void CPUINT1_Disable() |
|---|
| 136 | * |
|---|
| 137 | * Disables CPU or external interrupt specified by 'intId'. Valid |
|---|
| 138 | * intId values/mnemonics can be found in int1.h. |
|---|
| 139 | ***********************************************************************/ |
|---|
| 140 | void CPUINT1_Disable(unsigned long intId) |
|---|
| 141 | { |
|---|
| 142 | unsigned char reg_num = INT1_GET_REG_NUM(intId); |
|---|
| 143 | unsigned char bit_num = INT1_GET_BIT_NUM(intId); |
|---|
| 144 | |
|---|
| 145 | if (reg_num > 1) |
|---|
| 146 | CpuInt1Control->IntrW2MaskSet = 0x1 << bit_num; |
|---|
| 147 | else if (reg_num == 1) |
|---|
| 148 | CpuInt1Control->IntrW1MaskSet = 0x1 << bit_num; |
|---|
| 149 | else if (reg_num == 0) |
|---|
| 150 | CpuInt1Control->IntrW0MaskSet = 0x1 << bit_num; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | |
|---|
| 154 | /*********************************************************************** |
|---|
| 155 | * void CPUINT1_Enable() |
|---|
| 156 | * |
|---|
| 157 | * Enables the CPU or external interrupt specified by 'intId'. Valid |
|---|
| 158 | * intId values/mnemonics can be found in int1.h. |
|---|
| 159 | ***********************************************************************/ |
|---|
| 160 | void CPUINT1_Enable(unsigned long intId) |
|---|
| 161 | { |
|---|
| 162 | |
|---|
| 163 | unsigned char reg_num = INT1_GET_REG_NUM(intId); |
|---|
| 164 | unsigned char bit_num = INT1_GET_BIT_NUM(intId); |
|---|
| 165 | |
|---|
| 166 | if (reg_num > 1) |
|---|
| 167 | CpuInt1Control->IntrW2MaskClear = 0x1 << bit_num; |
|---|
| 168 | else if (reg_num == 1) |
|---|
| 169 | CpuInt1Control->IntrW1MaskClear = 0x1 << bit_num; |
|---|
| 170 | else if (reg_num == 0) |
|---|
| 171 | CpuInt1Control->IntrW0MaskClear = 0x1 << bit_num; |
|---|
| 172 | |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | /*********************************************************************** |
|---|
| 177 | * int CPUINT1_ConnectIsr() |
|---|
| 178 | * |
|---|
| 179 | * Maps CPU or external interrupts. Takes the ISR function pointer |
|---|
| 180 | * 'pfunc' and the parameters 'param1' and 'param2' and stores the |
|---|
| 181 | * values in a vector table, indexed by 'intId'. 'param1' and |
|---|
| 182 | * 'param2' will be passed as parameters to the function 'pfunc'. |
|---|
| 183 | * Valid intId values/mnemonics can be found in int1.h. |
|---|
| 184 | ***********************************************************************/ |
|---|
| 185 | int CPUINT1_ConnectIsr(unsigned long intId, FN_L1_ISR pfunc, |
|---|
| 186 | void *param1, int param2) |
|---|
| 187 | { |
|---|
| 188 | unsigned char reg_num = INT1_GET_REG_NUM(intId); |
|---|
| 189 | unsigned char bit_num = INT1_GET_BIT_NUM(intId); |
|---|
| 190 | |
|---|
| 191 | |
|---|
| 192 | if( reg_num == 1 ) |
|---|
| 193 | { |
|---|
| 194 | /* This for interrupt in W1 register */ |
|---|
| 195 | intId = 32 + bit_num; |
|---|
| 196 | }else if( reg_num > 1 ) |
|---|
| 197 | { |
|---|
| 198 | /* This for interrupt in W1 register */ |
|---|
| 199 | intId = 64 + bit_num; |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | if (intId > INT1_MAX_VECTORS) |
|---|
| 203 | return 0; |
|---|
| 204 | CpuInt1VectorTable[intId].isr = pfunc; |
|---|
| 205 | CpuInt1VectorTable[intId].param1 = param1; |
|---|
| 206 | CpuInt1VectorTable[intId].param2 = param2; |
|---|
| 207 | |
|---|
| 208 | return (int) pfunc; |
|---|
| 209 | } |
|---|
| 210 | |
|---|
| 211 | #ifdef ACB612 |
|---|
| 212 | /*********************************************************************** |
|---|
| 213 | * void CPUINT1_Isr() |
|---|
| 214 | * |
|---|
| 215 | * Main interrupt handler: Handle all CPU L1 interrupts |
|---|
| 216 | ***********************************************************************/ |
|---|
| 217 | void CPUINT1_Isr_ex(int bit) |
|---|
| 218 | { |
|---|
| 219 | Int1Vector *vec; |
|---|
| 220 | |
|---|
| 221 | if (8 != bit) { |
|---|
| 222 | return; |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | vec = &(CpuInt1VectorTable[bit]); |
|---|
| 226 | if (vec->isr!=0) |
|---|
| 227 | vec->isr(vec->param1, vec->param2); |
|---|
| 228 | } |
|---|
| 229 | #endif |
|---|
| 230 | |
|---|