diff options
Diffstat (limited to 'arch/xtensa/kernel/vectors.S')
-rw-r--r-- | arch/xtensa/kernel/vectors.S | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 68df35f66ce3..82109b42e240 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
@@ -10,7 +10,7 @@ | |||
10 | * Public License. See the file "COPYING" in the main directory of | 10 | * Public License. See the file "COPYING" in the main directory of |
11 | * this archive for more details. | 11 | * this archive for more details. |
12 | * | 12 | * |
13 | * Copyright (C) 2005 Tensilica, Inc. | 13 | * Copyright (C) 2005 - 2008 Tensilica, Inc. |
14 | * | 14 | * |
15 | * Chris Zankel <chris@zankel.net> | 15 | * Chris Zankel <chris@zankel.net> |
16 | * | 16 | * |
@@ -366,6 +366,41 @@ ENTRY(_DebugInterruptVector) | |||
366 | ENDPROC(_DebugInterruptVector) | 366 | ENDPROC(_DebugInterruptVector) |
367 | 367 | ||
368 | 368 | ||
369 | |||
370 | /* | ||
371 | * Medium priority level interrupt vectors | ||
372 | * | ||
373 | * Each takes less than 16 (0x10) bytes, no literals, by placing | ||
374 | * the extra 8 bytes that would otherwise be required in the window | ||
375 | * vectors area where there is space. With relocatable vectors, | ||
376 | * all vectors are within ~ 4 kB range of each other, so we can | ||
377 | * simply jump (J) to another vector without having to use JX. | ||
378 | * | ||
379 | * common_exception code gets current IRQ level in PS.INTLEVEL | ||
380 | * and preserves it for the IRQ handling time. | ||
381 | */ | ||
382 | |||
383 | .macro irq_entry_level level | ||
384 | |||
385 | .if XCHAL_EXCM_LEVEL >= \level | ||
386 | .section .Level\level\()InterruptVector.text, "ax" | ||
387 | ENTRY(_Level\level\()InterruptVector) | ||
388 | wsr a0, epc1 | ||
389 | rsr a0, epc\level | ||
390 | xsr a0, epc1 | ||
391 | # branch to user or kernel vector | ||
392 | j _SimulateUserKernelVectorException | ||
393 | .endif | ||
394 | |||
395 | .endm | ||
396 | |||
397 | irq_entry_level 2 | ||
398 | irq_entry_level 3 | ||
399 | irq_entry_level 4 | ||
400 | irq_entry_level 5 | ||
401 | irq_entry_level 6 | ||
402 | |||
403 | |||
369 | /* Window overflow and underflow handlers. | 404 | /* Window overflow and underflow handlers. |
370 | * The handlers must be 64 bytes apart, first starting with the underflow | 405 | * The handlers must be 64 bytes apart, first starting with the underflow |
371 | * handlers underflow-4 to underflow-12, then the overflow handlers | 406 | * handlers underflow-4 to underflow-12, then the overflow handlers |
@@ -396,6 +431,26 @@ ENTRY_ALIGN64(_WindowOverflow4) | |||
396 | ENDPROC(_WindowOverflow4) | 431 | ENDPROC(_WindowOverflow4) |
397 | 432 | ||
398 | 433 | ||
434 | #if XCHAL_EXCM_LEVEL >= 2 | ||
435 | /* Not a window vector - but a convenient location | ||
436 | * (where we know there's space) for continuation of | ||
437 | * medium priority interrupt dispatch code. | ||
438 | * On entry here, a0 contains PS, and EPC2 contains saved a0: | ||
439 | */ | ||
440 | .align 4 | ||
441 | _SimulateUserKernelVectorException: | ||
442 | wsr a0, excsave2 | ||
443 | movi a0, 4 # LEVEL1_INTERRUPT cause | ||
444 | wsr a0, exccause | ||
445 | rsr a0, ps | ||
446 | bbsi.l a0, PS_UM_BIT, 1f # branch if user mode | ||
447 | rsr a0, excsave2 # restore a0 | ||
448 | j _KernelExceptionVector # simulate kernel vector exception | ||
449 | 1: rsr a0, excsave2 # restore a0 | ||
450 | j _UserExceptionVector # simulate user vector exception | ||
451 | #endif | ||
452 | |||
453 | |||
399 | /* 4-Register Window Underflow Vector (Handler) */ | 454 | /* 4-Register Window Underflow Vector (Handler) */ |
400 | 455 | ||
401 | ENTRY_ALIGN64(_WindowUnderflow4) | 456 | ENTRY_ALIGN64(_WindowUnderflow4) |