aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorMarc Gauthier <marc@tensilica.com>2013-01-04 19:57:17 -0500
committerChris Zankel <chris@zankel.net>2013-02-23 22:12:52 -0500
commit2d1c645cc50b8f5a718b24bad9eb3931e7105d12 (patch)
treec385e5064cee10f79b9c359ddd99bd5d1b9f838a /arch/xtensa
parentd0b73b488c55df905ea8faaad079f8535629ed26 (diff)
xtensa: dispatch medium-priority interrupts
Add support for dispatching medium-priority interrupts, that is, interrupts of priority levels 2 to EXCM_LEVEL. IRQ handling may be preempted by higher priority IRQ. Signed-off-by: Marc Gauthier <marc@tensilica.com> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/include/asm/atomic.h6
-rw-r--r--arch/xtensa/include/asm/processor.h4
-rw-r--r--arch/xtensa/include/asm/regs.h1
-rw-r--r--arch/xtensa/include/asm/timex.h8
-rw-r--r--arch/xtensa/kernel/entry.S55
-rw-r--r--arch/xtensa/kernel/head.S9
-rw-r--r--arch/xtensa/kernel/setup.c42
-rw-r--r--arch/xtensa/kernel/traps.c55
-rw-r--r--arch/xtensa/kernel/vectors.S57
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S68
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
6531:
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
6531: wsr a0, depc 675 .align 16
6762:
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 679 rfe
680
681 .align 16
682 /* no rfi for level-1 irq, handled by rfe above*/
683 nop
684
685 irq_exit_level 2
686 irq_exit_level 3
687 irq_exit_level 4
688 irq_exit_level 5
689 irq_exit_level 6
657 690
658ENDPROC(kernel_exception) 691ENDPROC(kernel_exception)
659 692
@@ -753,7 +786,7 @@ ENTRY(unrecoverable_exception)
753 wsr a1, windowbase 786 wsr a1, windowbase
754 rsync 787 rsync
755 788
756 movi a1, (1 << PS_WOE_BIT) | 1 789 movi a1, (1 << PS_WOE_BIT) | LOCKLEVEL
757 wsr a1, ps 790 wsr a1, ps
758 rsync 791 rsync
759 792
@@ -1474,7 +1507,7 @@ ENTRY(_spill_registers)
1474 l32i a1, a3, EXC_TABLE_KSTK 1507 l32i a1, a3, EXC_TABLE_KSTK
1475 wsr a3, excsave1 1508 wsr a3, excsave1
1476 1509
1477 movi a4, (1 << PS_WOE_BIT) | 1 1510 movi a4, (1 << PS_WOE_BIT) | LOCKLEVEL
1478 wsr a4, ps 1511 wsr a4, ps
1479 rsync 1512 rsync
1480 1513
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index 91d9095284de..df88f98737f4 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.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) 2001 - 2005 Tensilica Inc. 10 * Copyright (C) 2001 - 2008 Tensilica Inc.
11 * 11 *
12 * Chris Zankel <chris@zankel.net> 12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> 13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
@@ -128,14 +128,14 @@ ENTRY(_startup)
128 wsr a0, cpenable 128 wsr a0, cpenable
129#endif 129#endif
130 130
131 /* Set PS.INTLEVEL=1, PS.WOE=0, kernel stack, PS.EXCM=0 131 /* Set PS.INTLEVEL=LOCKLEVEL, PS.WOE=0, kernel stack, PS.EXCM=0
132 * 132 *
133 * Note: PS.EXCM must be cleared before using any loop 133 * Note: PS.EXCM must be cleared before using any loop
134 * instructions; otherwise, they are silently disabled, and 134 * instructions; otherwise, they are silently disabled, and
135 * at most one iteration of the loop is executed. 135 * at most one iteration of the loop is executed.
136 */ 136 */
137 137
138 movi a1, 1 138 movi a1, LOCKLEVEL
139 wsr a1, ps 139 wsr a1, ps
140 rsync 140 rsync
141 141
@@ -211,7 +211,8 @@ ENTRY(_startup)
211 movi a1, init_thread_union 211 movi a1, init_thread_union
212 addi a1, a1, KERNEL_STACK_SIZE 212 addi a1, a1, KERNEL_STACK_SIZE
213 213
214 movi a2, 0x00040001 # WOE=1, INTLEVEL=1, UM=0 214 movi a2, (1 << PS_WOE_BIT) | LOCKLEVEL
215 # WOE=1, INTLEVEL=LOCKLEVEL, UM=0
215 wsr a2, ps # (enable reg-windows; progmode stack) 216 wsr a2, ps # (enable reg-windows; progmode stack)
216 rsync 217 rsync
217 218
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 24c1a57abb40..6dd25ecde3f5 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -328,6 +328,27 @@ extern char _UserExceptionVector_literal_start;
328extern char _UserExceptionVector_text_end; 328extern char _UserExceptionVector_text_end;
329extern char _DoubleExceptionVector_literal_start; 329extern char _DoubleExceptionVector_literal_start;
330extern char _DoubleExceptionVector_text_end; 330extern char _DoubleExceptionVector_text_end;
331#if XCHAL_EXCM_LEVEL >= 2
332extern char _Level2InterruptVector_text_start;
333extern char _Level2InterruptVector_text_end;
334#endif
335#if XCHAL_EXCM_LEVEL >= 3
336extern char _Level3InterruptVector_text_start;
337extern char _Level3InterruptVector_text_end;
338#endif
339#if XCHAL_EXCM_LEVEL >= 4
340extern char _Level4InterruptVector_text_start;
341extern char _Level4InterruptVector_text_end;
342#endif
343#if XCHAL_EXCM_LEVEL >= 5
344extern char _Level5InterruptVector_text_start;
345extern char _Level5InterruptVector_text_end;
346#endif
347#if XCHAL_EXCM_LEVEL >= 6
348extern char _Level6InterruptVector_text_start;
349extern char _Level6InterruptVector_text_end;
350#endif
351
331 352
332 353
333#ifdef CONFIG_S32C1I_SELFTEST 354#ifdef CONFIG_S32C1I_SELFTEST
@@ -482,6 +503,27 @@ void __init setup_arch(char **cmdline_p)
482 mem_reserve(__pa(&_DoubleExceptionVector_literal_start), 503 mem_reserve(__pa(&_DoubleExceptionVector_literal_start),
483 __pa(&_DoubleExceptionVector_text_end), 0); 504 __pa(&_DoubleExceptionVector_text_end), 0);
484 505
506#if XCHAL_EXCM_LEVEL >= 2
507 mem_reserve(__pa(&_Level2InterruptVector_text_start),
508 __pa(&_Level2InterruptVector_text_end), 0);
509#endif
510#if XCHAL_EXCM_LEVEL >= 3
511 mem_reserve(__pa(&_Level3InterruptVector_text_start),
512 __pa(&_Level3InterruptVector_text_end), 0);
513#endif
514#if XCHAL_EXCM_LEVEL >= 4
515 mem_reserve(__pa(&_Level4InterruptVector_text_start),
516 __pa(&_Level4InterruptVector_text_end), 0);
517#endif
518#if XCHAL_EXCM_LEVEL >= 5
519 mem_reserve(__pa(&_Level5InterruptVector_text_start),
520 __pa(&_Level5InterruptVector_text_end), 0);
521#endif
522#if XCHAL_EXCM_LEVEL >= 6
523 mem_reserve(__pa(&_Level6InterruptVector_text_start),
524 __pa(&_Level6InterruptVector_text_end), 0);
525#endif
526
485 bootmem_init(); 527 bootmem_init();
486 528
487#ifdef CONFIG_OF 529#ifdef CONFIG_OF
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 01e0111bf787..9b5c345d2b4f 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -193,28 +193,49 @@ void do_multihit(struct pt_regs *regs, unsigned long exccause)
193} 193}
194 194
195/* 195/*
196 * Level-1 interrupt. 196 * IRQ handler.
197 * We currently have no priority encoding. 197 * PS.INTLEVEL is the current IRQ priority level.
198 */ 198 */
199 199
200unsigned long ignored_level1_interrupts;
201extern void do_IRQ(int, struct pt_regs *); 200extern void do_IRQ(int, struct pt_regs *);
202 201
203void do_interrupt (struct pt_regs *regs) 202void do_interrupt(struct pt_regs *regs)
204{ 203{
205 unsigned long intread = get_sr (interrupt); 204 static const unsigned int_level_mask[] = {
206 unsigned long intenable = get_sr (intenable); 205 0,
207 int i, mask; 206 XCHAL_INTLEVEL1_MASK,
208 207 XCHAL_INTLEVEL2_MASK,
209 /* Handle all interrupts (no priorities). 208 XCHAL_INTLEVEL3_MASK,
210 * (Clear the interrupt before processing, in case it's 209 XCHAL_INTLEVEL4_MASK,
211 * edge-triggered or software-generated) 210 XCHAL_INTLEVEL5_MASK,
212 */ 211 XCHAL_INTLEVEL6_MASK,
212 XCHAL_INTLEVEL7_MASK,
213 };
214 unsigned level = get_sr(ps) & PS_INTLEVEL_MASK;
215
216 if (WARN_ON_ONCE(level >= ARRAY_SIZE(int_level_mask)))
217 return;
213 218
214 for (i=0, mask = 1; i < XCHAL_NUM_INTERRUPTS; i++, mask <<= 1) { 219 for (;;) {
215 if (mask & (intread & intenable)) { 220 unsigned intread = get_sr(interrupt);
216 set_sr (mask, intclear); 221 unsigned intenable = get_sr(intenable);
217 do_IRQ (i,regs); 222 unsigned int_at_level = intread & intenable &
223 int_level_mask[level];
224
225 if (!int_at_level)
226 return;
227
228 /*
229 * Clear the interrupt before processing, in case it's
230 * edge-triggered or software-generated
231 */
232 while (int_at_level) {
233 unsigned i = __ffs(int_at_level);
234 unsigned mask = 1 << i;
235
236 int_at_level ^= mask;
237 set_sr(mask, intclear);
238 do_IRQ(i, regs);
218 } 239 }
219 } 240 }
220} 241}
@@ -397,7 +418,7 @@ static inline void spill_registers(void)
397 unsigned int a0, ps; 418 unsigned int a0, ps;
398 419
399 __asm__ __volatile__ ( 420 __asm__ __volatile__ (
400 "movi a14, " __stringify(PS_EXCM_BIT | 1) "\n\t" 421 "movi a14, " __stringify(PS_EXCM_BIT | LOCKLEVEL) "\n\t"
401 "mov a12, a0\n\t" 422 "mov a12, a0\n\t"
402 "rsr a13, sar\n\t" 423 "rsr a13, sar\n\t"
403 "xsr a14, ps\n\t" 424 "xsr a14, ps\n\t"
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)
366ENDPROC(_DebugInterruptVector) 366ENDPROC(_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"
387ENTRY(_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)
396ENDPROC(_WindowOverflow4) 431ENDPROC(_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
4491: 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
401ENTRY_ALIGN64(_WindowUnderflow4) 456ENTRY_ALIGN64(_WindowUnderflow4)
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 255154f820b7..14695240536d 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.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) 2001 - 2005 Tensilica Inc. 10 * Copyright (C) 2001 - 2008 Tensilica Inc.
11 * 11 *
12 * Chris Zankel <chris@zankel.net> 12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca> 13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
@@ -134,6 +134,26 @@ SECTIONS
134 134
135 RELOCATE_ENTRY(_WindowVectors_text, 135 RELOCATE_ENTRY(_WindowVectors_text,
136 .WindowVectors.text); 136 .WindowVectors.text);
137#if XCHAL_EXCM_LEVEL >= 2
138 RELOCATE_ENTRY(_Level2InterruptVector_text,
139 .Level2InterruptVector.text);
140#endif
141#if XCHAL_EXCM_LEVEL >= 3
142 RELOCATE_ENTRY(_Level3InterruptVector_text,
143 .Level3InterruptVector.text);
144#endif
145#if XCHAL_EXCM_LEVEL >= 4
146 RELOCATE_ENTRY(_Level4InterruptVector_text,
147 .Level4InterruptVector.text);
148#endif
149#if XCHAL_EXCM_LEVEL >= 5
150 RELOCATE_ENTRY(_Level5InterruptVector_text,
151 .Level5InterruptVector.text);
152#endif
153#if XCHAL_EXCM_LEVEL >= 6
154 RELOCATE_ENTRY(_Level6InterruptVector_text,
155 .Level6InterruptVector.text);
156#endif
137 RELOCATE_ENTRY(_KernelExceptionVector_text, 157 RELOCATE_ENTRY(_KernelExceptionVector_text,
138 .KernelExceptionVector.text); 158 .KernelExceptionVector.text);
139 RELOCATE_ENTRY(_UserExceptionVector_text, 159 RELOCATE_ENTRY(_UserExceptionVector_text,
@@ -177,11 +197,53 @@ SECTIONS
177 XCHAL_DEBUG_VECTOR_VADDR, 197 XCHAL_DEBUG_VECTOR_VADDR,
178 4, 198 4,
179 .DebugInterruptVector.literal) 199 .DebugInterruptVector.literal)
200#undef LAST
201#define LAST .DebugInterruptVector.text
202#if XCHAL_EXCM_LEVEL >= 2
203 SECTION_VECTOR (_Level2InterruptVector_text,
204 .Level2InterruptVector.text,
205 XCHAL_INTLEVEL2_VECTOR_VADDR,
206 SIZEOF(LAST), LAST)
207# undef LAST
208# define LAST .Level2InterruptVector.text
209#endif
210#if XCHAL_EXCM_LEVEL >= 3
211 SECTION_VECTOR (_Level3InterruptVector_text,
212 .Level3InterruptVector.text,
213 XCHAL_INTLEVEL3_VECTOR_VADDR,
214 SIZEOF(LAST), LAST)
215# undef LAST
216# define LAST .Level3InterruptVector.text
217#endif
218#if XCHAL_EXCM_LEVEL >= 4
219 SECTION_VECTOR (_Level4InterruptVector_text,
220 .Level4InterruptVector.text,
221 XCHAL_INTLEVEL4_VECTOR_VADDR,
222 SIZEOF(LAST), LAST)
223# undef LAST
224# define LAST .Level4InterruptVector.text
225#endif
226#if XCHAL_EXCM_LEVEL >= 5
227 SECTION_VECTOR (_Level5InterruptVector_text,
228 .Level5InterruptVector.text,
229 XCHAL_INTLEVEL5_VECTOR_VADDR,
230 SIZEOF(LAST), LAST)
231# undef LAST
232# define LAST .Level5InterruptVector.text
233#endif
234#if XCHAL_EXCM_LEVEL >= 6
235 SECTION_VECTOR (_Level6InterruptVector_text,
236 .Level6InterruptVector.text,
237 XCHAL_INTLEVEL6_VECTOR_VADDR,
238 SIZEOF(LAST), LAST)
239# undef LAST
240# define LAST .Level6InterruptVector.text
241#endif
180 SECTION_VECTOR (_KernelExceptionVector_literal, 242 SECTION_VECTOR (_KernelExceptionVector_literal,
181 .KernelExceptionVector.literal, 243 .KernelExceptionVector.literal,
182 XCHAL_KERNEL_VECTOR_VADDR - 4, 244 XCHAL_KERNEL_VECTOR_VADDR - 4,
183 SIZEOF(.DebugInterruptVector.text), 245 SIZEOF(LAST), LAST)
184 .DebugInterruptVector.text) 246#undef LAST
185 SECTION_VECTOR (_KernelExceptionVector_text, 247 SECTION_VECTOR (_KernelExceptionVector_text,
186 .KernelExceptionVector.text, 248 .KernelExceptionVector.text,
187 XCHAL_KERNEL_VECTOR_VADDR, 249 XCHAL_KERNEL_VECTOR_VADDR,