Changeset d0b7c4e6 in rtems for c/src/exec/score/cpu/hppa1.1/cpu.c
- Timestamp:
- 04/22/96 16:30:02 (28 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- f581163a
- Parents:
- 767a6c6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
c/src/exec/score/cpu/hppa1.1/cpu.c
r767a6c6 rd0b7c4e6 20 20 #include <rtems/system.h> 21 21 #include <rtems/score/isr.h> 22 void hppa_cpu_halt(unsigned32 the_error); 22 23 23 void hppa_external_interrupt_initialize(void); 24 void hppa_external_interrupt_enable(unsigned32); 25 void hppa_external_interrupt_disable(unsigned32); 26 void hppa_external_interrupt(unsigned32, CPU_Interrupt_frame *); 27 void hppa_cpu_halt(unsigned32); 24 25 /*PAGE 26 * 27 * _CPU_ISR_install_raw_handler 28 */ 29 30 void _CPU_ISR_install_raw_handler( 31 unsigned32 vector, 32 proc_ptr new_handler, 33 proc_ptr *old_handler 34 ) 35 { 36 /* 37 * This is unsupported. For HPPA this function is handled by BSP 38 */ 39 40 _CPU_Fatal_halt( 0xdeaddead ); 41 } 42 43 28 44 29 45 /* 30 * The first level interrupt handler for first 32 interrupts/traps. 31 * Indexed by vector; generally each entry is _Generic_ISR_Handler. 32 * Some TLB traps may have their own first level handler. 46 * This is the default handler which is called if 47 * _CPU_ISR_install_vector() has not been called for the 48 * specified vector. It simply forwards onto the spurious 49 * handler defined in the cpu-table. 33 50 */ 34 51 35 extern void _Generic_ISR_Handler(void); 36 unsigned32 HPPA_first_level_interrupt_handler[HPPA_INTERNAL_INTERRUPTS]; 52 static ISR_Handler 53 hppa_interrupt_report_spurious(ISR_Vector_number vector, 54 void* rtems_isr_frame) /* HPPA extension */ 55 { 56 57 /* 58 * If the CPU table defines a spurious_handler, then 59 * call it. If the handler returns halt. 60 */ 61 if ( _CPU_Table.spurious_handler ) 62 _CPU_Table.spurious_handler(vector, rtems_isr_frame); 63 64 hppa_cpu_halt(vector); 65 } 66 67 68 /*PAGE 69 * 70 * _CPU_ISR_Get_level 71 */ 72 73 unsigned32 _CPU_ISR_Get_level(void) 74 { 75 int level; 76 HPPA_ASM_SSM(0, level); /* change no bits; just get copy */ 77 if (level & HPPA_PSW_I) 78 return 0; 79 return 1; 80 } 81 82 /*PAGE 83 * 84 * _CPU_ISR_install_vector 85 * 86 * This kernel routine installs the RTEMS handler for the 87 * specified vector. The handler is a C callable routine. 88 * 89 * Input parameters: 90 * vector - interrupt vector number 91 * old_handler - former ISR for this vector number 92 * new_handler - replacement ISR for this vector number 93 * 94 * Output parameters: NONE 95 * 96 */ 97 98 void _CPU_ISR_install_vector( 99 unsigned32 vector, 100 proc_ptr new_handler, 101 proc_ptr *old_handler 102 ) 103 { 104 *old_handler = _ISR_Vector_table[vector]; 105 106 _ISR_Vector_table[vector] = new_handler; 107 } 37 108 38 109 /* _CPU_Initialize … … 52 123 { 53 124 register unsigned8 *fp_context; 54 unsigned32 iva;55 unsigned32 iva_table;56 125 int i; 57 58 extern void IVA_Table(void); 126 proc_ptr old_handler; 59 127 60 128 /* … … 74 142 75 143 /* 76 * Init the first level interrupt handlers77 */78 79 for (i=0; i <= HPPA_INTERNAL_INTERRUPTS; i++)80 HPPA_first_level_interrupt_handler[i] = (unsigned32) _Generic_ISR_Handler;81 82 /*83 144 * Init the 2nd level interrupt handlers 84 145 */ 85 146 86 for (i=0; i <= CPU_INTERRUPT_NUMBER_OF_VECTORS; i++) 87 _ISR_Vector_table[i] = (ISR_Handler_entry) hppa_cpu_halt; 88 89 /* 90 * Stabilize the interrupt stuff 91 */ 92 93 (void) hppa_external_interrupt_initialize(); 94 95 /* 96 * Set the IVA to point to physical address of the IVA_Table 97 */ 98 99 iva_table = (unsigned32) IVA_Table; 100 #if defined(hppa1_1) 101 /* 102 * HACK: (from PA72000 TRM, page 4-19) 103 * "The hardware TLB miss handler will never attempt to service 104 * a non-access TLB miss or a TLB protection violation. It 105 * will only attempt to service TLB accesses that would cause 106 * Trap Numbers 6 (Instruction TLB miss) and 15 (Data TLB miss)." 107 * 108 * The LPA instruction is used to translate a virtual address to 109 * a physical address, however, if the requested virtual address 110 * is not currently resident in the TLB, the hardware TLB miss 111 * handler will NOT insert it. In this situation Trap Number 112 * #17 is invoked (Non-access Data TLB miss fault). 113 * 114 * To work around this, a dummy data access is first performed 115 * to the virtual address prior to the LPA. The dummy access 116 * causes the TLB entry to be inserted (if not already present) 117 * and then the following LPA instruction will not generate 118 * a non-access data TLB miss fault. 119 * 120 * It is unclear whether or not this behaves the same way for 121 * the PA8000. 122 * 123 */ 124 iva = *(volatile unsigned32 *)iva_table; /* dummy access */ 125 #endif 126 127 HPPA_ASM_LPA(0, iva_table, iva); 128 set_iva(iva); 147 for (i=0; i < CPU_INTERRUPT_NUMBER_OF_VECTORS; i++) 148 _CPU_ISR_install_vector(i, 149 hppa_interrupt_report_spurious, 150 &old_handler); 129 151 130 152 _CPU_Table = *cpu_table; 153 131 154 } 132 155 133 /*PAGE134 *135 * _CPU_ISR_Get_level136 */137 138 unsigned32 _CPU_ISR_Get_level(void)139 {140 int level;141 HPPA_ASM_SSM(0, level); /* change no bits; just get copy */142 if (level & HPPA_PSW_I)143 return 0;144 return 1;145 }146 147 /*PAGE148 *149 * _CPU_ISR_install_raw_handler150 */151 152 void _CPU_ISR_install_raw_handler(153 unsigned32 vector,154 proc_ptr new_handler,155 proc_ptr *old_handler156 )157 {158 /*159 * This is unsupported.160 */161 162 _CPU_Fatal_halt( 0xdeaddead );163 }164 165 /*PAGE166 *167 * _CPU_ISR_install_vector168 *169 * This kernel routine installs the RTEMS handler for the170 * specified vector.171 *172 * Input parameters:173 * vector - interrupt vector number174 * old_handler - former ISR for this vector number175 * new_handler - replacement ISR for this vector number176 *177 * Output parameters: NONE178 *179 */180 181 /*182 * HPPA has 8w for each vector instead of an address to jump to.183 * We put the actual ISR address in '_ISR_vector_table'. This will184 * be pulled by the code in the vector.185 */186 187 void _CPU_ISR_install_vector(188 unsigned32 vector,189 proc_ptr new_handler,190 proc_ptr *old_handler191 )192 {193 *old_handler = _ISR_Vector_table[vector];194 195 _ISR_Vector_table[vector] = new_handler;196 197 if (vector >= HPPA_INTERRUPT_EXTERNAL_BASE)198 {199 unsigned32 external_vector;200 201 external_vector = vector - HPPA_INTERRUPT_EXTERNAL_BASE;202 if (new_handler)203 hppa_external_interrupt_enable(external_vector);204 else205 /* XXX this can never happen due to _ISR_Is_valid_user_handler */206 hppa_external_interrupt_disable(external_vector);207 }208 }209 210 211 /*212 * Support for external and spurious interrupts on HPPA213 *214 * TODO:215 * Count interrupts216 * make sure interrupts disabled properly217 */218 219 #define DISMISS(mask) set_eirr(mask)220 #define DISABLE(mask) set_eiem(get_eiem() & ~(mask))221 #define ENABLE(mask) set_eiem(get_eiem() | (mask))222 #define VECTOR_TO_MASK(v) (1 << (31 - (v)))223 224 /*225 * Init the external interrupt scheme226 * called by bsp_start()227 */228 229 void230 hppa_external_interrupt_initialize(void)231 {232 proc_ptr ignore;233 234 /* mark them all unused */235 DISABLE(~0);236 DISMISS(~0);237 238 /* install the external interrupt handler */239 _CPU_ISR_install_vector(240 HPPA_INTERRUPT_EXTERNAL_INTERRUPT,241 (proc_ptr)hppa_external_interrupt, &ignore242 );243 }244 245 /*246 * Enable a specific external interrupt247 */248 249 void250 hppa_external_interrupt_enable(unsigned32 v)251 {252 unsigned32 isrlevel;253 254 _CPU_ISR_Disable(isrlevel);255 ENABLE(VECTOR_TO_MASK(v));256 _CPU_ISR_Enable(isrlevel);257 }258 259 /*260 * Does not clear or otherwise affect any pending requests261 */262 263 void264 hppa_external_interrupt_disable(unsigned32 v)265 {266 unsigned32 isrlevel;267 268 _CPU_ISR_Disable(isrlevel);269 DISABLE(VECTOR_TO_MASK(v));270 _CPU_ISR_Enable(isrlevel);271 }272 273 void274 hppa_external_interrupt_spurious_handler(unsigned32 vector,275 CPU_Interrupt_frame *iframe)276 {277 /* XXX should not be printing :)278 printf("spurious external interrupt: %d at pc 0x%x; disabling\n",279 vector, iframe->Interrupt.pcoqfront);280 */281 }282 283 void284 hppa_external_interrupt_report_spurious(unsigned32 spurious_mask,285 CPU_Interrupt_frame *iframe)286 {287 int v;288 for (v=0; v < HPPA_EXTERNAL_INTERRUPTS; v++)289 if (VECTOR_TO_MASK(v) & spurious_mask)290 {291 DISMISS(VECTOR_TO_MASK(v));292 DISABLE(VECTOR_TO_MASK(v));293 hppa_external_interrupt_spurious_handler(v, iframe);294 }295 DISMISS(spurious_mask);296 }297 298 299 /*300 * External interrupt handler.301 * This is installed as cpu interrupt handler for302 * HPPA_INTERRUPT_EXTERNAL_INTERRUPT. It vectors out to303 * specific external interrupt handlers.304 */305 306 void307 hppa_external_interrupt(unsigned32 vector,308 CPU_Interrupt_frame *iframe)309 {310 unsigned32 mask;311 unsigned32 *vp, *max_vp;312 unsigned32 external_vector;313 unsigned32 global_vector;314 hppa_rtems_isr_entry handler;315 316 max_vp = &_CPU_Table.external_interrupt[_CPU_Table.external_interrupts];317 while ( (mask = (get_eirr() & get_eiem())) )318 {319 for (vp = _CPU_Table.external_interrupt; (vp < max_vp) && mask; vp++)320 {321 unsigned32 m;322 323 external_vector = *vp;324 global_vector = external_vector + HPPA_INTERRUPT_EXTERNAL_BASE;325 m = VECTOR_TO_MASK(external_vector);326 handler = (hppa_rtems_isr_entry) _ISR_Vector_table[global_vector];327 if ((m & mask) && handler)328 {329 DISMISS(m);330 mask &= ~m;331 handler(global_vector, iframe);332 }333 }334 335 if (mask != 0) {336 if ( _CPU_Table.spurious_handler )337 {338 handler = (hppa_rtems_isr_entry) _CPU_Table.spurious_handler;339 handler(mask, iframe);340 }341 else342 hppa_external_interrupt_report_spurious(mask, iframe);343 }344 }345 }346 156 347 157 /* … … 352 162 * Later on, this will allow us to return to the prom. 353 163 * For now, we just ignore 'type_of_halt' 164 * 165 * XXX 166 * NOTE: for gcc, this function must be at the bottom 167 * of the file, that is because if it is at the top 168 * of the file, gcc will inline it's calls. Since 169 * the function uses the HPPA_ASM_LABEL() macro, when 170 * gcc inlines it, you get two definitions of the same 171 * label name, which is an assembly error. 354 172 */ 173 355 174 356 175 void … … 361 180 _CPU_ISR_Disable(isrlevel); 362 181 182 /* 183 * XXXXX NOTE: This label is only needed that that when 184 * the simulator stops, it shows the label name specified 185 */ 363 186 HPPA_ASM_LABEL("_hppa_cpu_halt"); 364 HPPA_ASM_BREAK( 1, 0);187 HPPA_ASM_BREAK(0, 0); 365 188 } 189
Note: See TracChangeset
for help on using the changeset viewer.