diff options
| -rw-r--r-- | arch/xtensa/include/asm/atomic.h | 6 | ||||
| -rw-r--r-- | arch/xtensa/include/asm/processor.h | 4 | ||||
| -rw-r--r-- | arch/xtensa/include/asm/regs.h | 1 | ||||
| -rw-r--r-- | arch/xtensa/include/asm/timex.h | 8 | ||||
| -rw-r--r-- | arch/xtensa/kernel/entry.S | 55 | ||||
| -rw-r--r-- | arch/xtensa/kernel/head.S | 9 | ||||
| -rw-r--r-- | arch/xtensa/kernel/setup.c | 42 | ||||
| -rw-r--r-- | arch/xtensa/kernel/traps.c | 55 | ||||
| -rw-r--r-- | arch/xtensa/kernel/vectors.S | 57 | ||||
| -rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 68 |
10 files changed, 260 insertions, 45 deletions
diff --git a/arch/xtensa/include/asm/atomic.h b/arch/xtensa/include/asm/atomic.h index c3f289174c10..e7fb447bce8e 100644 --- a/arch/xtensa/include/asm/atomic.h +++ b/arch/xtensa/include/asm/atomic.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
| 8 | * for more details. | 8 | * for more details. |
| 9 | * | 9 | * |
| 10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #ifndef _XTENSA_ATOMIC_H | 13 | #ifndef _XTENSA_ATOMIC_H |
| @@ -24,11 +24,11 @@ | |||
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * This Xtensa implementation assumes that the right mechanism | 26 | * This Xtensa implementation assumes that the right mechanism |
| 27 | * for exclusion is for locking interrupts to level 1. | 27 | * for exclusion is for locking interrupts to level EXCM_LEVEL. |
| 28 | * | 28 | * |
| 29 | * Locking interrupts looks like this: | 29 | * Locking interrupts looks like this: |
| 30 | * | 30 | * |
| 31 | * rsil a15, 1 | 31 | * rsil a15, LOCKLEVEL |
| 32 | * <code> | 32 | * <code> |
| 33 | * wsr a15, PS | 33 | * wsr a15, PS |
| 34 | * rsync | 34 | * rsync |
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h index e5fb6b0abdf4..7e409a5b0ec5 100644 --- a/arch/xtensa/include/asm/processor.h +++ b/arch/xtensa/include/asm/processor.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #ifndef _XTENSA_PROCESSOR_H | 11 | #ifndef _XTENSA_PROCESSOR_H |
| @@ -68,7 +68,7 @@ | |||
| 68 | /* LOCKLEVEL defines the interrupt level that masks all | 68 | /* LOCKLEVEL defines the interrupt level that masks all |
| 69 | * general-purpose interrupts. | 69 | * general-purpose interrupts. |
| 70 | */ | 70 | */ |
| 71 | #define LOCKLEVEL 1 | 71 | #define LOCKLEVEL XCHAL_EXCM_LEVEL |
| 72 | 72 | ||
| 73 | /* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE | 73 | /* WSBITS and WBBITS are the width of the WINDOWSTART and WINDOWBASE |
| 74 | * registers | 74 | * registers |
diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h index 76096a4e5b8d..b24de6717020 100644 --- a/arch/xtensa/include/asm/regs.h +++ b/arch/xtensa/include/asm/regs.h | |||
| @@ -88,6 +88,7 @@ | |||
| 88 | #define PS_UM_BIT 5 | 88 | #define PS_UM_BIT 5 |
| 89 | #define PS_EXCM_BIT 4 | 89 | #define PS_EXCM_BIT 4 |
| 90 | #define PS_INTLEVEL_SHIFT 0 | 90 | #define PS_INTLEVEL_SHIFT 0 |
| 91 | #define PS_INTLEVEL_WIDTH 4 | ||
| 91 | #define PS_INTLEVEL_MASK 0x0000000F | 92 | #define PS_INTLEVEL_MASK 0x0000000F |
| 92 | 93 | ||
| 93 | /* DBREAKCn register fields. */ | 94 | /* DBREAKCn register fields. */ |
diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h index 175b3d5e1b01..9e85ce8bd8dd 100644 --- a/arch/xtensa/include/asm/timex.h +++ b/arch/xtensa/include/asm/timex.h | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2008 Tensilica Inc. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #ifndef _XTENSA_TIMEX_H | 11 | #ifndef _XTENSA_TIMEX_H |
| @@ -19,13 +19,13 @@ | |||
| 19 | #define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL | 19 | #define _INTLEVEL(x) XCHAL_INT ## x ## _LEVEL |
| 20 | #define INTLEVEL(x) _INTLEVEL(x) | 20 | #define INTLEVEL(x) _INTLEVEL(x) |
| 21 | 21 | ||
| 22 | #if INTLEVEL(XCHAL_TIMER0_INTERRUPT) == 1 | 22 | #if INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL |
| 23 | # define LINUX_TIMER 0 | 23 | # define LINUX_TIMER 0 |
| 24 | # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT | 24 | # define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT |
| 25 | #elif INTLEVEL(XCHAL_TIMER1_INTERRUPT) == 1 | 25 | #elif INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL |
| 26 | # define LINUX_TIMER 1 | 26 | # define LINUX_TIMER 1 |
| 27 | # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT | 27 | # define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT |
| 28 | #elif INTLEVEL(XCHAL_TIMER2_INTERRUPT) == 1 | 28 | #elif INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL |
| 29 | # define LINUX_TIMER 2 | 29 | # define LINUX_TIMER 2 |
| 30 | # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT | 30 | # define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT |
| 31 | #else | 31 | #else |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index 3777fec85e7c..0ace2acbbad0 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * License. See the file "COPYING" in the main directory of this archive | 7 | * License. See the file "COPYING" in the main directory of this archive |
| 8 | * for more details. | 8 | * for more details. |
| 9 | * | 9 | * |
| 10 | * Copyright (C) 2004-2007 by Tensilica Inc. | 10 | * Copyright (C) 2004 - 2008 by Tensilica Inc. |
| 11 | * | 11 | * |
| 12 | * Chris Zankel <chris@zankel.net> | 12 | * Chris Zankel <chris@zankel.net> |
| 13 | * | 13 | * |
| @@ -349,15 +349,16 @@ common_exception: | |||
| 349 | * so we can allow exceptions and interrupts (*) again. | 349 | * so we can allow exceptions and interrupts (*) again. |
| 350 | * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X) | 350 | * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X) |
| 351 | * | 351 | * |
| 352 | * (*) We only allow interrupts if PS.INTLEVEL was not set to 1 before | 352 | * (*) We only allow interrupts of higher priority than current IRQ |
| 353 | * (interrupts disabled) and if this exception is not an interrupt. | ||
| 354 | */ | 353 | */ |
| 355 | 354 | ||
| 356 | rsr a3, ps | 355 | rsr a3, ps |
| 357 | addi a0, a0, -4 | 356 | addi a0, a0, -4 |
| 358 | movi a2, 1 | 357 | movi a2, 1 |
| 359 | extui a3, a3, 0, 1 # a3 = PS.INTLEVEL[0] | 358 | extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH |
| 360 | moveqz a3, a2, a0 # a3 = 1 iff interrupt exception | 359 | # a3 = PS.INTLEVEL |
| 360 | movnez a2, a3, a3 # a2 = 1: level-1, > 1: high priority | ||
| 361 | moveqz a3, a2, a0 # a3 = IRQ level iff interrupt | ||
| 361 | movi a2, 1 << PS_WOE_BIT | 362 | movi a2, 1 << PS_WOE_BIT |
| 362 | or a3, a3, a2 | 363 | or a3, a3, a2 |
| 363 | rsr a0, exccause | 364 | rsr a0, exccause |
| @@ -641,19 +642,51 @@ common_exception_exit: | |||
| 641 | 642 | ||
| 642 | l32i a0, a1, PT_DEPC | 643 | l32i a0, a1, PT_DEPC |
| 643 | l32i a3, a1, PT_AREG3 | 644 | l32i a3, a1, PT_AREG3 |
| 645 | _bltui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f | ||
| 646 | |||
| 647 | wsr a0, depc | ||
| 644 | l32i a2, a1, PT_AREG2 | 648 | l32i a2, a1, PT_AREG2 |
| 645 | _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f | 649 | l32i a0, a1, PT_AREG0 |
| 650 | l32i a1, a1, PT_AREG1 | ||
| 651 | rfde | ||
| 646 | 652 | ||
| 653 | 1: | ||
| 647 | /* Restore a0...a3 and return */ | 654 | /* Restore a0...a3 and return */ |
| 648 | 655 | ||
| 656 | rsr a0, ps | ||
| 657 | extui a2, a0, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH | ||
| 658 | movi a0, 2f | ||
| 659 | slli a2, a2, 4 | ||
| 660 | add a0, a2, a0 | ||
| 661 | l32i a2, a1, PT_AREG2 | ||
| 662 | jx a0 | ||
| 663 | |||
| 664 | .macro irq_exit_level level | ||
| 665 | .align 16 | ||
| 666 | .if XCHAL_EXCM_LEVEL >= \level | ||
| 667 | l32i a0, a1, PT_PC | ||
| 668 | wsr a0, epc\level | ||
| 649 | l32i a0, a1, PT_AREG0 | 669 | l32i a0, a1, PT_AREG0 |
| 650 | l32i a1, a1, PT_AREG1 | 670 | l32i a1, a1, PT_AREG1 |
| 651 | rfe | 671 | rfi \level |
| 672 | .endif | ||
| 673 | .endm | ||
| 652 | 674 | ||
| 653 | 1: wsr a0, depc | 675 | .align 16 |
| 676 | 2: | ||
| 654 | l32i a0, a1, PT_AREG0 | 677 | l32i a0, a1, PT_AREG0 |
| 655 | l32i a1, a1, PT_AREG1 | 678 | l32i a1, a1, PT_AREG1 |
| 656 | rfde | ||
