Changeset 4daebbd in rtems for cpukit/score/cpu/bfin/cpu_asm.S
 Timestamp:
 Aug 14, 2008, 3:25:14 PM (12 years ago)
 Branches:
 4.10, 4.11, 4.9, master
 Children:
 e73f9f6b
 Parents:
 b281e42
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

cpukit/score/cpu/bfin/cpu_asm.S
rb281e42 r4daebbd 5 5 * in assembly language 6 6 * 7 * Copyright (c) 2008 Kallisti Labs, Los Gatos, CA, USA 8 * written by Allan Hessenflow <allanh@kallisti.com> 9 * 10 * Based on earlier version: 11 * 7 12 * Copyright (c) 2006 by Atos Automacao Industrial Ltda. 8 * 9 * 13 * written by Alain Schaefer <alain.schaefer@easc.ch> 14 * and Antonio Giovanini <antonio@atos.com.br> 10 15 * 11 16 * The license and distribution terms for this file may be … … 15 20 * $Id$ 16 21 */ 17 18 22 23 19 24 #include <rtems/asm.h> 20 25 #include <rtems/score/cpu_asm.h> … … 25 30 #define HI(con32) (((con32) >> 16) & 0xFFFF) 26 31 32 33 #if 0 34 /* some debug routines */ 35 .globl __CPU_write_char; 36 __CPU_write_char: 37 p0.h = 0xffc0; 38 p0.l = 0x0400; 39 txWaitLoop: 40 r1 = w[p0 + 0x14]; 41 cc = bittst(r1, 5); 42 if !cc jump txWaitLoop; 43 w[p0 + 0x00] = r0; 44 rts; 45 46 .globl __CPU_write_crlf; 47 __CPU_write_crlf: 48 r0 = '\r'; 49 [sp] = rets; 50 call __CPU_write_char; 51 rets = [sp++]; 52 r0 = '\n'; 53 jump __CPU_write_char; 54 55 __CPU_write_space: 56 r0 = ' '; 57 jump __CPU_write_char; 58 59 .globl __CPU_write_nybble; 60 __CPU_write_nybble: 61 r1 = 0x0f; 62 r0 = r0 & r1; 63 r0 += '0'; 64 r1 = '9'; 65 cc = r0 <= r1; 66 if cc jump __CPU_write_char; 67 r0 += 'a'  '0'  10; 68 jump __CPU_write_char; 69 70 .globl __CPU_write_byte; 71 __CPU_write_byte: 72 [sp] = r0; 73 [sp] = rets; 74 r0 >>= 4; 75 call __CPU_write_nybble; 76 rets = [sp++]; 77 r0 = [sp++]; 78 jump __CPU_write_nybble; 79 80 __CPU_write_chawmp: 81 [sp] = r0; 82 [sp] = rets; 83 r0 >>= 8; 84 call __CPU_write_byte; 85 rets = [sp++]; 86 r0 = [sp++]; 87 jump __CPU_write_byte; 88 89 __CPU_write_gawble: 90 [sp] = r0; 91 [sp] = rets; 92 r0 >>= 16; 93 call __CPU_write_chawmp; 94 rets = [sp++]; 95 r0 = [sp++]; 96 jump __CPU_write_chawmp; 97 98 __CPU_dump_registers: 99 [sp] = rets; 100 [sp] = r0; 101 [sp] = r1; 102 [sp] = p0; 103 r0 = [sp + 8]; 104 call __CPU_write_gawble; 105 call __CPU_write_space; 106 r0 = [sp + 4]; 107 call __CPU_write_gawble; 108 call __CPU_write_space; 109 r0 = r2; 110 call __CPU_write_gawble; 111 call __CPU_write_space; 112 r0 = r3; 113 call __CPU_write_gawble; 114 call __CPU_write_space; 115 r0 = r4; 116 call __CPU_write_gawble; 117 call __CPU_write_space; 118 r0 = r5; 119 call __CPU_write_gawble; 120 call __CPU_write_space; 121 r0 = r6; 122 call __CPU_write_gawble; 123 call __CPU_write_space; 124 r0 = r7; 125 call __CPU_write_gawble; 126 call __CPU_write_crlf; 127 r0 = [sp]; 128 call __CPU_write_gawble; 129 call __CPU_write_space; 130 r0 = p1; 131 call __CPU_write_gawble; 132 call __CPU_write_space; 133 r0 = p2; 134 call __CPU_write_gawble; 135 call __CPU_write_space; 136 r0 = p3; 137 call __CPU_write_gawble; 138 call __CPU_write_space; 139 r0 = p4; 140 call __CPU_write_gawble; 141 call __CPU_write_space; 142 r0 = p5; 143 call __CPU_write_gawble; 144 call __CPU_write_space; 145 r0 = fp; 146 call __CPU_write_gawble; 147 call __CPU_write_space; 148 r0 = sp; 149 r0 += 16; 150 call __CPU_write_gawble; 151 call __CPU_write_crlf; 152 153 p0 = [sp++]; 154 r1 = [sp++]; 155 r0 = [sp++]; 156 rets = [sp++]; 157 rts; 158 159 .globl __CPU_Exception_handler; 160 __CPU_Exception_handler: 161 usp = sp; 162 sp.h = 0xffb0; 163 sp.l = 0x1000; 164 [sp] = (r7:0,p5:0); 165 166 r0 = 'x'; 167 call __CPU_write_char; 168 jump hcf; 169 170 171 .globl __CPU_Emulation_handler; 172 __CPU_Emulation_handler: 173 usp = sp; 174 sp.h = 0xffb0; 175 sp.l = 0x1000; 176 [sp] = (r7:0,p5:0); 177 178 r0 = 'e'; 179 call __CPU_write_char; 180 jump hcf; 181 182 .globl __CPU_Reset_handler; 183 __CPU_Reset_handler: 184 usp = sp; 185 sp.h = 0xffb0; 186 sp.l = 0x1000; 187 [sp] = (r7:0,p5:0); 188 189 r0 = 'r'; 190 call __CPU_write_char; 191 jump hcf; 192 193 .globl __CPU_NMI_handler; 194 __CPU_NMI_handler: 195 usp = sp; 196 sp.h = 0xffb0; 197 sp.l = 0x1000; 198 [sp] = (r7:0,p5:0); 199 200 r0 = 'n'; 201 call __CPU_write_char; 202 jump hcf; 203 204 .globl __CPU_Unhandled_Interrupt_handler; 205 __CPU_Unhandled_Interrupt_handler: 206 usp = sp; 207 sp.h = 0xffb0; 208 sp.l = 0x1000; 209 [sp] = (r7:0,p5:0); 210 211 call __CPU_write_crlf; 212 r0 = 'i'; 213 call __CPU_write_char; 214 p0.h = HI(IPEND); 215 p0.l = LO(IPEND); 216 r0 = [p0]; 217 call __CPU_write_chawmp; 218 jump hcf; 219 220 hcf: 221 idle; 222 jump hcf; 223 224 #endif 225 226 27 227 /* _CPU_Context_switch 28 228 * … … 32 232 * 33 233 * For now we simply save all registers. 34 * 234 * 35 235 */ 36 236 37 .globl __CPU_Context_switch 237 /* make sure this sequence stays in sync with the definition for 238 Context_Control in rtems/score/cpu.h */ 239 .globl __CPU_Context_switch 38 240 __CPU_Context_switch: 39 /* Start saving context R0 = current, R1=heir */ 40 /*save P0 first*/ 41 [FP+0x8] = P0; 42 P0 = R0; 43 [ P0 + R0_OFFSET ] = R0; 44 [ P0 + R1_OFFSET] = R1; 45 [ P0 + R2_OFFSET] = R2; 46 [ P0 + R4_OFFSET] = R4; 47 [ P0 + R3_OFFSET] = R3; 48 [ P0 + R5_OFFSET] = R5; 49 [ P0 + R6_OFFSET] = R6; 50 [ P0 + R7_OFFSET] = R7; 51 [ P0 + P1_OFFSET] = P1; 52 /* save the original value of P0 */ 53 P1 = [FP+0x8]; 54 [ P0 + P0_OFFSET] = P1; 55 [ P0 + P2_OFFSET] = P2; 56 [ P0 + P3_OFFSET] = P3; 57 [ P0 + P4_OFFSET] = P4; 58 [ P0 + P5_OFFSET] = P5; 59 [ P0 + FP_OFFSET] = FP; 60 [ P0 + SP_OFFSET] = SP; 61 62 /* save ASTAT */ 63 R0 = ASTAT; 64 [P0 + ASTAT_OFFSET] = R0; 65 66 /* save Loop Counters */ 67 R0 = LC0; 68 [P0 + LC0_OFFSET] = R0; 69 R0 = LC1; 70 [P0 + LC1_OFFSET] = R0; 71 72 /* save Accumulators */ 73 R0 = A0.W; 74 [P0 + A0W_OFFSET] = R0; 75 R0 = A0.X; 76 [P0 + A0X_OFFSET] = R0; 77 R0 = A1.W; 78 [P0 + A1W_OFFSET] = R0; 79 R0 = A1.X; 80 [P0 + A1X_OFFSET] = R0; 81 82 /* save Index Registers */ 83 R0 = I0; 84 [P0 + I0_OFFSET] = R0; 85 R0 = I1; 86 [P0 + I1_OFFSET] = R0; 87 R0 = I2; 88 [P0 + I2_OFFSET] = R0; 89 R0 = I3; 90 [P0 + I3_OFFSET] = R0; 91 92 /* save Modifier Registers */ 93 R0 = M0; 94 [P0 + M0_OFFSET] = R0; 95 R0 = M1; 96 [P0 + M1_OFFSET] = R0; 97 R0 = M2; 98 [P0 + M2_OFFSET] = R0; 99 R0 = M3; 100 [P0 + M3_OFFSET] = R0; 101 102 /* save Length Registers */ 103 R0 = L0; 104 [P0 + L0_OFFSET] = R0; 105 R0 = L1; 106 [P0 + L1_OFFSET] = R0; 107 R0 = L2; 108 [P0 + L2_OFFSET] = R0; 109 R0 = L3; 110 [P0 + L3_OFFSET] = R0; 111 112 /* Base Registers */ 113 R0 = B0; 114 [P0 + B0_OFFSET] = R0; 115 R0 = B1; 116 [P0 + B1_OFFSET] = R0; 117 R0 = B2; 118 [P0 + B2_OFFSET] = R0; 119 R0 = B3; 120 [P0 + B3_OFFSET] = R0; 121 122 /* save RETS */ 123 R0 = RETS; 124 [ P0 + RETS_OFFSET] = R0; 125 241 /* Start saving context R0 = current, R1=heir */ 242 p0 = r0; 243 [p0++] = r4; 244 [p0++] = r5; 245 [p0++] = r6; 246 [p0++] = r7; 247 248 /* save pointer registers */ 249 [p0++] = p3; 250 [p0++] = p4; 251 [p0++] = p5; 252 [p0++] = fp; 253 [p0++] = sp; 254 255 /* save length registers */ 256 r0 = l0; 257 [p0++] = r0; 258 r0 = l1; 259 [p0++] = r0; 260 r0 = l2; 261 [p0++] = r0; 262 r0 = l3; 263 [p0++] = r0; 264 265 /* save rets */ 266 r0 = rets; 267 [p0++] = r0; 268 269 /* save IMASK */ 270 p1.h = HI(IMASK); 271 p1.l = LO(IMASK); 272 r0 = [p1]; 273 [p0++] = r0; 274 275 p0 = r1; 126 276 restore: 127 P0 = R1; 128 R1 = [P0 + R1_OFFSET]; 129 R2 = [P0 + R2_OFFSET]; 130 R3 = [P0 + R3_OFFSET]; 131 R4 = [P0 + R4_OFFSET]; 132 R5 = [P0 + R5_OFFSET]; 133 R6 = [P0 + R6_OFFSET]; 134 R7 = [P0 + R7_OFFSET]; 135 136 P2 = [P0 + P2_OFFSET]; 137 P3 = [P0 + P3_OFFSET]; 138 P4 = [P0 + P4_OFFSET]; 139 P5 = [P0 + P5_OFFSET]; 140 141 /* might have to be placed more to the end */ 142 FP = [P0 + FP_OFFSET]; 143 SP = [P0 + SP_OFFSET]; 144 145 /* save ASTAT */ 146 R0 = [P0 + ASTAT_OFFSET]; 147 ASTAT = R0; 148 149 /* save Loop Counters */ 150 R0 = [P0 + LC0_OFFSET]; 151 LC0 = R0; 152 R0 = [P0 + LC1_OFFSET]; 153 LC1 = R0; 154 155 /* save Accumulators */ 156 R0 = [P0 + A0W_OFFSET]; 157 A0.W = R0; 158 R0 = [P0 + A0X_OFFSET]; 159 A0.X = R0; 160 R0 = [P0 + A1W_OFFSET]; 161 A1.W = R0; 162 R0 = [P0 + A1X_OFFSET]; 163 A1.X = R0; 164 165 /* save Index Registers */ 166 R0 = [P0 + I0_OFFSET]; 167 I0 = R0; 168 R0 = [P0 + I1_OFFSET]; 169 I1 = R0; 170 R0 = [P0 + I2_OFFSET]; 171 I2 = R0; 172 R0 = [P0 + I3_OFFSET]; 173 I3 = R0; 174 175 /* save Modifier Registers */ 176 R0 = [P0 + M0_OFFSET]; 177 M0 = R0; 178 R0 = [P0 + M1_OFFSET]; 179 M1 = R0; 180 R0 = [P0 + M2_OFFSET]; 181 M2 = R0; 182 R0 = [P0 + M3_OFFSET]; 183 M3 = R0; 184 185 /* save Length Registers */ 186 R0 = [P0 + L0_OFFSET]; 187 L0 = R0; 188 R0 = [P0 + L1_OFFSET]; 189 L1 = R0; 190 R0 = [P0 + L2_OFFSET]; 191 L2 = R0; 192 R0 = [P0 + L3_OFFSET]; 193 L3 = R0; 194 195 /* Base Registers */ 196 R0 = [P0 + B0_OFFSET]; 197 B0 = R0; 198 R0 = [P0 + B1_OFFSET]; 199 B1 = R0; 200 R0 = [P0 + B2_OFFSET]; 201 B2 = R0; 202 R0 = [P0 + B3_OFFSET]; 203 B3 = R0; 204 205 /* restore RETS */ 206 P1 = [P0 + RETS_OFFSET]; 207 RETS = P1; 208 209 /* now restore the P1 + P0 */ 210 P1 = [P0 + R1_OFFSET]; 211 P0 = [P0 + P0_OFFSET]; 212 213 rts; 214 277 /* restore data registers */ 278 r4 = [p0++]; 279 r5 = [p0++]; 280 r6 = [p0++]; 281 r7 = [p0++]; 282 283 /* restore pointer registers */ 284 p3 = [p0++]; 285 p4 = [p0++]; 286 p5 = [p0++]; 287 fp = [p0++]; 288 sp = [p0++]; 289 290 /* restore length registers */ 291 r0 = [p0++]; 292 l0 = r0; 293 r0 = [p0++]; 294 l1 = r0; 295 r0 = [p0++]; 296 l2 = r0; 297 r0 = [p0++]; 298 l3 = r0; 299 300 /* restore rets */ 301 r0 = [p0++]; 302 rets = r0; 303 304 /* restore IMASK */ 305 r0 = [p0++]; 306 p1.h = HI(IMASK); 307 p1.l = LO(IMASK); 308 [p1] = r0; 309 310 rts; 311 215 312 216 313 /* … … 227 324 * 228 325 */ 229 .globl __CPU_Context_restore326 .globl __CPU_Context_restore 230 327 __CPU_Context_restore: 231 jump restore; 232 233 234 235 .globl __ISR_Thread_Dispatch 236 __ISR_Thread_Dispatch: 237 238 .extern __Thread_Dispatch 239 R0.l = __Thread_Dispatch; 240 R0.h = __Thread_Dispatch; 241 242 /* Puts the address of th Thread_Dispatch function on Stack 243 * Where it will be restored to the RTI register 244 */ 245 P0 = [FP]; 246 /* save the old reti */ 247 R1 = [P0+0xc]; 248 [P0+0xc] = R0; 249 /* 250 * Overwriting the RETS Register is save because Thread_Dispatch is 251 * disabled when we are between call/link or unlink/rts 252 */ 253 [P0+0x8] = R1; 254 255 /* save old rets */ 256 257 rts; 258 259 260 .globl __ISR_Handler 328 p0 = r0; 329 jump restore; 330 331 332 .globl __ISR_Handler 333 .extern __CPU_Interrupt_stack_high; 334 .extern __ISR_Nest_level 335 .extern __Thread_Dispatch_disable_level 336 .extern __Context_Switch_necessary 337 .extern __ISR_Signals_to_thread_executing 261 338 __ISR_Handler: 262 /* First of all check the Stackpointer and */ 263 /* switch to Scratchpad if necessary */ 264 265 /* save P0 and R0 in the scratchpad */ 266 USP = P0; 267 268 /* load base adress of scratchpad */ 269 P0.H = HI(SCRATCH); 270 P0.L = LO(SCRATCH); 271 272 [SP] = ASTAT; /* save cc flag*/ 273 /* if SP is already inside the SCRATCHPAD */ 274 CC=SP<P0 (iu) 275 if !CC jump continue; 276 277 /* set PO to top of scratchpad */ 278 P0.h=HI(SCRATCH_TOP); 279 P0.l=LO(SCRATCH_TOP); 280 /*save the old SP*/ 281 [P0] = SP; 282 /*P0 += 4;*/ 283 /*set the new Stackpointer*/ 284 SP = P0; 285 /*restore the old PO*/ 286 287 /* The Stackpointer is now setup as we want */ 288 continue: 289 /* restore P0 and save some context */ 290 P0 = USP; 291 /* save some state on the isr stack (scratchpad), this enables interrupt nesting */ 292 [SP] = RETI; 293 [SP] = RETS; 294 [SP] = ASTAT; 295 [SP] = FP; 296 FP = SP; 297 [SP] = (R7:0, P5:0) ; 298 299 300 /* Context is saved, now check which Instruction we were executing 301 * If we were between a call and link or between a unlink and rts 302 * we have to disable Thread_Dispatch because correct restore of context after 303 * Thread_Dispatch would not be possible. */ 304 305 P0 = RETI; 306 R0 = P0; 307 R0.L = 0x0000; 308 R1.H = 0xffa0; 309 R1.L = 0x0000; 310 CC = R0 == R1; 311 if CC jump disablethreaddispatch; 312 313 R0 = W[P0](Z); 314 315 /* shift 16 bits to the right (select the high nibble ) */ 316 /*R0 >>= 16;*/ 317 318 R3 = 0; 319 /* Check if RETI is a LINK instruction */ 320 R1.h = HI(0x0000); 321 R1.l = LO(0xE800); 322 CC=R0==R1; 323 if cc jump disablethreaddispatch; 324 325 /* Check if RETI is a RTS instruction */ 326 R1.h = HI(0x0000); 327 R1.l = LO(0x0010); 328 CC=R0==R1; 329 if cc jump disablethreaddispatch; 330 331 jump afterthreaddispatch; 332 333 disablethreaddispatch: 334 /* _Thread_Dispatch_disable_level++ */ 335 .extern _Thread_Dispatch_disable_level 336 P0.H = __Thread_Dispatch_disable_level; 337 P0.L = __Thread_Dispatch_disable_level; 338 R0 = [P0]; 339 R0 += 1; 340 [P0] = R0; 341 R3 = 1; 342 343 afterthreaddispatch: 344 /* Put R3 on the stack */ 345 [SP] = R3; 346 347 /* Obtain a bitlist of the pending interrupts. */ 348 P0.H = HI(IPEND); 349 P0.L = LO(IPEND); 350 R1 = [P0]; 351 352 /* 353 * Search through the bit list stored in R0 to find the first enabled 354 * bit. The offset of this bit is the index of the interrupt that is 355 * to be handled. 356 */ 357 R0 = 1; 358 intloop: 359 R0 += 1; 360 R1 = ROT R1 by 1; 361 if !cc jump intloop; 362 363 364 /* pass SP as parameter to the C function */ 365 R1 = SP 366 367 /* pass values by register as well as by stack */ 368 /* to comply with the c calling conventions */ 369 [SP] = R0; 370 [SP] = R1; 371 372 .extern _ISR_Handler2 373 call _ISR_Handler2 374 375 /* inc 2 to compensate the passing of arguments */ 376 R3 = [SP++]; 377 R3 = [SP++]; 378 /* check if _Thread_Dispatch_disable_level has been incremented */ 379 R3 = [SP++] 380 CC=R3==0 381 if cc jump dont_decrement; 382 .extern _Thread_Dispatch_disable_level 383 P0.H = __Thread_Dispatch_disable_level; 384 P0.L = __Thread_Dispatch_disable_level; 385 R0 = [P0]; 386 R0 += 1; 387 [P0] = R0; 388 389 dont_decrement: 390 391 (R7:0, P5:0) = [SP++]; 392 FP = [SP++]; 393 ASTAT = [SP++]; 394 RETS = [SP++]; 395 RETI = [SP++]; 396 /* Interrupts are now disabled again */ 397 398 /*should restore the old stack !!!*/ 399 /*if sp now points to SCRATCH_TOP */ 400 401 /* load base adress of scratchpad */ 402 USP = P0; 403 P0.H = HI(SCRATCH_TOP); 404 P0.L = LO(SCRATCH_TOP); 405 406 CC=SP==P0 407 if !cc jump restoreP0 408 /* restore the stack */ 409 SP=[P0]; 410 411 restoreP0: 412 P0 = USP; 413 ASTAT = [SP++]; /* restore cc flag */ 414 415 /*now we should be on the old "userstack" again */ 416 417 /* return from interrupt, will jump to adress stored in RETI */ 418 RTI; 419 339 /* all interrupts are disabled at this point */ 340 /* the following few items are pushed onto the task stack for at 341 most one interrupt; nested interrupts will be using the interrupt 342 stack for everything. */ 343 [sp] = astat; 344 [sp] = p1; 345 [sp] = p0; 346 [sp] = r1; 347 [sp] = r0; 348 p0.h = __ISR_Nest_level; 349 p0.l = __ISR_Nest_level; 350 r0 = [p0]; 351 r0 += 1; 352 [p0] = r0; 353 cc = r0 <= 1 (iu); 354 if !cc jump noStackSwitch; 355 /* setup interrupt stack */ 356 r0 = sp; 357 p0.h = __CPU_Interrupt_stack_high; 358 p0.l = __CPU_Interrupt_stack_high; 359 sp = [p0]; 360 [sp] = r0; 361 noStackSwitch: 362 /* disable thread dispatch */ 363 p0.h = __Thread_Dispatch_disable_level; 364 p0.l = __Thread_Dispatch_disable_level; 365 r0 = [p0]; 366 r0 += 1; 367 [p0] = r0; 368 369 [sp] = reti; /* interrupts are now enabled */ 370 371 /* figure out what vector we are */ 372 p0.h = HI(IPEND); 373 p0.l = LO(IPEND); 374 r1 = [p0]; 375 /* we should only get here for events that require RTI to return */ 376 r1 = r1 >> 5; 377 r0 = 4; 378 /* at least one bit must be set, so this loop will exit */ 379 vectorIDLoop: 380 r0 += 1; 381 r1 = rot r1 by 1; 382 if !cc jump vectorIDLoop; 383 384 [sp] = r2; 385 p0.h = __ISR_Vector_table; 386 p0.l = __ISR_Vector_table; 387 r2 = [p0]; 388 r1 = r0 << 2; 389 r1 = r1 + r2; 390 p0 = r1; 391 p0 = [p0]; 392 cc = p0 == 0; 393 if cc jump noHandler; 394 395 /* r2, r0, r1, p0, p1, astat are already saved */ 396 [sp] = a1.x; 397 [sp] = a1.w; 398 [sp] = a0.x; 399 [sp] = a0.w; 400 [sp] = r3; 401 [sp] = p3; 402 [sp] = p2; 403 [sp] = lt1; 404 [sp] = lt0; 405 [sp] = lc1; 406 [sp] = lc0; 407 [sp] = lb1; 408 [sp] = lb0; 409 [sp] = i3; 410 [sp] = i2; 411 [sp] = i1; 412 [sp] = i0; 413 [sp] = m3; 414 [sp] = m2; 415 [sp] = m1; 416 [sp] = m0; 417 [sp] = l3; 418 [sp] = l2; 419 [sp] = l1; 420 [sp] = l0; 421 [sp] = b3; 422 [sp] = b2; 423 [sp] = b1; 424 [sp] = b0; 425 [sp] = rets; 426 r1 = fp; /* is this really what should be passed here? */ 427 /* call user isr; r0 = vector number, r1 = frame pointer */ 428 sp += 12; /* bizarre abi... */ 429 call (p0); 430 sp += 12; 431 rets = [sp++]; 432 b0 = [sp++]; 433 b1 = [sp++]; 434 b2 = [sp++]; 435 b3 = [sp++]; 436 l0 = [sp++]; 437 l1 = [sp++]; 438 l2 = [sp++]; 439 l3 = [sp++]; 440 m0 = [sp++]; 441 m1 = [sp++]; 442 m2 = [sp++]; 443 m3 = [sp++]; 444 i0 = [sp++]; 445 i1 = [sp++]; 446 i2 = [sp++]; 447 i3 = [sp++]; 448 lb0 = [sp++]; 449 lb1 = [sp++]; 450 lc0 = [sp++]; 451 lc1 = [sp++]; 452 lt0 = [sp++]; 453 lt1 = [sp++]; 454 p2 = [sp++]; 455 p3 = [sp++]; 456 r3 = [sp++]; 457 a0.w = [sp++]; 458 a0.x = [sp++]; 459 a1.w = [sp++]; 460 a1.x = [sp++]; 461 462 noHandler: 463 r2 = [sp++]; 464 /* this disables interrupts again */ 465 reti = [sp++]; 466 467 p0.h = __ISR_Nest_level; 468 p0.l = __ISR_Nest_level; 469 r0 = [p0]; 470 r0 += 1; 471 [p0] = r0; 472 cc = r0 == 0; 473 if !cc jump noStackRestore; 474 sp = [sp]; 475 noStackRestore: 476 477 /* check this stuff to insure context_switch_necessary and 478 isr_signals_to_thread_executing are being handled appropriately. */ 479 p0.h = __Thread_Dispatch_disable_level; 480 p0.l = __Thread_Dispatch_disable_level; 481 r0 = [p0]; 482 r0 += 1; 483 [p0] = r0; 484 cc = r0 == 0; 485 if !cc jump noDispatch 486 487 /* do thread dispatch if necessary */ 488 p0.h = __Context_Switch_necessary; 489 p0.l = __Context_Switch_necessary; 490 r0 = [p0]; 491 cc = r0 == 0; 492 p0.h = __ISR_Signals_to_thread_executing; 493 p0.l = __ISR_Signals_to_thread_executing; 494 if !cc jump doDispatch 495 r0 = [p0]; 496 cc = r0 == 0; 497 if cc jump noDispatch 498 doDispatch: 499 r0 = 0; 500 [p0] = r0; 501 raise 15; 502 noDispatch: 503 r0 = [sp++]; 504 r1 = [sp++]; 505 p0 = [sp++]; 506 p1 = [sp++]; 507 astat = [sp++]; 508 rti 509 510 511 /* the approach here is for the main interrupt handler, when a dispatch is 512 wanted, to do a "raise 15". when the main interrupt handler does its 513 "rti", the "raise 15" takes effect and we end up here. we can now 514 safely call _Thread_Dispatch, and do an "rti" to get back to the 515 original interrupted function. this does require selfnesting to be 516 enabled; the maximum nest depth is the number of tasks. */ 517 .global __ISR15_Handler 518 .extern __Thread_Dispatch 519 __ISR15_Handler: 520 [sp] = reti; 521 [sp] = rets; 522 [sp] = astat; 523 [sp] = a1.x; 524 [sp] = a1.w; 525 [sp] = a0.x; 526 [sp] = a0.w; 527 [sp] = r3; 528 [sp] = r2; 529 [sp] = r1; 530 [sp] = r0; 531 [sp] = p3; 532 [sp] = p2; 533 [sp] = p1; 534 [sp] = p0; 535 [sp] = lt1; 536 [sp] = lt0; 537 [sp] = lc1; 538 [sp] = lc0; 539 [sp] = lb1; 540 [sp] = lb0; 541 [sp] = i3; 542 [sp] = i2; 543 [sp] = i1; 544 [sp] = i0; 545 [sp] = m3; 546 [sp] = m2; 547 [sp] = m1; 548 [sp] = m0; 549 [sp] = l3; 550 [sp] = l2; 551 [sp] = l1; 552 [sp] = l0; 553 [sp] = b3; 554 [sp] = b2; 555 [sp] = b1; 556 [sp] = b0; 557 sp += 12; /* bizarre abi... */ 558 call __Thread_Dispatch; 559 sp += 12; 560 b0 = [sp++]; 561 b1 = [sp++]; 562 b2 = [sp++]; 563 b3 = [sp++]; 564 l0 = [sp++]; 565 l1 = [sp++]; 566 l2 = [sp++]; 567 l3 = [sp++]; 568 m0 = [sp++]; 569 m1 = [sp++]; 570 m2 = [sp++]; 571 m3 = [sp++]; 572 i0 = [sp++]; 573 i1 = [sp++]; 574 i2 = [sp++]; 575 i3 = [sp++]; 576 lb0 = [sp++]; 577 lb1 = [sp++]; 578 lc0 = [sp++]; 579 lc1 = [sp++]; 580 lt0 = [sp++]; 581 lt1 = [sp++]; 582 p0 = [sp++]; 583 p1 = [sp++]; 584 p2 = [sp++]; 585 p3 = [sp++]; 586 r0 = [sp++]; 587 r1 = [sp++]; 588 r2 = [sp++]; 589 r3 = [sp++]; 590 a0.w = [sp++]; 591 a0.x = [sp++]; 592 a1.w = [sp++]; 593 a1.x = [sp++]; 594 astat = [sp++]; 595 rets = [sp++]; 596 reti = [sp++]; 597 rti; 598
Note: See TracChangeset
for help on using the changeset viewer.