diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh3/entry.S')
-rw-r--r-- | arch/sh/kernel/cpu/sh3/entry.S | 357 |
1 files changed, 194 insertions, 163 deletions
diff --git a/arch/sh/kernel/cpu/sh3/entry.S b/arch/sh/kernel/cpu/sh3/entry.S index b4106d0c68ec..55da0ff9848d 100644 --- a/arch/sh/kernel/cpu/sh3/entry.S +++ b/arch/sh/kernel/cpu/sh3/entry.S | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <asm/unistd.h> | 16 | #include <asm/unistd.h> |
17 | #include <cpu/mmu_context.h> | 17 | #include <cpu/mmu_context.h> |
18 | #include <asm/page.h> | 18 | #include <asm/page.h> |
19 | #include <asm/cache.h> | ||
19 | 20 | ||
20 | ! NOTE: | 21 | ! NOTE: |
21 | ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address | 22 | ! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address |
@@ -187,44 +188,35 @@ call_dae: | |||
187 | #if defined(CONFIG_SH_STANDARD_BIOS) | 188 | #if defined(CONFIG_SH_STANDARD_BIOS) |
188 | /* Unwind the stack and jmp to the debug entry */ | 189 | /* Unwind the stack and jmp to the debug entry */ |
189 | ENTRY(sh_bios_handler) | 190 | ENTRY(sh_bios_handler) |
190 | mov.l @r15+, r0 | 191 | mov.l 1f, r8 |
191 | mov.l @r15+, r1 | 192 | bsr restore_regs |
192 | mov.l @r15+, r2 | 193 | nop |
193 | mov.l @r15+, r3 | 194 | |
194 | mov.l @r15+, r4 | 195 | lds k2, pr ! restore pr |
195 | mov.l @r15+, r5 | 196 | mov k4, r15 |
196 | mov.l @r15+, r6 | ||
197 | mov.l @r15+, r7 | ||
198 | stc sr, r8 | ||
199 | mov.l 1f, r9 ! BL =1, RB=1, IMASK=0x0F | ||
200 | or r9, r8 | ||
201 | ldc r8, sr ! here, change the register bank | ||
202 | mov.l @r15+, r8 | ||
203 | mov.l @r15+, r9 | ||
204 | mov.l @r15+, r10 | ||
205 | mov.l @r15+, r11 | ||
206 | mov.l @r15+, r12 | ||
207 | mov.l @r15+, r13 | ||
208 | mov.l @r15+, r14 | ||
209 | mov.l @r15+, k0 | ||
210 | ldc.l @r15+, spc | ||
211 | lds.l @r15+, pr | ||
212 | mov.l @r15+, k1 | ||
213 | ldc.l @r15+, gbr | ||
214 | lds.l @r15+, mach | ||
215 | lds.l @r15+, macl | ||
216 | mov k0, r15 | ||
217 | ! | 197 | ! |
218 | mov.l 2f, k0 | 198 | mov.l 2f, k0 |
219 | mov.l @k0, k0 | 199 | mov.l @k0, k0 |
220 | jmp @k0 | 200 | jmp @k0 |
221 | ldc k1, ssr | 201 | ldc k3, ssr |
222 | .align 2 | 202 | .align 2 |
223 | 1: .long 0x300000f0 | 203 | 1: .long 0x300000f0 |
224 | 2: .long gdb_vbr_vector | 204 | 2: .long gdb_vbr_vector |
225 | #endif /* CONFIG_SH_STANDARD_BIOS */ | 205 | #endif /* CONFIG_SH_STANDARD_BIOS */ |
226 | 206 | ||
227 | restore_all: | 207 | ! restore_regs() |
208 | ! - restore r0, r1, r2, r3, r4, r5, r6, r7 from the stack | ||
209 | ! - switch bank | ||
210 | ! - restore r8, r9, r10, r11, r12, r13, r14, r15 from the stack | ||
211 | ! - restore spc, pr*, ssr, gbr, mach, macl, skip default tra | ||
212 | ! k2 returns original pr | ||
213 | ! k3 returns original sr | ||
214 | ! k4 returns original stack pointer | ||
215 | ! r8 passes SR bitmask, overwritten with restored data on return | ||
216 | ! r9 trashed | ||
217 | ! BL=0 on entry, on exit BL=1 (depending on r8). | ||
218 | |||
219 | ENTRY(restore_regs) | ||
228 | mov.l @r15+, r0 | 220 | mov.l @r15+, r0 |
229 | mov.l @r15+, r1 | 221 | mov.l @r15+, r1 |
230 | mov.l @r15+, r2 | 222 | mov.l @r15+, r2 |
@@ -234,10 +226,9 @@ restore_all: | |||
234 | mov.l @r15+, r6 | 226 | mov.l @r15+, r6 |
235 | mov.l @r15+, r7 | 227 | mov.l @r15+, r7 |
236 | ! | 228 | ! |
237 | stc sr, r8 | 229 | stc sr, r9 |
238 | mov.l 7f, r9 | 230 | or r8, r9 |
239 | or r9, r8 ! BL =1, RB=1 | 231 | ldc r9, sr |
240 | ldc r8, sr ! here, change the register bank | ||
241 | ! | 232 | ! |
242 | mov.l @r15+, r8 | 233 | mov.l @r15+, r8 |
243 | mov.l @r15+, r9 | 234 | mov.l @r15+, r9 |
@@ -248,12 +239,20 @@ restore_all: | |||
248 | mov.l @r15+, r14 | 239 | mov.l @r15+, r14 |
249 | mov.l @r15+, k4 ! original stack pointer | 240 | mov.l @r15+, k4 ! original stack pointer |
250 | ldc.l @r15+, spc | 241 | ldc.l @r15+, spc |
251 | lds.l @r15+, pr | 242 | mov.l @r15+, k2 ! original PR |
252 | mov.l @r15+, k3 ! original SR | 243 | mov.l @r15+, k3 ! original SR |
253 | ldc.l @r15+, gbr | 244 | ldc.l @r15+, gbr |
254 | lds.l @r15+, mach | 245 | lds.l @r15+, mach |
255 | lds.l @r15+, macl | 246 | lds.l @r15+, macl |
256 | add #4, r15 ! Skip syscall number | 247 | rts |
248 | add #4, r15 ! Skip syscall number | ||
249 | |||
250 | restore_all: | ||
251 | mov.l 7f, r8 | ||
252 | bsr restore_regs | ||
253 | nop | ||
254 | |||
255 | lds k2, pr ! restore pr | ||
257 | ! | 256 | ! |
258 | #ifdef CONFIG_SH_DSP | 257 | #ifdef CONFIG_SH_DSP |
259 | mov.l @r15+, k0 ! DSP mode marker | 258 | mov.l @r15+, k0 ! DSP mode marker |
@@ -294,7 +293,7 @@ skip_restore: | |||
294 | mov #0xf0, k1 | 293 | mov #0xf0, k1 |
295 | extu.b k1, k1 | 294 | extu.b k1, k1 |
296 | not k1, k1 | 295 | not k1, k1 |
297 | and k1, k2 ! Mask orignal SR value | 296 | and k1, k2 ! Mask original SR value |
298 | ! | 297 | ! |
299 | mov k3, k0 ! Calculate IMASK-bits | 298 | mov k3, k0 ! Calculate IMASK-bits |
300 | shlr2 k0 | 299 | shlr2 k0 |
@@ -313,7 +312,6 @@ skip_restore: | |||
313 | mov #0, k1 | 312 | mov #0, k1 |
314 | mov.b k1, @k0 | 313 | mov.b k1, @k0 |
315 | #endif | 314 | #endif |
316 | mov.l @r15+, k2 ! restore EXPEVT | ||
317 | mov k4, r15 | 315 | mov k4, r15 |
318 | rte | 316 | rte |
319 | nop | 317 | nop |
@@ -336,81 +334,55 @@ skip_restore: | |||
336 | ENTRY(vbr_base) | 334 | ENTRY(vbr_base) |
337 | .long 0 | 335 | .long 0 |
338 | ! | 336 | ! |
337 | ! 0x100: General exception vector | ||
338 | ! | ||
339 | .balign 256,0,256 | 339 | .balign 256,0,256 |
340 | general_exception: | 340 | general_exception: |
341 | mov.l 1f, k2 | 341 | #ifndef CONFIG_CPU_SUBTYPE_SHX3 |
342 | mov.l 2f, k3 | 342 | bra handle_exception |
343 | #ifdef CONFIG_CPU_SUBTYPE_SHX3 | 343 | sts pr, k3 ! save original pr value in k3 |
344 | mov.l @k2, k2 | 344 | #else |
345 | mov.l 1f, k4 | ||
346 | mov.l @k4, k4 | ||
345 | 347 | ||
346 | ! Is EXPEVT larger than 0x800? | 348 | ! Is EXPEVT larger than 0x800? |
347 | mov #0x8, k0 | 349 | mov #0x8, k0 |
348 | shll8 k0 | 350 | shll8 k0 |
349 | cmp/hs k0, k2 | 351 | cmp/hs k0, k4 |
350 | bf 0f | 352 | bf 0f |
351 | 353 | ||
352 | ! then add 0x580 (k2 is 0xd80 or 0xda0) | 354 | ! then add 0x580 (k2 is 0xd80 or 0xda0) |
353 | mov #0x58, k0 | 355 | mov #0x58, k0 |
354 | shll2 k0 | 356 | shll2 k0 |
355 | shll2 k0 | 357 | shll2 k0 |
356 | add k0, k2 | 358 | add k0, k4 |
357 | 0: | 359 | 0: |
358 | bra handle_exception | 360 | ! Setup stack and save DSP context (k0 contains original r15 on return) |
361 | bsr prepare_stack_save_dsp | ||
359 | nop | 362 | nop |
360 | #else | ||
361 | bra handle_exception | ||
362 | mov.l @k2, k2 | ||
363 | #endif | ||
364 | .align 2 | ||
365 | 1: .long EXPEVT | ||
366 | 2: .long ret_from_exception | ||
367 | ! | ||
368 | ! | ||
369 | 363 | ||
370 | .balign 1024,0,1024 | 364 | ! Save registers / Switch to bank 0 |
371 | tlb_miss: | 365 | mov k4, k2 ! keep vector in k2 |
372 | mov.l 1f, k2 | 366 | mov.l 1f, k4 ! SR bits to clear in k4 |
373 | mov.l 4f, k3 | 367 | bsr save_regs ! needs original pr value in k3 |
374 | bra handle_exception | 368 | nop |
375 | mov.l @k2, k2 | 369 | |
376 | ! | 370 | bra handle_exception_special |
377 | .balign 512,0,512 | ||
378 | interrupt: | ||
379 | mov.l 3f, k3 | ||
380 | #if defined(CONFIG_KGDB) | ||
381 | mov.l 2f, k2 | ||
382 | ! Debounce (filter nested NMI) | ||
383 | mov.l @k2, k0 | ||
384 | mov.l 5f, k1 | ||
385 | cmp/eq k1, k0 | ||
386 | bf 0f | ||
387 | mov.l 6f, k1 | ||
388 | tas.b @k1 | ||
389 | bt 0f | ||
390 | rte | ||
391 | nop | 371 | nop |
392 | .align 2 | ||
393 | 2: .long INTEVT | ||
394 | 5: .long NMI_VEC | ||
395 | 6: .long in_nmi | ||
396 | 0: | ||
397 | #endif /* defined(CONFIG_KGDB) */ | ||
398 | bra handle_exception | ||
399 | mov #-1, k2 ! interrupt exception marker | ||
400 | 372 | ||
401 | .align 2 | 373 | .align 2 |
402 | 1: .long EXPEVT | 374 | 1: .long EXPEVT |
403 | 3: .long ret_from_irq | 375 | #endif |
404 | 4: .long ret_from_exception | ||
405 | 376 | ||
406 | ! | 377 | ! prepare_stack_save_dsp() |
407 | ! | 378 | ! - roll back gRB |
408 | .align 2 | 379 | ! - switch to kernel stack |
409 | ENTRY(handle_exception) | 380 | ! - save DSP |
410 | ! Using k0, k1 for scratch registers (r0_bank1, r1_bank), | 381 | ! k0 returns original sp (after roll back) |
411 | ! save all registers onto stack. | 382 | ! k1 trashed |
412 | ! | 383 | ! k2 trashed |
413 | 384 | ||
385 | prepare_stack_save_dsp: | ||
414 | #ifdef CONFIG_GUSA | 386 | #ifdef CONFIG_GUSA |
415 | ! Check for roll back gRB (User and Kernel) | 387 | ! Check for roll back gRB (User and Kernel) |
416 | mov r15, k0 | 388 | mov r15, k0 |
@@ -430,7 +402,7 @@ ENTRY(handle_exception) | |||
430 | 2: mov k1, r15 ! SP = r1 | 402 | 2: mov k1, r15 ! SP = r1 |
431 | 1: | 403 | 1: |
432 | #endif | 404 | #endif |
433 | 405 | ! Switch to kernel stack if needed | |
434 | stc ssr, k0 ! Is it from kernel space? | 406 | stc ssr, k0 ! Is it from kernel space? |
435 | shll k0 ! Check MD bit (bit30) by shifting it into... | 407 | shll k0 ! Check MD bit (bit30) by shifting it into... |
436 | shll k0 ! ...the T bit | 408 | shll k0 ! ...the T bit |
@@ -443,18 +415,17 @@ ENTRY(handle_exception) | |||
443 | add current, k1 | 415 | add current, k1 |
444 | mov k1, r15 ! change to kernel stack | 416 | mov k1, r15 ! change to kernel stack |
445 | ! | 417 | ! |
446 | 1: mov.l 2f, k1 | 418 | 1: |
447 | ! | ||
448 | #ifdef CONFIG_SH_DSP | 419 | #ifdef CONFIG_SH_DSP |
449 | mov.l r2, @-r15 ! Save r2, we need another reg | 420 | ! Save DSP context if needed |
450 | stc sr, k4 | 421 | stc sr, k1 |
451 | mov.l 1f, r2 | 422 | mov #0x10, k2 |
452 | tst r2, k4 ! Check if in DSP mode | 423 | shll8 k2 ! DSP=1 (0x00001000) |
453 | mov.l @r15+, r2 ! Restore r2 now | 424 | tst k2, k1 ! Check if in DSP mode (passed in k2) |
454 | bt/s skip_save | 425 | bt/s skip_save |
455 | mov #0, k4 ! Set marker for no stack frame | 426 | mov #0, k1 ! Set marker for no stack frame |
456 | 427 | ||
457 | mov r2, k4 ! Backup r2 (in k4) for later | 428 | mov k2, k1 ! Save has-frame marker |
458 | 429 | ||
459 | ! Save DSP registers on stack | 430 | ! Save DSP registers on stack |
460 | stc.l mod, @-r15 | 431 | stc.l mod, @-r15 |
@@ -473,35 +444,74 @@ ENTRY(handle_exception) | |||
473 | ! as we're not at all interested in supporting ancient toolchains at | 444 | ! as we're not at all interested in supporting ancient toolchains at |
474 | ! this point. -- PFM. | 445 | ! this point. -- PFM. |
475 | 446 | ||
476 | mov r15, r2 | 447 | mov r15, k2 |
477 | .word 0xf653 ! movs.l a1, @-r2 | 448 | .word 0xf653 ! movs.l a1, @-r2 |
478 | .word 0xf6f3 ! movs.l a0g, @-r2 | 449 | .word 0xf6f3 ! movs.l a0g, @-r2 |
479 | .word 0xf6d3 ! movs.l a1g, @-r2 | 450 | .word 0xf6d3 ! movs.l a1g, @-r2 |
480 | .word 0xf6c3 ! movs.l m0, @-r2 | 451 | .word 0xf6c3 ! movs.l m0, @-r2 |
481 | .word 0xf6e3 ! movs.l m1, @-r2 | 452 | .word 0xf6e3 ! movs.l m1, @-r2 |
482 | mov r2, r15 | 453 | mov k2, r15 |
483 | 454 | ||
484 | mov k4, r2 ! Restore r2 | ||
485 | mov.l 1f, k4 ! Force DSP stack frame | ||
486 | skip_save: | 455 | skip_save: |
487 | mov.l k4, @-r15 ! Push DSP mode marker onto stack | 456 | mov.l k1, @-r15 ! Push DSP mode marker onto stack |
488 | #endif | 457 | #endif |
489 | ! Save the user registers on the stack. | 458 | rts |
490 | mov.l k2, @-r15 ! EXPEVT | 459 | nop |
491 | 460 | ! | |
492 | mov #-1, k4 | 461 | ! 0x400: Instruction and Data TLB miss exception vector |
493 | mov.l k4, @-r15 ! set TRA (default: -1) | 462 | ! |
494 | ! | 463 | .balign 1024,0,1024 |
464 | tlb_miss: | ||
465 | sts pr, k3 ! save original pr value in k3 | ||
466 | |||
467 | handle_exception: | ||
468 | mova exception_data, k0 | ||
469 | |||
470 | ! Setup stack and save DSP context (k0 contains original r15 on return) | ||
471 | bsr prepare_stack_save_dsp | ||
472 | PREF(k0) | ||
473 | |||
474 | ! Save registers / Switch to bank 0 | ||
475 | mov.l 5f, k2 ! vector register address | ||
476 | mov.l 1f, k4 ! SR bits to clear in k4 | ||
477 | bsr save_regs ! needs original pr value in k3 | ||
478 | mov.l @k2, k2 ! read out vector and keep in k2 | ||
479 | |||
480 | handle_exception_special: | ||
481 | ! Setup return address and jump to exception handler | ||
482 | mov.l 7f, r9 ! fetch return address | ||
483 | stc r2_bank, r0 ! k2 (vector) | ||
484 | mov.l 6f, r10 | ||
485 | shlr2 r0 | ||
486 | shlr r0 | ||
487 | mov.l @(r0, r10), r10 | ||
488 | jmp @r10 | ||
489 | lds r9, pr ! put return address in pr | ||
490 | |||
491 | .align L1_CACHE_SHIFT | ||
492 | |||
493 | ! save_regs() | ||
494 | ! - save default tra, macl, mach, gbr, ssr, pr* and spc on the stack | ||
495 | ! - save r15*, r14, r13, r12, r11, r10, r9, r8 on the stack | ||
496 | ! - switch bank | ||
497 | ! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack | ||
498 | ! k0 contains original stack pointer* | ||
499 | ! k1 trashed | ||
500 | ! k3 passes original pr* | ||
501 | ! k4 passes SR bitmask | ||
502 | ! BL=1 on entry, on exit BL=0. | ||
503 | |||
504 | ENTRY(save_regs) | ||
505 | mov #-1, r1 | ||
506 | mov.l k1, @-r15 ! set TRA (default: -1) | ||
495 | sts.l macl, @-r15 | 507 | sts.l macl, @-r15 |
496 | sts.l mach, @-r15 | 508 | sts.l mach, @-r15 |
497 | stc.l gbr, @-r15 | 509 | stc.l gbr, @-r15 |
498 | stc.l ssr, @-r15 | 510 | stc.l ssr, @-r15 |
499 | sts.l pr, @-r15 | 511 | mov.l k3, @-r15 ! original pr in k3 |
500 | stc.l spc, @-r15 | 512 | stc.l spc, @-r15 |
501 | ! | 513 | |
502 | lds k3, pr ! Set the return address to pr | 514 | mov.l k0, @-r15 ! original stack pointer in k0 |
503 | ! | ||
504 | mov.l k0, @-r15 ! save orignal stack | ||
505 | mov.l r14, @-r15 | 515 | mov.l r14, @-r15 |
506 | mov.l r13, @-r15 | 516 | mov.l r13, @-r15 |
507 | mov.l r12, @-r15 | 517 | mov.l r12, @-r15 |
@@ -509,13 +519,23 @@ skip_save: | |||
509 | mov.l r10, @-r15 | 519 | mov.l r10, @-r15 |
510 | mov.l r9, @-r15 | 520 | mov.l r9, @-r15 |
511 | mov.l r8, @-r15 | 521 | mov.l r8, @-r15 |
512 | ! | 522 | |
513 | stc sr, r8 ! Back to normal register bank, and | 523 | mov.l 0f, k3 ! SR bits to set in k3 |
514 | or k1, r8 ! Block all interrupts | 524 | |
515 | mov.l 3f, k1 | 525 | ! fall-through |
516 | and k1, r8 ! ... | 526 | |
517 | ldc r8, sr ! ...changed here. | 527 | ! save_low_regs() |
518 | ! | 528 | ! - modify SR for bank switch |
529 | ! - save r7, r6, r5, r4, r3, r2, r1, r0 on the stack | ||
530 | ! k3 passes bits to set in SR | ||
531 | ! k4 passes bits to clear in SR | ||
532 | |||
533 | ENTRY(save_low_regs) | ||
534 | stc sr, r8 | ||
535 | or k3, r8 | ||
536 | and k4, r8 | ||
537 | ldc r8, sr | ||
538 | |||
519 | mov.l r7, @-r15 | 539 | mov.l r7, @-r15 |
520 | mov.l r6, @-r15 | 540 | mov.l r6, @-r15 |
521 | mov.l r5, @-r15 | 541 | mov.l r5, @-r15 |
@@ -523,52 +543,63 @@ skip_save: | |||
523 | mov.l r3, @-r15 | 543 | mov.l r3, @-r15 |
524 | mov.l r2, @-r15 | 544 | mov.l r2, @-r15 |
525 | mov.l r1, @-r15 | 545 | mov.l r1, @-r15 |
526 | mov.l r0, @-r15 | ||
527 | |||
528 | /* | ||
529 | * This gets a bit tricky.. in the INTEVT case we don't want to use | ||
530 | * the VBR offset as a destination in the jump call table, since all | ||
531 | * of the destinations are the same. In this case, (interrupt) sets | ||
532 | * a marker in r2 (now r2_bank since SR.RB changed), which we check | ||
533 | * to determine the exception type. For all other exceptions, we | ||
534 | * forcibly read EXPEVT from memory and fix up the jump address, in | ||
535 | * the interrupt exception case we jump to do_IRQ() and defer the | ||
536 | * INTEVT read until there. As a bonus, we can also clean up the SR.RB | ||
537 | * checks that do_IRQ() was doing.. | ||
538 | */ | ||
539 | stc r2_bank, r8 | ||
540 | cmp/pz r8 | ||
541 | bf interrupt_exception | ||
542 | shlr2 r8 | ||
543 | shlr r8 | ||
544 | mov.l 4f, r9 | ||
545 | add r8, r9 | ||
546 | mov.l @r9, r9 | ||
547 | jmp @r9 | ||
548 | nop | ||
549 | rts | 546 | rts |
550 | nop | 547 | mov.l r0, @-r15 |
551 | 548 | ||
549 | ! | ||
550 | ! 0x600: Interrupt / NMI vector | ||
551 | ! | ||
552 | .balign 512,0,512 | ||
553 | ENTRY(handle_interrupt) | ||
554 | #if defined(CONFIG_KGDB) | ||
555 | mov.l 2f, k2 | ||
556 | ! Debounce (filter nested NMI) | ||
557 | mov.l @k2, k0 | ||
558 | mov.l 9f, k1 | ||
559 | cmp/eq k1, k0 | ||
560 | bf 11f | ||
561 | mov.l 10f, k1 | ||
562 | tas.b @k1 | ||
563 | bt 11f | ||
564 | rte | ||
565 | nop | ||
552 | .align 2 | 566 | .align 2 |
553 | 1: .long 0x00001000 ! DSP=1 | 567 | 9: .long NMI_VEC |
554 | 2: .long 0x000080f0 ! FD=1, IMASK=15 | 568 | 10: .long in_nmi |
555 | 3: .long 0xcfffffff ! RB=0, BL=0 | 569 | 11: |
556 | 4: .long exception_handling_table | 570 | #endif /* defined(CONFIG_KGDB) */ |
571 | sts pr, k3 ! save original pr value in k3 | ||
572 | mova exception_data, k0 | ||
557 | 573 | ||
558 | interrupt_exception: | 574 | ! Setup stack and save DSP context (k0 contains original r15 on return) |
559 | mov.l 1f, r9 | 575 | bsr prepare_stack_save_dsp |
576 | PREF(k0) | ||
577 | |||
578 | ! Save registers / Switch to bank 0 | ||
579 | mov.l 1f, k4 ! SR bits to clear in k4 | ||
580 | bsr save_regs ! needs original pr value in k3 | ||
581 | mov #-1, k2 ! default vector kept in k2 | ||
582 | |||
583 | ! Setup return address and jump to do_IRQ | ||
584 | mov.l 4f, r9 ! fetch return address | ||
585 | lds r9, pr ! put return address in pr | ||
560 | mov.l 2f, r4 | 586 | mov.l 2f, r4 |
561 | mov.l @r4, r4 | 587 | mov.l 3f, r9 |
588 | mov.l @r4, r4 ! pass INTEVT vector as arg0 | ||
562 | jmp @r9 | 589 | jmp @r9 |
563 | mov r15, r5 | 590 | mov r15, r5 ! pass saved registers as arg1 |
564 | rts | ||
565 | nop | ||
566 | |||
567 | .align 2 | ||
568 | 1: .long do_IRQ | ||
569 | 2: .long INTEVT | ||
570 | 591 | ||
571 | .align 2 | ||
572 | ENTRY(exception_none) | 592 | ENTRY(exception_none) |
573 | rts | 593 | rts |
574 | nop | 594 | nop |
595 | |||
596 | .align L1_CACHE_SHIFT | ||
597 | exception_data: | ||
598 | 0: .long 0x000080f0 ! FD=1, IMASK=15 | ||
599 | 1: .long 0xcfffffff ! RB=0, BL=0 | ||
600 | 2: .long INTEVT | ||
601 | 3: .long do_IRQ | ||
602 | 4: .long ret_from_irq | ||
603 | 5: .long EXPEVT | ||
604 | 6: .long exception_handling_table | ||
605 | 7: .long ret_from_exception | ||