Changeset d0b7c4e6 in rtems
- Timestamp:
- 04/22/96 16:30:02 (27 years ago)
- Branches:
- 4.10, 4.11, 4.8, 4.9, 5, master
- Children:
- f581163a
- Parents:
- 767a6c6
- Files:
-
- 5 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 -
c/src/exec/score/cpu/hppa1.1/cpu.h
r767a6c6 rd0b7c4e6 217 217 void (*postdriver_hook)( void ); 218 218 void (*idle_task)( void ); 219 220 /* HPPA simulator is slow enough; don't waste time221 * zeroing memory that is already zero222 */223 219 boolean do_zero_of_workspace; 224 225 220 unsigned32 interrupt_stack_size; 226 221 unsigned32 extra_mpci_receive_server_stack; 227 228 /* 229 * Control of external interrupts. 230 * We keep a table of external vector numbers (0 - 31) 231 * The table is sorted by priority, that is: the first entry 232 * in the table indicates the vector that is highest priorty. 233 * The handler function is stored in _ISR_Vector_Table[] and 234 * is set by rtems_interrupt_catch() 235 */ 236 237 unsigned32 external_interrupts; /* # of external interrupts we use */ 238 unsigned32 external_interrupt[HPPA_EXTERNAL_INTERRUPTS]; 222 void * (*stack_allocate_hook)( unsigned32 ); 223 void (*stack_free_hook)( void * ); 224 /* end of fields required on all CPUs */ 239 225 240 226 hppa_rtems_isr_entry spurious_handler; … … 250 236 EXTERN void *_CPU_Interrupt_stack_high; 251 237 252 /* entry points */253 void hppa_external_interrupt_spurious_handler(unsigned32, CPU_Interrupt_frame *);254 255 238 #endif /* ! ASM */ 256 239 … … 286 269 /* 287 270 * HPPA has 32 interrupts, then 32 external interrupts 288 * Rtems (_ISR_Vector_Table) is aware of the first 64 289 * A BSP may reserve more. 290 * 291 * External interrupts all come thru the same vector (4) 292 * The external handler is the only person aware of the other 293 * interrupts (genie, rhino, etc) 294 */ 295 296 #define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERRUPT_MAX) 271 * Rtems (_ISR_Vector_Table) is aware ONLY of the first 32 272 * The BSP is aware of the external interrupts and possibly more. 273 * 274 */ 275 276 #define CPU_INTERRUPT_NUMBER_OF_VECTORS (HPPA_INTERNAL_INTERRUPTS) 297 277 #define CPU_INTERRUPT_MAXIMUM_VECTOR_NUMBER (CPU_INTERRUPT_NUMBER_OF_VECTORS - 1) 298 278 -
c/src/exec/score/cpu/hppa1.1/cpu_asm.s
r767a6c6 rd0b7c4e6 1 # @(#)cpu_asm.S 1.7 - 95/09/212 #3 1 # 4 2 # TODO: … … 31 29 #include <rtems/score/cpu_asm.h> 32 30 #include <rtems/score/cpu.h> 33 34 31 #include <rtems/score/offsets.h> 35 32 … … 65 62 66 63 # PAGE^L 67 # void _ _Generic_ISR_Handler()64 # void _Generic_ISR_Handler() 68 65 # 69 66 # This routine provides the RTEMS interrupt management. 70 67 # 71 # NOTE:72 # Upon entry, the stack will contain a stack frame back to the73 # interrupted task. If dispatching is enabled, this is the74 # outer most interrupt, (and a context switch is necessary or75 # the current task has signals), then set up the stack to76 # transfer control to the interrupt dispatcher.77 #78 #79 68 # We jump here from the interrupt vector. 80 # The hardware has done some stuff for us:69 # The HPPA hardware has done some stuff for us: 81 70 # PSW saved in IPSW 82 71 # PSW set to 0 … … 90 79 # SHR 0 1 2 3 4 5 6 91 80 # 92 # Our vector stub did the following 93 # placed vector number is in r1 94 # 95 # stub 96 # r1 <- vector number 97 # save ipsw under rock 98 # ipsw = ipsw & ~1 -- disable ints 99 # save qregs under rock 100 # qra = _Generic_ISR_handler 101 # rfi 102 # 103 ################################################ 104 105 # Distinct Interrupt Entry Points 106 # 107 # The following macro and the 32 instantiations of the macro 108 # are necessary to determine which interrupt vector occurred. 109 # 110 # r9 is loaded with the vector number and then we jump to 111 # the first level interrupt handler. In most cases this 112 # is _Generic_ISR_Handler. In a few cases (such as TLB misc) 113 # it may be to some other entry point. 114 # 115 116 # table for first level interrupt handlers 117 .import HPPA_first_level_interrupt_handler, data 118 119 #define THANDLER(vector) \ 120 mtctl %r9, isr_r9 ! \ 121 mtctl %r8, isr_r8 ! \ 122 ldi vector, %r9 ! \ 123 ldil L%HPPA_first_level_interrupt_handler,%r8 ! \ 124 ldo R%HPPA_first_level_interrupt_handler(%r8),%r8 ! \ 125 ldwx,s %r9(%r8),%r8 ! \ 126 bv 0(%r8) ! \ 127 mfctl isr_r8, %r8 128 129 .align 4096 130 .EXPORT IVA_Table,ENTRY,PRIV_LEV=0 131 IVA_Table: 132 .PROC 133 .CALLINFO FRAME=0,NO_CALLS 134 .ENTRY 135 136 THANDLER(0) /* unused */ 137 138 THANDLER(HPPA_INTERRUPT_HIGH_PRIORITY_MACHINE_CHECK) 139 140 THANDLER(HPPA_INTERRUPT_POWER_FAIL) 141 142 THANDLER(HPPA_INTERRUPT_RECOVERY_COUNTER) 143 144 THANDLER(HPPA_INTERRUPT_EXTERNAL_INTERRUPT) 145 146 THANDLER(HPPA_INTERRUPT_LOW_PRIORITY_MACHINE_CHECK) 147 148 THANDLER(HPPA_INTERRUPT_INSTRUCTION_TLB_MISS) 149 150 THANDLER(HPPA_INTERRUPT_INSTRUCTION_MEMORY_PROTECTION) 151 152 THANDLER(HPPA_INTERRUPT_ILLEGAL_INSTRUCTION) 153 154 THANDLER(HPPA_INTERRUPT_BREAK_INSTRUCTION) 155 156 THANDLER(HPPA_INTERRUPT_PRIVILEGED_OPERATION) 157 158 THANDLER(HPPA_INTERRUPT_PRIVILEGED_REGISTER) 159 160 THANDLER(HPPA_INTERRUPT_OVERFLOW) 161 162 THANDLER(HPPA_INTERRUPT_CONDITIONAL) 163 164 THANDLER(HPPA_INTERRUPT_ASSIST_EXCEPTION) 165 166 THANDLER(HPPA_INTERRUPT_DATA_TLB_MISS) 167 168 THANDLER(HPPA_INTERRUPT_NON_ACCESS_INSTRUCTION_TLB_MISS) 169 170 THANDLER(HPPA_INTERRUPT_NON_ACCESS_DATA_TLB_MISS) 171 172 THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION) 173 174 THANDLER(HPPA_INTERRUPT_DATA_MEMORY_BREAK) 175 176 THANDLER(HPPA_INTERRUPT_TLB_DIRTY_BIT) 177 178 THANDLER(HPPA_INTERRUPT_PAGE_REFERENCE) 179 180 THANDLER(HPPA_INTERRUPT_ASSIST_EMULATION) 181 182 THANDLER(HPPA_INTERRUPT_HIGHER_PRIVILEGE_TRANSFER) 183 184 THANDLER(HPPA_INTERRUPT_LOWER_PRIVILEGE_TRANSFER) 185 186 THANDLER(HPPA_INTERRUPT_TAKEN_BRANCH) 187 188 THANDLER(HPPA_INTERRUPT_DATA_MEMORY_ACCESS_RIGHTS) 189 190 THANDLER(HPPA_INTERRUPT_DATA_MEMORY_PROTECTION_ID) 191 192 THANDLER(HPPA_INTERRUPT_UNALIGNED_DATA_REFERENCE) 193 194 THANDLER(HPPA_INTERRUPT_PERFORMANCE_MONITOR) 195 196 THANDLER(HPPA_INTERRUPT_INSTRUCTION_DEBUG) 197 198 THANDLER(HPPA_INTERRUPT_DATA_DEBUG) 199 200 .EXIT 201 .PROCEND 202 81 # Our vector stub (in the BSP) MUST have done the following: 82 # 83 # a) Saved the original %r9 into %isr_r9 (%cr25) 84 # b) Placed the vector number in %r9 85 # c) Was allowed to also destroy $isr_r8 (%cr26), 86 # but the stub was NOT allowed to destroy any other registers. 87 # 88 # The typical stub sequence (in the BSP) should look like this: 89 # 90 # a) mtctl %r9,isr_r9 ; (save r9 in cr25) 91 # b) ldi vector,%r9 ; (load constant vector number in r9) 92 # c) mtctl %r8,isr_r8 ; (save r8 in cr26) 93 # d) ldil L%MY_BSP_first_level_interrupt_handler,%r8 94 # e) ldo R%MY_BSP_first_level_interrupt_handler(%r8),%r8 95 # ; (point to BSP raw handler table) 96 # f) ldwx,s %r9(%r8),%r8 ; (load value from raw handler table) 97 # g) bv 0(%r8) ; (call raw handler: _Generic_ISR_Handler) 98 # h) mfctl isr_r8,%r8 ; (restore r8 from cr26 in delay slot) 99 # 100 # Optionally, steps (c) thru (h) _could_ be replaced with a single 101 # bl,n _Generic_ISR_Handler,%r0 102 # 103 # 104 # 203 105 .EXPORT _Generic_ISR_Handler,ENTRY,PRIV_LEV=0 204 106 _Generic_ISR_Handler: … … 236 138 # reg current value saved value 237 139 # ------------------------------------------------ 238 # arg0 scratch isr_arg0 (c tl)239 # r9 vector number isr_r9 (c tl)140 # arg0 scratch isr_arg0 (cr24) 141 # r9 vector number isr_r9 (cr25) 240 142 # 241 143 # Point to beginning of integer context and … … 278 180 # reg current value saved value 279 181 # ------------------------------------------------ 280 # arg0 scratch isr_arg0 (c tl)281 # r9 vector number isr_r9 (c tl)182 # arg0 scratch isr_arg0 (cr24) 183 # r9 vector number isr_r9 (cr25) 282 184 # 283 185 # Fix them … … 378 280 379 281 # load address of user handler 282 # Note: No error checking is done, it is assumed that the 283 # vector table contains a valid address or a stub 284 # spurious handler. 380 285 .import _ISR_Vector_table,data 381 286 ldil L%_ISR_Vector_table,%r8 … … 389 294 # and we are using a hard coded address from a table 390 295 # So... we fudge r2 ourselves (ala dynacall) 391 # 296 # arg0 = vector number, arg1 = ptr to rtems_interrupt_frame 392 297 copy %r9, %r26 393 298 .call ARGW0=GR, ARGW1=GR … … 405 310 ldw -4(sp), sp 406 311 407 # r3 -- &_ISR_Nest_level312 # r3 -- (most of) &_ISR_Nest_level 408 313 # r5 -- value _ISR_Nest_level 409 # r4 -- &_Thread_Dispatch_disable_level314 # r4 -- (most of) &_Thread_Dispatch_disable_level 410 315 # r6 -- value _Thread_Dispatch_disable_level 316 # r7 -- (most of) &_ISR_Signals_to_thread_executing 317 # r8 -- value _ISR_Signals_to_thread_executing 411 318 412 319 .import _ISR_Nest_level,data 413 320 ldil L%_ISR_Nest_level,%r3 414 ldo R%_ISR_Nest_level(%r3),%r3 415 ldw 0(%r3),%r5 321 ldw R%_ISR_Nest_level(%r3),%r5 416 322 417 323 .import _Thread_Dispatch_disable_level,data 418 324 ldil L%_Thread_Dispatch_disable_level,%r4 419 ldo R%_Thread_Dispatch_disable_level(%r4),%r4 420 ldw 0(%r4), %r6 325 ldw R%_Thread_Dispatch_disable_level(%r4),%r6 326 327 .import _ISR_Signals_to_thread_executing,data 328 ldil L%_ISR_Signals_to_thread_executing,%r7 421 329 422 330 # decrement isr nest level 423 331 addi -1, %r5, %r5 424 stw %r5, 0(%r3)332 stw %r5, R%_ISR_Nest_level(%r3) 425 333 426 334 # decrement dispatch disable level counter and, if not 0, go on 427 335 addi -1,%r6,%r6 428 336 comibf,= 0,%r6,isr_restore 429 stw %r6, 0(%r4)337 stw %r6, R%_Thread_Dispatch_disable_level(%r4) 430 338 431 339 # check whether or not a context switch is necessary … … 437 345 # check whether or not a context switch is necessary because an ISR 438 346 # sent signals to the interrupted task 439 .import _ISR_Signals_to_thread_executing,data 440 ldil L%_ISR_Signals_to_thread_executing,%r8 441 ldw R%_ISR_Signals_to_thread_executing(%r8),%r8 347 ldw R%_ISR_Signals_to_thread_executing(%r7),%r8 442 348 comibt,=,n 0,%r8,isr_restore 443 349 … … 451 357 452 358 ISR_dispatch: 359 stw %r0, R%_ISR_Signals_to_thread_executing(%r7) 360 453 361 ssm HPPA_PSW_I, %r0 454 362 -
c/src/exec/score/cpu/hppa1.1/hppa.h
r767a6c6 rd0b7c4e6 1 1 /* 2 * @(#)hppa.h 1.17 - 95/12/133 *4 *5 2 * Description: 6 3 * -
cpukit/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.