aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 17:38:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-09 17:38:16 -0400
commitc61c48dfe00907007df3b87e4ed271a5c143bdda (patch)
tree6d26bd3a8b4aa3cf35cad35fa27d1e0afe715db3 /arch/xtensa/kernel
parente30f4192456971623b40c97a027346b69457ef69 (diff)
parentb341d84c8ac5ecbf7aa0b3ccd0745d87e881953c (diff)
Merge tag 'xtensa-next-20130508' of git://github.com/czankel/xtensa-linux
Pull xtensa updates from Chris Zankel: "Support for the latest MMU architecture that allows for a larger accessible memory region, and various bug-fixes" * tag 'xtensa-next-20130508' of git://github.com/czankel/xtensa-linux: xtensa: Switch to asm-generic/linkage.h xtensa: fix redboot load address xtensa: ISS: fix timer_lock usage in rs_open xtensa: disable IRQs while IRQ handler is running xtensa: enable lockdep support xtensa: fix arch_irqs_disabled_flags implementation xtensa: add irq flags trace support xtensa: provide custom CALLER_ADDR* implementations xtensa: add stacktrace support xtensa: clean up stpill_registers xtensa: don't use a7 in simcalls xtensa: don't attempt to use unconfigured timers xtensa: provide default platform_pcibios_init implementation xtensa: remove KCORE_ELF again xtensa: document MMUv3 setup sequence xtensa: add MMU v3 support xtensa: fix ibreakenable register update xtensa: fix oprofile building as module
Diffstat (limited to 'arch/xtensa/kernel')
-rw-r--r--arch/xtensa/kernel/Makefile8
-rw-r--r--arch/xtensa/kernel/entry.S84
-rw-r--r--arch/xtensa/kernel/head.S39
-rw-r--r--arch/xtensa/kernel/platform.c1
-rw-r--r--arch/xtensa/kernel/stacktrace.c120
-rw-r--r--arch/xtensa/kernel/traps.c67
-rw-r--r--arch/xtensa/kernel/vectors.S16
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S48
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c5
9 files changed, 265 insertions, 123 deletions
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index c3a59d992ac0..1e7fc87a94bb 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -4,14 +4,16 @@
4 4
5extra-y := head.o vmlinux.lds 5extra-y := head.o vmlinux.lds
6 6
7obj-y := align.o entry.o irq.o coprocessor.o process.o ptrace.o \ 7obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \
8 setup.o signal.o syscall.o time.o traps.o vectors.o platform.o \ 8 ptrace.o setup.o signal.o stacktrace.o syscall.o time.o traps.o \
9 pci-dma.o 9 vectors.o
10 10
11obj-$(CONFIG_KGDB) += xtensa-stub.o 11obj-$(CONFIG_KGDB) += xtensa-stub.o
12obj-$(CONFIG_PCI) += pci.o 12obj-$(CONFIG_PCI) += pci.o
13obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o 13obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
14 14
15AFLAGS_head.o += -mtext-section-literals
16
15# In the Xtensa architecture, assembly generates literals which must always 17# In the Xtensa architecture, assembly generates literals which must always
16# precede the L32R instruction with a relative offset less than 256 kB. 18# precede the L32R instruction with a relative offset less than 256 kB.
17# Therefore, the .text and .literal section must be combined in parenthesis 19# Therefore, the .text and .literal section must be combined in parenthesis
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 63845f950792..5082507d5631 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -354,16 +354,16 @@ common_exception:
354 * so we can allow exceptions and interrupts (*) again. 354 * so we can allow exceptions and interrupts (*) again.
355 * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X) 355 * Set PS(EXCM = 0, UM = 0, RING = 0, OWB = 0, WOE = 1, INTLEVEL = X)
356 * 356 *
357 * (*) We only allow interrupts of higher priority than current IRQ 357 * (*) We only allow interrupts if they were previously enabled and
358 * we're not handling an IRQ
358 */ 359 */
359 360
360 rsr a3, ps 361 rsr a3, ps
361 addi a0, a0, -4 362 addi a0, a0, -EXCCAUSE_LEVEL1_INTERRUPT
362 movi a2, 1 363 movi a2, LOCKLEVEL
363 extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH 364 extui a3, a3, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
364 # a3 = PS.INTLEVEL 365 # a3 = PS.INTLEVEL
365 movnez a2, a3, a3 # a2 = 1: level-1, > 1: high priority 366 moveqz a3, a2, a0 # a3 = LOCKLEVEL iff interrupt
366 moveqz a3, a2, a0 # a3 = IRQ level iff interrupt
367 movi a2, 1 << PS_WOE_BIT 367 movi a2, 1 << PS_WOE_BIT
368 or a3, a3, a2 368 or a3, a3, a2
369 rsr a0, exccause 369 rsr a0, exccause
@@ -389,6 +389,22 @@ common_exception:
389 389
390 save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT 390 save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
391 391
392#ifdef CONFIG_TRACE_IRQFLAGS
393 l32i a4, a1, PT_DEPC
394 /* Double exception means we came here with an exception
395 * while PS.EXCM was set, i.e. interrupts disabled.
396 */
397 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
398 l32i a4, a1, PT_EXCCAUSE
399 bnei a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
400 /* We came here with an interrupt means interrupts were enabled
401 * and we've just disabled them.
402 */
403 movi a4, trace_hardirqs_off
404 callx4 a4
4051:
406#endif
407
392 /* Go to second-level dispatcher. Set up parameters to pass to the 408 /* Go to second-level dispatcher. Set up parameters to pass to the
393 * exception handler and call the exception handler. 409 * exception handler and call the exception handler.
394 */ 410 */
@@ -407,11 +423,29 @@ common_exception:
407 .global common_exception_return 423 .global common_exception_return
408common_exception_return: 424common_exception_return:
409 425
426#ifdef CONFIG_TRACE_IRQFLAGS
427 l32i a4, a1, PT_DEPC
428 /* Double exception means we came here with an exception
429 * while PS.EXCM was set, i.e. interrupts disabled.
430 */
431 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
432 l32i a4, a1, PT_EXCCAUSE
433 bnei a4, EXCCAUSE_LEVEL1_INTERRUPT, 1f
434 /* We came here with an interrupt means interrupts were enabled
435 * and we'll reenable them on return.
436 */
437 movi a4, trace_hardirqs_on
438 callx4 a4
4391:
440#endif
441
410 /* Jump if we are returning from kernel exceptions. */ 442 /* Jump if we are returning from kernel exceptions. */
411 443
4121: l32i a3, a1, PT_PS 4441: l32i a3, a1, PT_PS
413 _bbci.l a3, PS_UM_BIT, 4f 445 _bbci.l a3, PS_UM_BIT, 4f
414 446
447 rsil a2, 0
448
415 /* Specific to a user exception exit: 449 /* Specific to a user exception exit:
416 * We need to check some flags for signal handling and rescheduling, 450 * We need to check some flags for signal handling and rescheduling,
417 * and have to restore WB and WS, extra states, and all registers 451 * and have to restore WB and WS, extra states, and all registers
@@ -652,51 +686,19 @@ common_exception_exit:
652 686
653 l32i a0, a1, PT_DEPC 687 l32i a0, a1, PT_DEPC
654 l32i a3, a1, PT_AREG3 688 l32i a3, a1, PT_AREG3
655 _bltui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
656
657 wsr a0, depc
658 l32i a2, a1, PT_AREG2 689 l32i a2, a1, PT_AREG2
659 l32i a0, a1, PT_AREG0 690 _bgeui a0, VALID_DOUBLE_EXCEPTION_ADDRESS, 1f
660 l32i a1, a1, PT_AREG1
661 rfde
662 691
6631:
664 /* Restore a0...a3 and return */ 692 /* Restore a0...a3 and return */
665 693
666 rsr a0, ps
667 extui a2, a0, PS_INTLEVEL_SHIFT, PS_INTLEVEL_WIDTH
668 movi a0, 2f
669 slli a2, a2, 4
670 add a0, a2, a0
671 l32i a2, a1, PT_AREG2
672 jx a0
673
674 .macro irq_exit_level level
675 .align 16
676 .if XCHAL_EXCM_LEVEL >= \level
677 l32i a0, a1, PT_PC
678 wsr a0, epc\level
679 l32i a0, a1, PT_AREG0 694 l32i a0, a1, PT_AREG0
680 l32i a1, a1, PT_AREG1 695 l32i a1, a1, PT_AREG1
681 rfi \level 696 rfe
682 .endif
683 .endm
684 697
685 .align 16 6981: wsr a0, depc
6862:
687 l32i a0, a1, PT_AREG0 699 l32i a0, a1, PT_AREG0
688 l32i a1, a1, PT_AREG1 700 l32i a1, a1, PT_AREG1
689 rfe 701 rfde
690
691 .align 16
692 /* no rfi for level-1 irq, handled by rfe above*/
693 nop
694
695 irq_exit_level 2
696 irq_exit_level 3
697 irq_exit_level 4
698 irq_exit_level 5
699 irq_exit_level 6
700 702
701ENDPROC(kernel_exception) 703ENDPROC(kernel_exception)
702 704
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index df88f98737f4..ef12c0e6fa25 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -48,17 +48,36 @@
48 */ 48 */
49 49
50 __HEAD 50 __HEAD
51 .begin no-absolute-literals
52
51ENTRY(_start) 53ENTRY(_start)
52 54
53 _j 2f 55 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
56 wsr a2, excsave1
57 _j _SetupMMU
58
59 .align 4
60 .literal_position
61.Lstartup:
62 .word _startup
63
54 .align 4 64 .align 4
551: .word _startup 65 .global _SetupMMU
562: l32r a0, 1b 66_SetupMMU:
67 Offset = _SetupMMU - _start
68
69#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
70 initialize_mmu
71#endif
72 .end no-absolute-literals
73
74 l32r a0, .Lstartup
57 jx a0 75 jx a0
58 76
59ENDPROC(_start) 77ENDPROC(_start)
60 78
61 .section .init.text, "ax" 79 __INIT
80 .literal_position
62 81
63ENTRY(_startup) 82ENTRY(_startup)
64 83
@@ -67,10 +86,6 @@ ENTRY(_startup)
67 movi a0, LOCKLEVEL 86 movi a0, LOCKLEVEL
68 wsr a0, ps 87 wsr a0, ps
69 88
70 /* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
71
72 wsr a2, excsave1
73
74 /* Start with a fresh windowbase and windowstart. */ 89 /* Start with a fresh windowbase and windowstart. */
75 90
76 movi a1, 1 91 movi a1, 1
@@ -86,7 +101,9 @@ ENTRY(_startup)
86 /* Clear debugging registers. */ 101 /* Clear debugging registers. */
87 102
88#if XCHAL_HAVE_DEBUG 103#if XCHAL_HAVE_DEBUG
104#if XCHAL_NUM_IBREAK > 0
89 wsr a0, ibreakenable 105 wsr a0, ibreakenable
106#endif
90 wsr a0, icount 107 wsr a0, icount
91 movi a1, 15 108 movi a1, 15
92 wsr a0, icountlevel 109 wsr a0, icountlevel
@@ -156,8 +173,6 @@ ENTRY(_startup)
156 173
157 isync 174 isync
158 175
159 initialize_mmu
160
161 /* Unpack data sections 176 /* Unpack data sections
162 * 177 *
163 * The linker script used to build the Linux kernel image 178 * The linker script used to build the Linux kernel image
@@ -205,6 +220,10 @@ ENTRY(_startup)
205 220
206 ___flush_dcache_all a2 a3 221 ___flush_dcache_all a2 a3
207#endif 222#endif
223 memw
224 isync
225 ___invalidate_icache_all a2 a3
226 isync
208 227
209 /* Setup stack and enable window exceptions (keep irqs disabled) */ 228 /* Setup stack and enable window exceptions (keep irqs disabled) */
210 229
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 44bf21c3769a..2bd6c351f37c 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -36,6 +36,7 @@ _F(void, power_off, (void), { while(1); });
36_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); }); 36_F(void, idle, (void), { __asm__ __volatile__ ("waiti 0" ::: "memory"); });
37_F(void, heartbeat, (void), { }); 37_F(void, heartbeat, (void), { });
38_F(int, pcibios_fixup, (void), { return 0; }); 38_F(int, pcibios_fixup, (void), { return 0; });
39_F(void, pcibios_init, (void), { });
39 40
40#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT 41#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
41_F(void, calibrate_ccount, (void), 42_F(void, calibrate_ccount, (void),
diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c
new file mode 100644
index 000000000000..7d2c317bd98b
--- /dev/null
+++ b/arch/xtensa/kernel/stacktrace.c
@@ -0,0 +1,120 @@
1/*
2 * arch/xtensa/kernel/stacktrace.c
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 2001 - 2013 Tensilica Inc.
9 */
10#include <linux/export.h>
11#include <linux/sched.h>
12#include <linux/stacktrace.h>
13
14#include <asm/stacktrace.h>
15#include <asm/traps.h>
16
17void walk_stackframe(unsigned long *sp,
18 int (*fn)(struct stackframe *frame, void *data),
19 void *data)
20{
21 unsigned long a0, a1;
22 unsigned long sp_end;
23
24 a1 = (unsigned long)sp;
25 sp_end = ALIGN(a1, THREAD_SIZE);
26
27 spill_registers();
28
29 while (a1 < sp_end) {
30 struct stackframe frame;
31
32 sp = (unsigned long *)a1;
33
34 a0 = *(sp - 4);
35 a1 = *(sp - 3);
36
37 if (a1 <= (unsigned long)sp)
38 break;
39
40 frame.pc = MAKE_PC_FROM_RA(a0, a1);
41 frame.sp = a1;
42
43 if (fn(&frame, data))
44 return;
45 }
46}
47
48#ifdef CONFIG_STACKTRACE
49
50struct stack_trace_data {
51 struct stack_trace *trace;
52 unsigned skip;
53};
54
55static int stack_trace_cb(struct stackframe *frame, void *data)
56{
57 struct stack_trace_data *trace_data = data;
58 struct stack_trace *trace = trace_data->trace;
59
60 if (trace_data->skip) {
61 --trace_data->skip;
62 return 0;
63 }
64 if (!kernel_text_address(frame->pc))
65 return 0;
66
67 trace->entries[trace->nr_entries++] = frame->pc;
68 return trace->nr_entries >= trace->max_entries;
69}
70
71void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
72{
73 struct stack_trace_data trace_data = {
74 .trace = trace,
75 .skip = trace->skip,
76 };
77 walk_stackframe(stack_pointer(task), stack_trace_cb, &trace_data);
78}
79EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
80
81void save_stack_trace(struct stack_trace *trace)
82{
83 save_stack_trace_tsk(current, trace);
84}
85EXPORT_SYMBOL_GPL(save_stack_trace);
86
87#endif
88
89#ifdef CONFIG_FRAME_POINTER
90
91struct return_addr_data {
92 unsigned long addr;
93 unsigned skip;
94};
95
96static int return_address_cb(struct stackframe *frame, void *data)
97{
98 struct return_addr_data *r = data;
99
100 if (r->skip) {
101 --r->skip;
102 return 0;
103 }
104 if (!kernel_text_address(frame->pc))
105 return 0;
106 r->addr = frame->pc;
107 return 1;
108}
109
110unsigned long return_address(unsigned level)
111{
112 struct return_addr_data r = {
113 .skip = level + 1,
114 };
115 walk_stackframe(stack_pointer(NULL), return_address_cb, &r);
116 return r.addr;
117}
118EXPORT_SYMBOL(return_address);
119
120#endif
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c
index 458186dab5dc..3e8a05c874cd 100644
--- a/arch/xtensa/kernel/traps.c
+++ b/arch/xtensa/kernel/traps.c
@@ -11,7 +11,7 @@
11 * 11 *
12 * Essentially rewritten for the Xtensa architecture port. 12 * Essentially rewritten for the Xtensa architecture port.
13 * 13 *
14 * Copyright (C) 2001 - 2005 Tensilica Inc. 14 * Copyright (C) 2001 - 2013 Tensilica Inc.
15 * 15 *
16 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> 16 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
17 * Chris Zankel <chris@zankel.net> 17 * Chris Zankel <chris@zankel.net>
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/hardirq.h> 33#include <linux/hardirq.h>
34 34
35#include <asm/stacktrace.h>
35#include <asm/ptrace.h> 36#include <asm/ptrace.h>
36#include <asm/timex.h> 37#include <asm/timex.h>
37#include <asm/uaccess.h> 38#include <asm/uaccess.h>
@@ -195,7 +196,6 @@ void do_multihit(struct pt_regs *regs, unsigned long exccause)
195 196
196/* 197/*
197 * IRQ handler. 198 * IRQ handler.
198 * PS.INTLEVEL is the current IRQ priority level.
199 */ 199 */
200 200
201extern void do_IRQ(int, struct pt_regs *); 201extern void do_IRQ(int, struct pt_regs *);
@@ -212,18 +212,21 @@ void do_interrupt(struct pt_regs *regs)
212 XCHAL_INTLEVEL6_MASK, 212 XCHAL_INTLEVEL6_MASK,
213 XCHAL_INTLEVEL7_MASK, 213 XCHAL_INTLEVEL7_MASK,
214 }; 214 };
215 unsigned level = get_sr(ps) & PS_INTLEVEL_MASK;
216
217 if (WARN_ON_ONCE(level >= ARRAY_SIZE(int_level_mask)))
218 return;
219 215
220 for (;;) { 216 for (;;) {
221 unsigned intread = get_sr(interrupt); 217 unsigned intread = get_sr(interrupt);
222 unsigned intenable = get_sr(intenable); 218 unsigned intenable = get_sr(intenable);
223 unsigned int_at_level = intread & intenable & 219 unsigned int_at_level = intread & intenable;
224 int_level_mask[level]; 220 unsigned level;
221
222 for (level = LOCKLEVEL; level > 0; --level) {
223 if (int_at_level & int_level_mask[level]) {
224 int_at_level &= int_level_mask[level];
225 break;
226 }
227 }
225 228
226 if (!int_at_level) 229 if (level == 0)
227 return; 230 return;
228 231
229 /* 232 /*
@@ -404,53 +407,25 @@ void show_regs(struct pt_regs * regs)
404 regs->syscall); 407 regs->syscall);
405} 408}
406 409
407static __always_inline unsigned long *stack_pointer(struct task_struct *task) 410static int show_trace_cb(struct stackframe *frame, void *data)
408{ 411{
409 unsigned long *sp; 412 if (kernel_text_address(frame->pc)) {
410 413 printk(" [<%08lx>] ", frame->pc);
411 if (!task || task == current) 414 print_symbol("%s\n", frame->pc);
412 __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp)); 415 }
413 else 416 return 0;
414 sp = (unsigned long *)task->thread.sp;
415
416 return sp;
417} 417}
418 418
419void show_trace(struct task_struct *task, unsigned long *sp) 419void show_trace(struct task_struct *task, unsigned long *sp)
420{ 420{
421 unsigned long a0, a1, pc; 421 if (!sp)
422 unsigned long sp_start, sp_end; 422 sp = stack_pointer(task);
423
424 if (sp)
425 a1 = (unsigned long)sp;
426 else
427 a1 = (unsigned long)stack_pointer(task);
428
429 sp_start = a1 & ~(THREAD_SIZE-1);
430 sp_end = sp_start + THREAD_SIZE;
431 423
432 printk("Call Trace:"); 424 printk("Call Trace:");
433#ifdef CONFIG_KALLSYMS 425#ifdef CONFIG_KALLSYMS
434 printk("\n"); 426 printk("\n");
435#endif 427#endif
436 spill_registers(); 428 walk_stackframe(sp, show_trace_cb, NULL);
437
438 while (a1 > sp_start && a1 < sp_end) {
439 sp = (unsigned long*)a1;
440
441 a0 = *(sp - 4);
442 a1 = *(sp - 3);
443
444 if (a1 <= (unsigned long) sp)
445 break;
446
447 pc = MAKE_PC_FROM_RA(a0, a1);
448
449 if (kernel_text_address(pc)) {
450 printk(" [<%08lx>] ", pc);
451 print_symbol("%s\n", pc);
452 }
453 }
454 printk("\n"); 429 printk("\n");
455} 430}
456 431
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 82109b42e240..f9e175382aa9 100644
--- a/arch/xtensa/kernel/vectors.S
+++ b/arch/xtensa/kernel/vectors.S
@@ -50,6 +50,7 @@
50#include <asm/processor.h> 50#include <asm/processor.h>
51#include <asm/page.h> 51#include <asm/page.h>
52#include <asm/thread_info.h> 52#include <asm/thread_info.h>
53#include <asm/vectors.h>
53 54
54#define WINDOW_VECTORS_SIZE 0x180 55#define WINDOW_VECTORS_SIZE 0x180
55 56
@@ -220,7 +221,7 @@ ENTRY(_DoubleExceptionVector)
220 221
221 xsr a0, depc # get DEPC, save a0 222 xsr a0, depc # get DEPC, save a0
222 223
223 movi a3, XCHAL_WINDOW_VECTORS_VADDR 224 movi a3, WINDOW_VECTORS_VADDR
224 _bltu a0, a3, .Lfixup 225 _bltu a0, a3, .Lfixup
225 addi a3, a3, WINDOW_VECTORS_SIZE 226 addi a3, a3, WINDOW_VECTORS_SIZE
226 _bgeu a0, a3, .Lfixup 227 _bgeu a0, a3, .Lfixup
@@ -385,9 +386,12 @@ ENDPROC(_DebugInterruptVector)
385 .if XCHAL_EXCM_LEVEL >= \level 386 .if XCHAL_EXCM_LEVEL >= \level
386 .section .Level\level\()InterruptVector.text, "ax" 387 .section .Level\level\()InterruptVector.text, "ax"
387ENTRY(_Level\level\()InterruptVector) 388ENTRY(_Level\level\()InterruptVector)
388 wsr a0, epc1 389 wsr a0, excsave2
389 rsr a0, epc\level 390 rsr a0, epc\level
390 xsr a0, epc1 391 wsr a0, epc1
392 movi a0, EXCCAUSE_LEVEL1_INTERRUPT
393 wsr a0, exccause
394 rsr a0, eps\level
391 # branch to user or kernel vector 395 # branch to user or kernel vector
392 j _SimulateUserKernelVectorException 396 j _SimulateUserKernelVectorException
393 .endif 397 .endif
@@ -439,10 +443,8 @@ ENDPROC(_WindowOverflow4)
439 */ 443 */
440 .align 4 444 .align 4
441_SimulateUserKernelVectorException: 445_SimulateUserKernelVectorException:
442 wsr a0, excsave2 446 addi a0, a0, (1 << PS_EXCM_BIT)
443 movi a0, 4 # LEVEL1_INTERRUPT cause 447 wsr a0, ps
444 wsr a0, exccause
445 rsr a0, ps
446 bbsi.l a0, PS_UM_BIT, 1f # branch if user mode 448 bbsi.l a0, PS_UM_BIT, 1f # branch if user mode
447 rsr a0, excsave2 # restore a0 449 rsr a0, excsave2 # restore a0
448 j _KernelExceptionVector # simulate kernel vector exception 450 j _KernelExceptionVector # simulate kernel vector exception
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S
index 14695240536d..21acd11b5df2 100644
--- a/arch/xtensa/kernel/vmlinux.lds.S
+++ b/arch/xtensa/kernel/vmlinux.lds.S
@@ -18,6 +18,7 @@
18#include <asm/page.h> 18#include <asm/page.h>
19#include <asm/thread_info.h> 19#include <asm/thread_info.h>
20 20
21#include <asm/vectors.h>
21#include <variant/core.h> 22#include <variant/core.h>
22#include <platform/hardware.h> 23#include <platform/hardware.h>
23OUTPUT_ARCH(xtensa) 24OUTPUT_ARCH(xtensa)
@@ -30,7 +31,7 @@ jiffies = jiffies_64;
30#endif 31#endif
31 32
32#ifndef KERNELOFFSET 33#ifndef KERNELOFFSET
33#define KERNELOFFSET 0xd0001000 34#define KERNELOFFSET 0xd0003000
34#endif 35#endif
35 36
36/* Note: In the following macros, it would be nice to specify only the 37/* Note: In the following macros, it would be nice to specify only the
@@ -185,16 +186,16 @@ SECTIONS
185 186
186 SECTION_VECTOR (_WindowVectors_text, 187 SECTION_VECTOR (_WindowVectors_text,
187 .WindowVectors.text, 188 .WindowVectors.text,
188 XCHAL_WINDOW_VECTORS_VADDR, 4, 189 WINDOW_VECTORS_VADDR, 4,
189 .dummy) 190 .dummy)
190 SECTION_VECTOR (_DebugInterruptVector_literal, 191 SECTION_VECTOR (_DebugInterruptVector_literal,
191 .DebugInterruptVector.literal, 192 .DebugInterruptVector.literal,
192 XCHAL_DEBUG_VECTOR_VADDR - 4, 193 DEBUG_VECTOR_VADDR - 4,
193 SIZEOF(.WindowVectors.text), 194 SIZEOF(.WindowVectors.text),
194 .WindowVectors.text) 195 .WindowVectors.text)
195 SECTION_VECTOR (_DebugInterruptVector_text, 196 SECTION_VECTOR (_DebugInterruptVector_text,
196 .DebugInterruptVector.text, 197 .DebugInterruptVector.text,
197 XCHAL_DEBUG_VECTOR_VADDR, 198 DEBUG_VECTOR_VADDR,
198 4, 199 4,
199 .DebugInterruptVector.literal) 200 .DebugInterruptVector.literal)
200#undef LAST 201#undef LAST
@@ -202,7 +203,7 @@ SECTIONS
202#if XCHAL_EXCM_LEVEL >= 2 203#if XCHAL_EXCM_LEVEL >= 2
203 SECTION_VECTOR (_Level2InterruptVector_text, 204 SECTION_VECTOR (_Level2InterruptVector_text,
204 .Level2InterruptVector.text, 205 .Level2InterruptVector.text,
205 XCHAL_INTLEVEL2_VECTOR_VADDR, 206 INTLEVEL2_VECTOR_VADDR,
206 SIZEOF(LAST), LAST) 207 SIZEOF(LAST), LAST)
207# undef LAST 208# undef LAST
208# define LAST .Level2InterruptVector.text 209# define LAST .Level2InterruptVector.text
@@ -210,7 +211,7 @@ SECTIONS
210#if XCHAL_EXCM_LEVEL >= 3 211#if XCHAL_EXCM_LEVEL >= 3
211 SECTION_VECTOR (_Level3InterruptVector_text, 212 SECTION_VECTOR (_Level3InterruptVector_text,
212 .Level3InterruptVector.text, 213 .Level3InterruptVector.text,
213 XCHAL_INTLEVEL3_VECTOR_VADDR, 214 INTLEVEL3_VECTOR_VADDR,
214 SIZEOF(LAST), LAST) 215 SIZEOF(LAST), LAST)
215# undef LAST 216# undef LAST
216# define LAST .Level3InterruptVector.text 217# define LAST .Level3InterruptVector.text
@@ -218,7 +219,7 @@ SECTIONS
218#if XCHAL_EXCM_LEVEL >= 4 219#if XCHAL_EXCM_LEVEL >= 4
219 SECTION_VECTOR (_Level4InterruptVector_text, 220 SECTION_VECTOR (_Level4InterruptVector_text,
220 .Level4InterruptVector.text, 221 .Level4InterruptVector.text,
221 XCHAL_INTLEVEL4_VECTOR_VADDR, 222 INTLEVEL4_VECTOR_VADDR,
222 SIZEOF(LAST), LAST) 223 SIZEOF(LAST), LAST)
223# undef LAST 224# undef LAST
224# define LAST .Level4InterruptVector.text 225# define LAST .Level4InterruptVector.text
@@ -226,7 +227,7 @@ SECTIONS
226#if XCHAL_EXCM_LEVEL >= 5 227#if XCHAL_EXCM_LEVEL >= 5
227 SECTION_VECTOR (_Level5InterruptVector_text, 228 SECTION_VECTOR (_Level5InterruptVector_text,
228 .Level5InterruptVector.text, 229 .Level5InterruptVector.text,
229 XCHAL_INTLEVEL5_VECTOR_VADDR, 230 INTLEVEL5_VECTOR_VADDR,
230 SIZEOF(LAST), LAST) 231 SIZEOF(LAST), LAST)
231# undef LAST 232# undef LAST
232# define LAST .Level5InterruptVector.text 233# define LAST .Level5InterruptVector.text
@@ -234,39 +235,39 @@ SECTIONS
234#if XCHAL_EXCM_LEVEL >= 6 235#if XCHAL_EXCM_LEVEL >= 6
235 SECTION_VECTOR (_Level6InterruptVector_text, 236 SECTION_VECTOR (_Level6InterruptVector_text,
236 .Level6InterruptVector.text, 237 .Level6InterruptVector.text,
237 XCHAL_INTLEVEL6_VECTOR_VADDR, 238 INTLEVEL6_VECTOR_VADDR,
238 SIZEOF(LAST), LAST) 239 SIZEOF(LAST), LAST)
239# undef LAST 240# undef LAST
240# define LAST .Level6InterruptVector.text 241# define LAST .Level6InterruptVector.text
241#endif 242#endif
242 SECTION_VECTOR (_KernelExceptionVector_literal, 243 SECTION_VECTOR (_KernelExceptionVector_literal,
243 .KernelExceptionVector.literal, 244 .KernelExceptionVector.literal,
244 XCHAL_KERNEL_VECTOR_VADDR - 4, 245 KERNEL_VECTOR_VADDR - 4,
245 SIZEOF(LAST), LAST) 246 SIZEOF(LAST), LAST)
246#undef LAST 247#undef LAST
247 SECTION_VECTOR (_KernelExceptionVector_text, 248 SECTION_VECTOR (_KernelExceptionVector_text,
248 .KernelExceptionVector.text, 249 .KernelExceptionVector.text,
249 XCHAL_KERNEL_VECTOR_VADDR, 250 KERNEL_VECTOR_VADDR,
250 4, 251 4,
251 .KernelExceptionVector.literal) 252 .KernelExceptionVector.literal)
252 SECTION_VECTOR (_UserExceptionVector_literal, 253 SECTION_VECTOR (_UserExceptionVector_literal,
253 .UserExceptionVector.literal, 254 .UserExceptionVector.literal,
254 XCHAL_USER_VECTOR_VADDR - 4, 255 USER_VECTOR_VADDR - 4,
255 SIZEOF(.KernelExceptionVector.text), 256 SIZEOF(.KernelExceptionVector.text),
256 .KernelExceptionVector.text) 257 .KernelExceptionVector.text)
257 SECTION_VECTOR (_UserExceptionVector_text, 258 SECTION_VECTOR (_UserExceptionVector_text,
258 .UserExceptionVector.text, 259 .UserExceptionVector.text,
259 XCHAL_USER_VECTOR_VADDR, 260 USER_VECTOR_VADDR,
260 4, 261 4,
261 .UserExceptionVector.literal) 262 .UserExceptionVector.literal)
262 SECTION_VECTOR (_DoubleExceptionVector_literal, 263 SECTION_VECTOR (_DoubleExceptionVector_literal,
263 .DoubleExceptionVector.literal, 264 .DoubleExceptionVector.literal,
264 XCHAL_DOUBLEEXC_VECTOR_VADDR - 16, 265 DOUBLEEXC_VECTOR_VADDR - 16,
265 SIZEOF(.UserExceptionVector.text), 266 SIZEOF(.UserExceptionVector.text),
266 .UserExceptionVector.text) 267 .UserExceptionVector.text)
267 SECTION_VECTOR (_DoubleExceptionVector_text, 268 SECTION_VECTOR (_DoubleExceptionVector_text,
268 .DoubleExceptionVector.text, 269 .DoubleExceptionVector.text,
269 XCHAL_DOUBLEEXC_VECTOR_VADDR, 270 DOUBLEEXC_VECTOR_VADDR,
270 32, 271 32,
271 .DoubleExceptionVector.literal) 272 .DoubleExceptionVector.literal)
272 273
@@ -284,11 +285,26 @@ SECTIONS
284 . = ALIGN(0x10); 285 . = ALIGN(0x10);
285 .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) } 286 .bootstrap : { *(.bootstrap.literal .bootstrap.text .bootstrap.data) }
286 287
287 .ResetVector.text XCHAL_RESET_VECTOR_VADDR : 288 .ResetVector.text RESET_VECTOR_VADDR :
288 { 289 {
289 *(.ResetVector.text) 290 *(.ResetVector.text)
290 } 291 }
291 292
293
294 /*
295 * This is a remapped copy of the Secondary Reset Vector Code.
296 * It keeps gdb in sync with the PC after switching
297 * to the temporary mapping used while setting up
298 * the V2 MMU mappings for Linux.
299 *
300 * Only debug information about this section is put in the kernel image.
301 */
302 .SecondaryResetVector.remapped_text 0x46000000 (INFO):
303 {
304 *(.SecondaryResetVector.remapped_text)
305 }
306
307
292 .xt.lit : { *(.xt.lit) } 308 .xt.lit : { *(.xt.lit) }
293 .xt.prop : { *(.xt.prop) } 309 .xt.prop : { *(.xt.prop) }
294 310
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index afe058b24e6e..42c53c87c204 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -119,3 +119,8 @@ EXPORT_SYMBOL(outsl);
119EXPORT_SYMBOL(insb); 119EXPORT_SYMBOL(insb);
120EXPORT_SYMBOL(insw); 120EXPORT_SYMBOL(insw);
121EXPORT_SYMBOL(insl); 121EXPORT_SYMBOL(insl);
122
123extern long common_exception_return;
124extern long _spill_registers;
125EXPORT_SYMBOL(common_exception_return);
126EXPORT_SYMBOL(_spill_registers);