aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
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
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')
-rw-r--r--arch/xtensa/Kconfig57
-rw-r--r--arch/xtensa/boot/boot-elf/Makefile1
-rw-r--r--arch/xtensa/boot/boot-elf/boot.lds.S64
-rw-r--r--arch/xtensa/boot/boot-elf/bootstrap.S101
-rw-r--r--arch/xtensa/boot/boot-redboot/boot.ld2
-rw-r--r--arch/xtensa/boot/boot-uboot/Makefile6
-rw-r--r--arch/xtensa/include/asm/Kbuild1
-rw-r--r--arch/xtensa/include/asm/ftrace.h34
-rw-r--r--arch/xtensa/include/asm/initialize_mmu.h107
-rw-r--r--arch/xtensa/include/asm/irqflags.h5
-rw-r--r--arch/xtensa/include/asm/linkage.h16
-rw-r--r--arch/xtensa/include/asm/stacktrace.h36
-rw-r--r--arch/xtensa/include/asm/timex.h9
-rw-r--r--arch/xtensa/include/asm/traps.h5
-rw-r--r--arch/xtensa/include/asm/vectors.h125
-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
-rw-r--r--arch/xtensa/mm/mmu.c14
-rw-r--r--arch/xtensa/oprofile/backtrace.c4
-rw-r--r--arch/xtensa/platforms/iss/console.c12
-rw-r--r--arch/xtensa/platforms/iss/include/platform/simcall.h24
-rw-r--r--arch/xtensa/platforms/iss/setup.c8
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c4
-rw-r--r--arch/xtensa/platforms/xt2000/setup.c2
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c2
32 files changed, 773 insertions, 254 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index acdfc615cca2..0a1b95f81a32 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -1,11 +1,9 @@
1config FRAME_POINTER
2 def_bool n
3
4config ZONE_DMA 1config ZONE_DMA
5 def_bool y 2 def_bool y
6 3
7config XTENSA 4config XTENSA
8 def_bool y 5 def_bool y
6 select ARCH_WANT_FRAME_POINTERS
9 select HAVE_IDE 7 select HAVE_IDE
10 select GENERIC_ATOMIC64 8 select GENERIC_ATOMIC64
11 select HAVE_GENERIC_HARDIRQS 9 select HAVE_GENERIC_HARDIRQS
@@ -49,6 +47,15 @@ config HZ
49source "init/Kconfig" 47source "init/Kconfig"
50source "kernel/Kconfig.freezer" 48source "kernel/Kconfig.freezer"
51 49
50config LOCKDEP_SUPPORT
51 def_bool y
52
53config STACKTRACE_SUPPORT
54 def_bool y
55
56config TRACE_IRQFLAGS_SUPPORT
57 def_bool y
58
52config MMU 59config MMU
53 def_bool n 60 def_bool n
54 61
@@ -100,6 +107,35 @@ config MATH_EMULATION
100 help 107 help
101 Can we use information of configuration file? 108 Can we use information of configuration file?
102 109
110config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
111 bool "Initialize Xtensa MMU inside the Linux kernel code"
112 default y
113 help
114 Earlier version initialized the MMU in the exception vector
115 before jumping to _startup in head.S and had an advantage that
116 it was possible to place a software breakpoint at 'reset' and
117 then enter your normal kernel breakpoints once the MMU was mapped
118 to the kernel mappings (0XC0000000).
119
120 This unfortunately doesn't work for U-Boot and likley also wont
121 work for using KEXEC to have a hot kernel ready for doing a
122 KDUMP.
123
124 So now the MMU is initialized in head.S but it's necessary to
125 use hardware breakpoints (gdb 'hbreak' cmd) to break at _startup.
126 xt-gdb can't place a Software Breakpoint in the 0XD region prior
127 to mapping the MMU and after mapping even if the area of low memory
128 was mapped gdb wouldn't remove the breakpoint on hitting it as the
129 PC wouldn't match. Since Hardware Breakpoints are recommended for
130 Linux configurations it seems reasonable to just assume they exist
131 and leave this older mechanism for unfortunate souls that choose
132 not to follow Tensilica's recommendation.
133
134 Selecting this will cause U-Boot to set the KERNEL Load and Entry
135 address at 0x00003000 instead of the mapped std of 0xD0003000.
136
137 If in doubt, say Y.
138
103endmenu 139endmenu
104 140
105config XTENSA_CALIBRATE_CCOUNT 141config XTENSA_CALIBRATE_CCOUNT
@@ -249,21 +285,6 @@ endmenu
249 285
250menu "Executable file formats" 286menu "Executable file formats"
251 287
252# only elf supported
253config KCORE_ELF
254 def_bool y
255 depends on PROC_FS
256 help
257 If you enabled support for /proc file system then the file
258 /proc/kcore will contain the kernel core image in ELF format. This
259 can be used in gdb:
260
261 $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
262
263 This is especially useful if you have compiled the kernel with the
264 "-g" option to preserve debugging information. It is mainly used
265 for examining kernel data structures on the live kernel.
266
267source "fs/Kconfig.binfmt" 288source "fs/Kconfig.binfmt"
268 289
269endmenu 290endmenu
diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile
index 1fe01b78c124..89db089f5a12 100644
--- a/arch/xtensa/boot/boot-elf/Makefile
+++ b/arch/xtensa/boot/boot-elf/Makefile
@@ -12,6 +12,7 @@ endif
12 12
13export OBJCOPY_ARGS 13export OBJCOPY_ARGS
14export CPPFLAGS_boot.lds += -P -C 14export CPPFLAGS_boot.lds += -P -C
15export KBUILD_AFLAGS += -mtext-section-literals
15 16
16boot-y := bootstrap.o 17boot-y := bootstrap.o
17 18
diff --git a/arch/xtensa/boot/boot-elf/boot.lds.S b/arch/xtensa/boot/boot-elf/boot.lds.S
index 7b646e0a6486..932b58ef33d4 100644
--- a/arch/xtensa/boot/boot-elf/boot.lds.S
+++ b/arch/xtensa/boot/boot-elf/boot.lds.S
@@ -1,41 +1,29 @@
1#include <variant/core.h> 1/*
2 * linux/arch/xtensa/boot/boot-elf/boot.lds.S
3 *
4 * Copyright (C) 2008 - 2013 by Tensilica Inc.
5 *
6 * Chris Zankel <chris@zankel.net>
7 * Marc Gauthier <marc@tensilica.com
8 * Pete Delaney <piet@tensilica.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <asm/vectors.h>
2OUTPUT_ARCH(xtensa) 16OUTPUT_ARCH(xtensa)
3ENTRY(_ResetVector) 17ENTRY(_ResetVector)
4 18
5SECTIONS 19SECTIONS
6{ 20{
7 .start 0xD0000000 : { *(.start) } 21 .ResetVector.text XCHAL_RESET_VECTOR_VADDR :
8
9 .text 0xD0000000:
10 {
11 __reloc_start = . ;
12 _text_start = . ;
13 *(.literal .text.literal .text)
14 _text_end = . ;
15 }
16
17 .rodata ALIGN(0x04):
18 {
19 *(.rodata)
20 *(.rodata1)
21 }
22
23 .data ALIGN(0x04):
24 { 22 {
25 *(.data) 23 *(.ResetVector.text)
26 *(.data1)
27 *(.sdata)
28 *(.sdata2)
29 *(.got.plt)
30 *(.got)
31 *(.dynamic)
32 } 24 }
33 25
34 __reloc_end = . ; 26 .image KERNELOFFSET: AT (LOAD_MEMORY_ADDRESS)
35
36 . = ALIGN(0x10);
37 __image_load = . ;
38 .image 0xd0001000:
39 { 27 {
40 _image_start = .; 28 _image_start = .;
41 *(image) 29 *(image)
@@ -43,7 +31,6 @@ SECTIONS
43 _image_end = . ; 31 _image_end = . ;
44 } 32 }
45 33
46
47 .bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3): 34 .bss ((LOADADDR(.image) + SIZEOF(.image) + 3) & ~ 3):
48 { 35 {
49 __bss_start = .; 36 __bss_start = .;
@@ -53,14 +40,15 @@ SECTIONS
53 *(.bss) 40 *(.bss)
54 __bss_end = .; 41 __bss_end = .;
55 } 42 }
56 _end = .;
57 _param_start = .;
58 43
59 .ResetVector.text XCHAL_RESET_VECTOR_VADDR : 44 /*
45 * This is a remapped copy of the Reset Vector Code.
46 * It keeps gdb in sync with the PC after switching
47 * to the temporary mapping used while setting up
48 * the V2 MMU mappings for Linux.
49 */
50 .ResetVector.remapped_text 0x46000000 (INFO):
60 { 51 {
61 *(.ResetVector.text) 52 *(.ResetVector.remapped_text)
62 } 53 }
63
64
65 PROVIDE (end = .);
66} 54}
diff --git a/arch/xtensa/boot/boot-elf/bootstrap.S b/arch/xtensa/boot/boot-elf/bootstrap.S
index 464298bc348b..1388a499753b 100644
--- a/arch/xtensa/boot/boot-elf/bootstrap.S
+++ b/arch/xtensa/boot/boot-elf/bootstrap.S
@@ -1,18 +1,77 @@
1/*
2 * arch/xtensa/boot/boot-elf/bootstrap.S
3 *
4 * Low-level exception handling
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2004 - 2013 by Tensilica Inc.
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Marc Gauthier <marc@tensilica.com>
14 * Piet Delaney <piet@tensilica.com>
15 */
1 16
2#include <asm/bootparam.h> 17#include <asm/bootparam.h>
18#include <asm/processor.h>
19#include <asm/pgtable.h>
20#include <asm/page.h>
21#include <asm/cacheasm.h>
22#include <asm/initialize_mmu.h>
23#include <linux/linkage.h>
3 24
4 25 .section .ResetVector.text, "ax"
5/* ResetVector
6 */
7 .section .ResetVector.text, "ax"
8 .global _ResetVector 26 .global _ResetVector
27 .global reset
28
9_ResetVector: 29_ResetVector:
10 _j reset 30 _j _SetupMMU
31
32 .begin no-absolute-literals
33 .literal_position
34
11 .align 4 35 .align 4
12RomInitAddr: 36RomInitAddr:
13 .word 0xd0001000 37#if defined(CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) && \
38 XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
39 .word 0x00003000
40#else
41 .word 0xd0003000
42#endif
14RomBootParam: 43RomBootParam:
15 .word _bootparam 44 .word _bootparam
45_bootparam:
46 .short BP_TAG_FIRST
47 .short 4
48 .long BP_VERSION
49 .short BP_TAG_LAST
50 .short 0
51 .long 0
52
53 .align 4
54_SetupMMU:
55 movi a0, 0
56 wsr a0, windowbase
57 rsync
58 movi a0, 1
59 wsr a0, windowstart
60 rsync
61 movi a0, 0x1F
62 wsr a0, ps
63 rsync
64
65 Offset = _SetupMMU - _ResetVector
66
67#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
68 initialize_mmu
69#endif
70
71 .end no-absolute-literals
72
73 rsil a0, XCHAL_DEBUGLEVEL-1
74 rsync
16reset: 75reset:
17 l32r a0, RomInitAddr 76 l32r a0, RomInitAddr
18 l32r a2, RomBootParam 77 l32r a2, RomBootParam
@@ -21,13 +80,25 @@ reset:
21 jx a0 80 jx a0
22 81
23 .align 4 82 .align 4
24 .section .bootstrap.data, "aw"
25 83
26 .globl _bootparam 84 .section .ResetVector.remapped_text, "x"
27_bootparam: 85 .global _RemappedResetVector
28 .short BP_TAG_FIRST 86
29 .short 4 87 /* Do org before literals */
30 .long BP_VERSION 88 .org 0
31 .short BP_TAG_LAST 89
32 .short 0 90_RemappedResetVector:
33 .long 0 91 .begin no-absolute-literals
92 .literal_position
93
94 _j _RemappedSetupMMU
95
96 /* Position Remapped code at the same location as the original code */
97 . = _RemappedResetVector + Offset
98
99_RemappedSetupMMU:
100#ifndef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
101 initialize_mmu
102#endif
103
104 .end no-absolute-literals
diff --git a/arch/xtensa/boot/boot-redboot/boot.ld b/arch/xtensa/boot/boot-redboot/boot.ld
index 5bbcaf9e830d..b0b9e95b58bd 100644
--- a/arch/xtensa/boot/boot-redboot/boot.ld
+++ b/arch/xtensa/boot/boot-redboot/boot.ld
@@ -33,7 +33,7 @@ SECTIONS
33 33
34 . = ALIGN(0x10); 34 . = ALIGN(0x10);
35 __image_load = . ; 35 __image_load = . ;
36 .image 0xd0001000: AT(__image_load) 36 .image 0xd0003000: AT(__image_load)
37 { 37 {
38 _image_start = .; 38 _image_start = .;
39 *(image) 39 *(image)
diff --git a/arch/xtensa/boot/boot-uboot/Makefile b/arch/xtensa/boot/boot-uboot/Makefile
index bfbf8af582f1..545759819ef9 100644
--- a/arch/xtensa/boot/boot-uboot/Makefile
+++ b/arch/xtensa/boot/boot-uboot/Makefile
@@ -4,7 +4,11 @@
4# for more details. 4# for more details.
5# 5#
6 6
7UIMAGE_LOADADDR = 0xd0001000 7ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
8UIMAGE_LOADADDR = 0x00003000
9else
10UIMAGE_LOADADDR = 0xd0003000
11endif
8UIMAGE_COMPRESSION = gzip 12UIMAGE_COMPRESSION = gzip
9 13
10$(obj)/../uImage: vmlinux.bin.gz FORCE 14$(obj)/../uImage: vmlinux.bin.gz FORCE
diff --git a/arch/xtensa/include/asm/Kbuild b/arch/xtensa/include/asm/Kbuild
index 095f0a2244f7..1b982641ec35 100644
--- a/arch/xtensa/include/asm/Kbuild
+++ b/arch/xtensa/include/asm/Kbuild
@@ -15,6 +15,7 @@ generic-y += irq_regs.h
15generic-y += kdebug.h 15generic-y += kdebug.h
16generic-y += kmap_types.h 16generic-y += kmap_types.h
17generic-y += kvm_para.h 17generic-y += kvm_para.h
18generic-y += linkage.h
18generic-y += local.h 19generic-y += local.h
19generic-y += local64.h 20generic-y += local64.h
20generic-y += percpu.h 21generic-y += percpu.h
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
index 40a8c178f10d..36dc7a684397 100644
--- a/arch/xtensa/include/asm/ftrace.h
+++ b/arch/xtensa/include/asm/ftrace.h
@@ -1 +1,33 @@
1/* empty */ 1/*
2 * arch/xtensa/include/asm/ftrace.h
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) 2013 Tensilica Inc.
9 */
10#ifndef _XTENSA_FTRACE_H
11#define _XTENSA_FTRACE_H
12
13#include <asm/processor.h>
14
15#define HAVE_ARCH_CALLER_ADDR
16#define CALLER_ADDR0 ({ unsigned long a0, a1; \
17 __asm__ __volatile__ ( \
18 "mov %0, a0\n" \
19 "mov %1, a1\n" \
20 : "=r"(a0), "=r"(a1) : : ); \
21 MAKE_PC_FROM_RA(a0, a1); })
22#ifdef CONFIG_FRAME_POINTER
23extern unsigned long return_address(unsigned level);
24#define CALLER_ADDR1 return_address(1)
25#define CALLER_ADDR2 return_address(2)
26#define CALLER_ADDR3 return_address(3)
27#else
28#define CALLER_ADDR1 (0)
29#define CALLER_ADDR2 (0)
30#define CALLER_ADDR3 (0)
31#endif
32
33#endif /* _XTENSA_FTRACE_H */
diff --git a/arch/xtensa/include/asm/initialize_mmu.h b/arch/xtensa/include/asm/initialize_mmu.h
index e1f8ba4061ed..722553f17db3 100644
--- a/arch/xtensa/include/asm/initialize_mmu.h
+++ b/arch/xtensa/include/asm/initialize_mmu.h
@@ -23,6 +23,9 @@
23#ifndef _XTENSA_INITIALIZE_MMU_H 23#ifndef _XTENSA_INITIALIZE_MMU_H
24#define _XTENSA_INITIALIZE_MMU_H 24#define _XTENSA_INITIALIZE_MMU_H
25 25
26#include <asm/pgtable.h>
27#include <asm/vectors.h>
28
26#ifdef __ASSEMBLY__ 29#ifdef __ASSEMBLY__
27 30
28#define XTENSA_HWVERSION_RC_2009_0 230000 31#define XTENSA_HWVERSION_RC_2009_0 230000
@@ -48,6 +51,110 @@
48 * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) 51 * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)
49 */ 52 */
50 53
54#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
55/*
56 * Have MMU v3
57 */
58
59#if !XCHAL_HAVE_VECBASE
60# error "MMU v3 requires reloc vectors"
61#endif
62
63 movi a1, 0
64 _call0 1f
65 _j 2f
66
67 .align 4
681: movi a2, 0x10000000
69 movi a3, 0x18000000
70 add a2, a2, a0
719: bgeu a2, a3, 9b /* PC is out of the expected range */
72
73 /* Step 1: invalidate mapping at 0x40000000..0x5FFFFFFF. */
74
75 movi a2, 0x40000006
76 idtlb a2
77 iitlb a2
78 isync
79
80 /* Step 2: map 0x40000000..0x47FFFFFF to paddr containing this code
81 * and jump to the new mapping.
82 */
83#define CA_BYPASS (_PAGE_CA_BYPASS | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
84#define CA_WRITEBACK (_PAGE_CA_WB | _PAGE_HW_WRITE | _PAGE_HW_EXEC)
85
86 srli a3, a0, 27
87 slli a3, a3, 27
88 addi a3, a3, CA_BYPASS
89 addi a7, a2, -1
90 wdtlb a3, a7
91 witlb a3, a7
92 isync
93
94 slli a4, a0, 5
95 srli a4, a4, 5
96 addi a5, a2, -6
97 add a4, a4, a5
98 jx a4
99
100 /* Step 3: unmap everything other than current area.
101 * Start at 0x60000000, wrap around, and end with 0x20000000
102 */
1032: movi a4, 0x20000000
104 add a5, a2, a4
1053: idtlb a5
106 iitlb a5
107 add a5, a5, a4
108 bne a5, a2, 3b
109
110 /* Step 4: Setup MMU with the old V2 mappings. */
111 movi a6, 0x01000000
112 wsr a6, ITLBCFG
113 wsr a6, DTLBCFG
114 isync
115
116 movi a5, 0xd0000005
117 movi a4, CA_WRITEBACK
118 wdtlb a4, a5
119 witlb a4, a5
120
121 movi a5, 0xd8000005
122 movi a4, CA_BYPASS
123 wdtlb a4, a5
124 witlb a4, a5
125
126 movi a5, 0xe0000006
127 movi a4, 0xf0000000 + CA_WRITEBACK
128 wdtlb a4, a5
129 witlb a4, a5
130
131 movi a5, 0xf0000006
132 movi a4, 0xf0000000 + CA_BYPASS
133 wdtlb a4, a5
134 witlb a4, a5
135
136 isync
137
138 /* Jump to self, using MMU v2 mappings. */
139 movi a4, 1f
140 jx a4
141
1421:
143 movi a2, VECBASE_RESET_VADDR
144 wsr a2, vecbase
145
146 /* Step 5: remove temporary mapping. */
147 idtlb a7
148 iitlb a7
149 isync
150
151 movi a0, 0
152 wsr a0, ptevaddr
153 rsync
154
155#endif /* defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU &&
156 XCHAL_HAVE_SPANNING_WAY */
157
51 .endm 158 .endm
52 159
53#endif /*__ASSEMBLY__*/ 160#endif /*__ASSEMBLY__*/
diff --git a/arch/xtensa/include/asm/irqflags.h b/arch/xtensa/include/asm/irqflags.h
index f865b1c1eae4..ea36674c6ec5 100644
--- a/arch/xtensa/include/asm/irqflags.h
+++ b/arch/xtensa/include/asm/irqflags.h
@@ -47,7 +47,10 @@ static inline void arch_local_irq_restore(unsigned long flags)
47 47
48static inline bool arch_irqs_disabled_flags(unsigned long flags) 48static inline bool arch_irqs_disabled_flags(unsigned long flags)
49{ 49{
50 return (flags & 0xf) != 0; 50#if XCHAL_EXCM_LEVEL < LOCKLEVEL || (1 << PS_EXCM_BIT) < LOCKLEVEL
51#error "XCHAL_EXCM_LEVEL and 1<<PS_EXCM_BIT must be no less than LOCKLEVEL"
52#endif
53 return (flags & (PS_INTLEVEL_MASK | (1 << PS_EXCM_BIT))) >= LOCKLEVEL;
51} 54}
52 55
53static inline bool arch_irqs_disabled(void) 56static inline bool arch_irqs_disabled(void)
diff --git a/arch/xtensa/include/asm/linkage.h b/arch/xtensa/include/asm/linkage.h
deleted file mode 100644
index bf2128a99d79..000000000000
--- a/arch/xtensa/include/asm/linkage.h
+++ /dev/null
@@ -1,16 +0,0 @@
1/*
2 * include/asm-xtensa/linkage.h
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 - 2005 Tensilica Inc.
9 */
10
11#ifndef _XTENSA_LINKAGE_H
12#define _XTENSA_LINKAGE_H
13
14/* Nothing to do here ... */
15
16#endif /* _XTENSA_LINKAGE_H */
diff --git a/arch/xtensa/include/asm/stacktrace.h b/arch/xtensa/include/asm/stacktrace.h
new file mode 100644
index 000000000000..6a05fcb0a20d
--- /dev/null
+++ b/arch/xtensa/include/asm/stacktrace.h
@@ -0,0 +1,36 @@
1/*
2 * arch/xtensa/include/asm/stacktrace.h
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#ifndef _XTENSA_STACKTRACE_H
11#define _XTENSA_STACKTRACE_H
12
13#include <linux/sched.h>
14
15struct stackframe {
16 unsigned long pc;
17 unsigned long sp;
18};
19
20static __always_inline unsigned long *stack_pointer(struct task_struct *task)
21{
22 unsigned long *sp;
23
24 if (!task || task == current)
25 __asm__ __volatile__ ("mov %0, a1\n" : "=a"(sp));
26 else
27 sp = (unsigned long *)task->thread.sp;
28
29 return sp;
30}
31
32void walk_stackframe(unsigned long *sp,
33 int (*fn)(struct stackframe *frame, void *data),
34 void *data);
35
36#endif /* _XTENSA_STACKTRACE_H */
diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h
index 9e85ce8bd8dd..3d35e5d0367e 100644
--- a/arch/xtensa/include/asm/timex.h
+++ b/arch/xtensa/include/asm/timex.h
@@ -19,13 +19,16 @@
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) <= XCHAL_EXCM_LEVEL 22#if XCHAL_NUM_TIMERS > 0 && \
23 INTLEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
23# define LINUX_TIMER 0 24# define LINUX_TIMER 0
24# define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT 25# define LINUX_TIMER_INT XCHAL_TIMER0_INTERRUPT
25#elif INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL 26#elif XCHAL_NUM_TIMERS > 1 && \
27 INTLEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
26# define LINUX_TIMER 1 28# define LINUX_TIMER 1
27# define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT 29# define LINUX_TIMER_INT XCHAL_TIMER1_INTERRUPT
28#elif INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL 30#elif XCHAL_NUM_TIMERS > 2 && \
31 INTLEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
29# define LINUX_TIMER 2 32# define LINUX_TIMER 2
30# define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT 33# define LINUX_TIMER_INT XCHAL_TIMER2_INTERRUPT
31#else 34#else
diff --git a/arch/xtensa/include/asm/traps.h b/arch/xtensa/include/asm/traps.h
index b5464ef3cf66..917488a0ab00 100644
--- a/arch/xtensa/include/asm/traps.h
+++ b/arch/xtensa/include/asm/traps.h
@@ -22,10 +22,9 @@ extern void do_unhandled(struct pt_regs *regs, unsigned long exccause);
22 22
23static inline void spill_registers(void) 23static inline void spill_registers(void)
24{ 24{
25 unsigned int a0, ps;
26 25
27 __asm__ __volatile__ ( 26 __asm__ __volatile__ (
28 "movi a14, " __stringify(PS_EXCM_BIT | LOCKLEVEL) "\n\t" 27 "movi a14, "__stringify((1 << PS_EXCM_BIT) | LOCKLEVEL)"\n\t"
29 "mov a12, a0\n\t" 28 "mov a12, a0\n\t"
30 "rsr a13, sar\n\t" 29 "rsr a13, sar\n\t"
31 "xsr a14, ps\n\t" 30 "xsr a14, ps\n\t"
@@ -35,7 +34,7 @@ static inline void spill_registers(void)
35 "mov a0, a12\n\t" 34 "mov a0, a12\n\t"
36 "wsr a13, sar\n\t" 35 "wsr a13, sar\n\t"
37 "wsr a14, ps\n\t" 36 "wsr a14, ps\n\t"
38 : : "a" (&a0), "a" (&ps) 37 : :
39#if defined(CONFIG_FRAME_POINTER) 38#if defined(CONFIG_FRAME_POINTER)
40 : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15", 39 : "a2", "a3", "a4", "a11", "a12", "a13", "a14", "a15",
41#else 40#else
diff --git a/arch/xtensa/include/asm/vectors.h b/arch/xtensa/include/asm/vectors.h
new file mode 100644
index 000000000000..c52b656d0310
--- /dev/null
+++ b/arch/xtensa/include/asm/vectors.h
@@ -0,0 +1,125 @@
1/*
2 * arch/xtensa/include/asm/xchal_vaddr_remap.h
3 *
4 * Xtensa macros for MMU V3 Support. Deals with re-mapping the Virtual
5 * Memory Addresses from "Virtual == Physical" to their prevvious V2 MMU
6 * mappings (KSEG at 0xD0000000 and KIO at 0XF0000000).
7 *
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
10 * for more details.
11 *
12 * Copyright (C) 2008 - 2012 Tensilica Inc.
13 *
14 * Pete Delaney <piet@tensilica.com>
15 * Marc Gauthier <marc@tensilica.com
16 */
17
18#ifndef _XTENSA_VECTORS_H
19#define _XTENSA_VECTORS_H
20
21#include <variant/core.h>
22
23#if defined(CONFIG_MMU)
24
25/* Will Become VECBASE */
26#define VIRTUAL_MEMORY_ADDRESS 0xD0000000
27
28/* Image Virtual Start Address */
29#define KERNELOFFSET 0xD0003000
30
31#if defined(XCHAL_HAVE_PTP_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
32 /* MMU v3 - XCHAL_HAVE_PTP_MMU == 1 */
33 #define PHYSICAL_MEMORY_ADDRESS 0x00000000
34 #define LOAD_MEMORY_ADDRESS 0x00003000
35#else
36 /* MMU V2 - XCHAL_HAVE_PTP_MMU == 0 */
37 #define PHYSICAL_MEMORY_ADDRESS 0xD0000000
38 #define LOAD_MEMORY_ADDRESS 0xD0003000
39#endif
40
41#else /* !defined(CONFIG_MMU) */
42 /* MMU Not being used - Virtual == Physical */
43
44 /* VECBASE */
45 #define VIRTUAL_MEMORY_ADDRESS 0x00002000
46
47 /* Location of the start of the kernel text, _start */
48 #define KERNELOFFSET 0x00003000
49 #define PHYSICAL_MEMORY_ADDRESS 0x00000000
50
51 /* Loaded just above possibly live vectors */
52 #define LOAD_MEMORY_ADDRESS 0x00003000
53
54#endif /* CONFIG_MMU */
55
56#define XC_VADDR(offset) (VIRTUAL_MEMORY_ADDRESS + offset)
57#define XC_PADDR(offset) (PHYSICAL_MEMORY_ADDRESS + offset)
58
59/* Used to set VECBASE register */
60#define VECBASE_RESET_VADDR VIRTUAL_MEMORY_ADDRESS
61
62#define RESET_VECTOR_VECOFS (XCHAL_RESET_VECTOR_VADDR - \
63 VECBASE_RESET_VADDR)
64#define RESET_VECTOR_VADDR XC_VADDR(RESET_VECTOR_VECOFS)
65
66#define RESET_VECTOR1_VECOFS (XCHAL_RESET_VECTOR1_VADDR - \
67 VECBASE_RESET_VADDR)
68#define RESET_VECTOR1_VADDR XC_VADDR(RESET_VECTOR1_VECOFS)
69
70#if XCHAL_HAVE_VECBASE
71
72#define USER_VECTOR_VADDR XC_VADDR(XCHAL_USER_VECOFS)
73#define KERNEL_VECTOR_VADDR XC_VADDR(XCHAL_KERNEL_VECOFS)
74#define DOUBLEEXC_VECTOR_VADDR XC_VADDR(XCHAL_DOUBLEEXC_VECOFS)
75#define WINDOW_VECTORS_VADDR XC_VADDR(XCHAL_WINDOW_OF4_VECOFS)
76#define INTLEVEL2_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL2_VECOFS)
77#define INTLEVEL3_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL3_VECOFS)
78#define INTLEVEL4_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL4_VECOFS)
79#define INTLEVEL5_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL5_VECOFS)
80#define INTLEVEL6_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL6_VECOFS)
81
82#define DEBUG_VECTOR_VADDR XC_VADDR(XCHAL_DEBUG_VECOFS)
83
84#undef XCHAL_NMI_VECTOR_VADDR
85#define XCHAL_NMI_VECTOR_VADDR XC_VADDR(XCHAL_NMI_VECOFS)
86
87#undef XCHAL_INTLEVEL7_VECTOR_VADDR
88#define XCHAL_INTLEVEL7_VECTOR_VADDR XC_VADDR(XCHAL_INTLEVEL7_VECOFS)
89
90/*
91 * These XCHAL_* #defines from varian/core.h
92 * are not valid to use with V3 MMU. Non-XCHAL
93 * constants are defined above and should be used.
94 */
95#undef XCHAL_VECBASE_RESET_VADDR
96#undef XCHAL_RESET_VECTOR0_VADDR
97#undef XCHAL_USER_VECTOR_VADDR
98#undef XCHAL_KERNEL_VECTOR_VADDR
99#undef XCHAL_DOUBLEEXC_VECTOR_VADDR
100#undef XCHAL_WINDOW_VECTORS_VADDR
101#undef XCHAL_INTLEVEL2_VECTOR_VADDR
102#undef XCHAL_INTLEVEL3_VECTOR_VADDR
103#undef XCHAL_INTLEVEL4_VECTOR_VADDR
104#undef XCHAL_INTLEVEL5_VECTOR_VADDR
105#undef XCHAL_INTLEVEL6_VECTOR_VADDR
106#undef XCHAL_DEBUG_VECTOR_VADDR
107#undef XCHAL_NMI_VECTOR_VADDR
108#undef XCHAL_INTLEVEL7_VECTOR_VADDR
109
110#else
111
112#define USER_VECTOR_VADDR XCHAL_USER_VECTOR_VADDR
113#define KERNEL_VECTOR_VADDR XCHAL_KERNEL_VECTOR_VADDR
114#define DOUBLEEXC_VECTOR_VADDR XCHAL_DOUBLEEXC_VECTOR_VADDR
115#define WINDOW_VECTORS_VADDR XCHAL_WINDOW_VECTORS_VADDR
116#define INTLEVEL2_VECTOR_VADDR XCHAL_INTLEVEL2_VECTOR_VADDR
117#define INTLEVEL3_VECTOR_VADDR XCHAL_INTLEVEL3_VECTOR_VADDR
118#define INTLEVEL4_VECTOR_VADDR XCHAL_INTLEVEL4_VECTOR_VADDR
119#define INTLEVEL5_VECTOR_VADDR XCHAL_INTLEVEL5_VECTOR_VADDR
120#define INTLEVEL6_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR
121#define DEBUG_VECTOR_VADDR XCHAL_DEBUG_VECTOR_VADDR
122
123#endif
124
125#endif /* _XTENSA_VECTORS_H */
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);
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c
index 0f77f9d3bb8b..a1077570e383 100644
--- a/arch/xtensa/mm/mmu.c
+++ b/arch/xtensa/mm/mmu.c
@@ -24,15 +24,19 @@ void __init paging_init(void)
24 */ 24 */
25void __init init_mmu(void) 25void __init init_mmu(void)
26{ 26{
27 /* Writing zeros to the <t>TLBCFG special registers ensure 27#if !(XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)
28 * that valid values exist in the register. For existing 28 /*
29 * PGSZID<w> fields, zero selects the first element of the 29 * Writing zeros to the instruction and data TLBCFG special
30 * page-size array. For nonexistent PGSZID<w> fields, zero is 30 * registers ensure that valid values exist in the register.
31 * the best value to write. Also, when changing PGSZID<w> 31 *
32 * For existing PGSZID<w> fields, zero selects the first element
33 * of the page-size array. For nonexistent PGSZID<w> fields,
34 * zero is the best value to write. Also, when changing PGSZID<w>
32 * fields, the corresponding TLB must be flushed. 35 * fields, the corresponding TLB must be flushed.
33 */ 36 */
34 set_itlbcfg_register(0); 37 set_itlbcfg_register(0);
35 set_dtlbcfg_register(0); 38 set_dtlbcfg_register(0);
39#endif
36 flush_tlb_all(); 40 flush_tlb_all();
37 41
38 /* Set rasid register to a known value. */ 42 /* Set rasid register to a known value. */
diff --git a/arch/xtensa/oprofile/backtrace.c b/arch/xtensa/oprofile/backtrace.c
index 66f32ee2c982..5f03a593d84f 100644
--- a/arch/xtensa/oprofile/backtrace.c
+++ b/arch/xtensa/oprofile/backtrace.c
@@ -132,9 +132,7 @@ static void xtensa_backtrace_kernel(struct pt_regs *regs, unsigned int depth)
132 pc = MAKE_PC_FROM_RA(a0, pc); 132 pc = MAKE_PC_FROM_RA(a0, pc);
133 133
134 /* Add the PC to the trace. */ 134 /* Add the PC to the trace. */
135 if (kernel_text_address(pc)) 135 oprofile_add_trace(pc);
136 oprofile_add_trace(pc);
137
138 if (pc == (unsigned long) &common_exception_return) { 136 if (pc == (unsigned long) &common_exception_return) {
139 regs = (struct pt_regs *)a1; 137 regs = (struct pt_regs *)a1;
140 if (user_mode(regs)) { 138 if (user_mode(regs)) {
diff --git a/arch/xtensa/platforms/iss/console.c b/arch/xtensa/platforms/iss/console.c
index da9866f7fecf..70cb408bc20d 100644
--- a/arch/xtensa/platforms/iss/console.c
+++ b/arch/xtensa/platforms/iss/console.c
@@ -56,13 +56,13 @@ static void rs_poll(unsigned long);
56static int rs_open(struct tty_struct *tty, struct file * filp) 56static int rs_open(struct tty_struct *tty, struct file * filp)
57{ 57{
58 tty->port = &serial_port; 58 tty->port = &serial_port;
59 spin_lock(&timer_lock); 59 spin_lock_bh(&timer_lock);
60 if (tty->count == 1) { 60 if (tty->count == 1) {
61 setup_timer(&serial_timer, rs_poll, 61 setup_timer(&serial_timer, rs_poll,
62 (unsigned long)&serial_port); 62 (unsigned long)&serial_port);
63 mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE); 63 mod_timer(&serial_timer, jiffies + SERIAL_TIMER_VALUE);
64 } 64 }
65 spin_unlock(&timer_lock); 65 spin_unlock_bh(&timer_lock);
66 66
67 return 0; 67 return 0;
68} 68}
@@ -99,14 +99,13 @@ static int rs_write(struct tty_struct * tty,
99static void rs_poll(unsigned long priv) 99static void rs_poll(unsigned long priv)
100{ 100{
101 struct tty_port *port = (struct tty_port *)priv; 101 struct tty_port *port = (struct tty_port *)priv;
102 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
103 int i = 0; 102 int i = 0;
104 unsigned char c; 103 unsigned char c;
105 104
106 spin_lock(&timer_lock); 105 spin_lock(&timer_lock);
107 106
108 while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ 107 while (simc_poll(0)) {
109 __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); 108 simc_read(0, &c, 1);
110 tty_insert_flip_char(port, c, TTY_NORMAL); 109 tty_insert_flip_char(port, c, TTY_NORMAL);
111 i++; 110 i++;
112 } 111 }
@@ -244,8 +243,7 @@ static void iss_console_write(struct console *co, const char *s, unsigned count)
244 int len = strlen(s); 243 int len = strlen(s);
245 244
246 if (s != 0 && *s != 0) 245 if (s != 0 && *s != 0)
247 __simc (SYS_write, 1, (unsigned long)s, 246 simc_write(1, s, count < len ? count : len);
248 count < len ? count : len,0,0);
249} 247}
250 248
251static struct tty_driver* iss_console_device(struct console *c, int *index) 249static struct tty_driver* iss_console_device(struct console *c, int *index)
diff --git a/arch/xtensa/platforms/iss/include/platform/simcall.h b/arch/xtensa/platforms/iss/include/platform/simcall.h
index b5a4edf02d76..12b15ad1e586 100644
--- a/arch/xtensa/platforms/iss/include/platform/simcall.h
+++ b/arch/xtensa/platforms/iss/include/platform/simcall.h
@@ -59,56 +59,58 @@
59 59
60static int errno; 60static int errno;
61 61
62static inline int __simc(int a, int b, int c, int d, int e, int f) 62static inline int __simc(int a, int b, int c, int d)
63{ 63{
64 int ret; 64 int ret;
65 register int a1 asm("a2") = a; 65 register int a1 asm("a2") = a;
66 register int b1 asm("a3") = b; 66 register int b1 asm("a3") = b;
67 register int c1 asm("a4") = c; 67 register int c1 asm("a4") = c;
68 register int d1 asm("a5") = d; 68 register int d1 asm("a5") = d;
69 register int e1 asm("a6") = e;
70 register int f1 asm("a7") = f;
71 __asm__ __volatile__ ( 69 __asm__ __volatile__ (
72 "simcall\n" 70 "simcall\n"
73 "mov %0, a2\n" 71 "mov %0, a2\n"
74 "mov %1, a3\n" 72 "mov %1, a3\n"
75 : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) 73 : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1)
76 : "r"(c1), "r"(d1), "r"(e1), "r"(f1) 74 : "r"(c1), "r"(d1)
77 : "memory"); 75 : "memory");
78 return ret; 76 return ret;
79} 77}
80 78
81static inline int simc_open(const char *file, int flags, int mode) 79static inline int simc_open(const char *file, int flags, int mode)
82{ 80{
83 return __simc(SYS_open, (int) file, flags, mode, 0, 0); 81 return __simc(SYS_open, (int) file, flags, mode);
84} 82}
85 83
86static inline int simc_close(int fd) 84static inline int simc_close(int fd)
87{ 85{
88 return __simc(SYS_close, fd, 0, 0, 0, 0); 86 return __simc(SYS_close, fd, 0, 0);
89} 87}
90 88
91static inline int simc_ioctl(int fd, int request, void *arg) 89static inline int simc_ioctl(int fd, int request, void *arg)
92{ 90{
93 return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); 91 return __simc(SYS_ioctl, fd, request, (int) arg);
94} 92}
95 93
96static inline int simc_read(int fd, void *buf, size_t count) 94static inline int simc_read(int fd, void *buf, size_t count)
97{ 95{
98 return __simc(SYS_read, fd, (int) buf, count, 0, 0); 96 return __simc(SYS_read, fd, (int) buf, count);
99} 97}
100 98
101static inline int simc_write(int fd, const void *buf, size_t count) 99static inline int simc_write(int fd, const void *buf, size_t count)
102{ 100{
103 return __simc(SYS_write, fd, (int) buf, count, 0, 0); 101 return __simc(SYS_write, fd, (int) buf, count);
104} 102}
105 103
106static inline int simc_poll(int fd) 104static inline int simc_poll(int fd)
107{ 105{
108 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; 106 struct timeval tv = { .tv_sec = 0, .tv_usec = 0 };
109 107
110 return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, 108 return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv);
111 0, 0); 109}
110
111static inline int simc_lseek(int fd, uint32_t off, int whence)
112{
113 return __simc(SYS_lseek, fd, off, whence);
112} 114}
113 115
114#endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */ 116#endif /* _XTENSA_PLATFORM_ISS_SIMCALL_H */
diff --git a/arch/xtensa/platforms/iss/setup.c b/arch/xtensa/platforms/iss/setup.c
index e1700102f35e..da7d18240866 100644
--- a/arch/xtensa/platforms/iss/setup.c
+++ b/arch/xtensa/platforms/iss/setup.c
@@ -38,12 +38,6 @@ void __init platform_init(bp_tag_t* bootparam)
38 38
39} 39}
40 40
41#ifdef CONFIG_PCI
42void platform_pcibios_init(void)
43{
44}
45#endif
46
47void platform_halt(void) 41void platform_halt(void)
48{ 42{
49 pr_info(" ** Called platform_halt() **\n"); 43 pr_info(" ** Called platform_halt() **\n");
@@ -64,7 +58,9 @@ void platform_restart(void)
64 "wsr a2, icountlevel\n\t" 58 "wsr a2, icountlevel\n\t"
65 "movi a2, 0\n\t" 59 "movi a2, 0\n\t"
66 "wsr a2, icount\n\t" 60 "wsr a2, icount\n\t"
61#if XCHAL_NUM_IBREAK > 0
67 "wsr a2, ibreakenable\n\t" 62 "wsr a2, ibreakenable\n\t"
63#endif
68 "wsr a2, lcount\n\t" 64 "wsr a2, lcount\n\t"
69 "movi a2, 0x1f\n\t" 65 "movi a2, 0x1f\n\t"
70 "wsr a2, ps\n\t" 66 "wsr a2, ps\n\t"
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index fc3c91fd20f7..c0edb35424ce 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -85,7 +85,7 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
85 while (nbytes > 0) { 85 while (nbytes > 0) {
86 unsigned long io; 86 unsigned long io;
87 87
88 __simc(SYS_lseek, dev->fd, offset, SEEK_SET, 0, 0); 88 simc_lseek(dev->fd, offset, SEEK_SET);
89 if (write) 89 if (write)
90 io = simc_write(dev->fd, buffer, nbytes); 90 io = simc_write(dev->fd, buffer, nbytes);
91 else 91 else
@@ -176,7 +176,7 @@ static int simdisk_attach(struct simdisk *dev, const char *filename)
176 err = -ENODEV; 176 err = -ENODEV;
177 goto out; 177 goto out;
178 } 178 }
179 dev->size = __simc(SYS_lseek, dev->fd, 0, SEEK_END, 0, 0); 179 dev->size = simc_lseek(dev->fd, 0, SEEK_END);
180 set_capacity(dev->gd, dev->size >> SECTOR_SHIFT); 180 set_capacity(dev->gd, dev->size >> SECTOR_SHIFT);
181 dev->filename = filename; 181 dev->filename = filename;
182 pr_info("SIMDISK: %s=%s\n", dev->gd->disk_name, dev->filename); 182 pr_info("SIMDISK: %s=%s\n", dev->gd->disk_name, dev->filename);
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c
index c7d90f17886e..f9bc87966290 100644
--- a/arch/xtensa/platforms/xt2000/setup.c
+++ b/arch/xtensa/platforms/xt2000/setup.c
@@ -69,7 +69,9 @@ void platform_restart(void)
69 "wsr a2, icountlevel\n\t" 69 "wsr a2, icountlevel\n\t"
70 "movi a2, 0\n\t" 70 "movi a2, 0\n\t"
71 "wsr a2, icount\n\t" 71 "wsr a2, icount\n\t"
72#if XCHAL_NUM_IBREAK > 0
72 "wsr a2, ibreakenable\n\t" 73 "wsr a2, ibreakenable\n\t"
74#endif
73 "wsr a2, lcount\n\t" 75 "wsr a2, lcount\n\t"
74 "movi a2, 0x1f\n\t" 76 "movi a2, 0x1f\n\t"
75 "wsr a2, ps\n\t" 77 "wsr a2, ps\n\t"
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
index 9d888a2a5755..96ef8eeb064e 100644
--- a/arch/xtensa/platforms/xtfpga/setup.c
+++ b/arch/xtensa/platforms/xtfpga/setup.c
@@ -60,7 +60,9 @@ void platform_restart(void)
60 "wsr a2, icountlevel\n\t" 60 "wsr a2, icountlevel\n\t"
61 "movi a2, 0\n\t" 61 "movi a2, 0\n\t"
62 "wsr a2, icount\n\t" 62 "wsr a2, icount\n\t"
63#if XCHAL_NUM_IBREAK > 0
63 "wsr a2, ibreakenable\n\t" 64 "wsr a2, ibreakenable\n\t"
65#endif
64 "wsr a2, lcount\n\t" 66 "wsr a2, lcount\n\t"
65 "movi a2, 0x1f\n\t" 67 "movi a2, 0x1f\n\t"
66 "wsr a2, ps\n\t" 68 "wsr a2, ps\n\t"