aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2012-12-03 06:01:43 -0500
committerChris Zankel <chris@zankel.net>2013-05-09 04:07:09 -0400
commite85e335f8ff615f74e29e09cc2599f095600114b (patch)
tree8f09bbab5ca6a37f027fef17bf1de523ab574f10 /arch/xtensa
parentd83ff0bb828854d9e7172ac5d8d007a7466934c9 (diff)
xtensa: add MMU v3 support
MMUv3 comes out of reset with identity vaddr -> paddr mapping in the TLB way 6: Way 6 (512 MB) Vaddr Paddr ASID Attr RWX Cache ---------- ---------- ---- ---- --- ------- 0x00000000 0x00000000 0x01 0x03 RWX Bypass 0x20000000 0x20000000 0x01 0x03 RWX Bypass 0x40000000 0x40000000 0x01 0x03 RWX Bypass 0x60000000 0x60000000 0x01 0x03 RWX Bypass 0x80000000 0x80000000 0x01 0x03 RWX Bypass 0xa0000000 0xa0000000 0x01 0x03 RWX Bypass 0xc0000000 0xc0000000 0x01 0x03 RWX Bypass 0xe0000000 0xe0000000 0x01 0x03 RWX Bypass This patch adds remapping code at the reset vector or at the kernel _start (depending on CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX) that reconfigures MMUv3 as MMUv2: Way 5 (128 MB) Vaddr Paddr ASID Attr RWX Cache ---------- ---------- ---- ---- --- ------- 0xd0000000 0x00000000 0x01 0x07 RWX WB 0xd8000000 0x00000000 0x01 0x03 RWX Bypass Way 6 (256 MB) Vaddr Paddr ASID Attr RWX Cache ---------- ---------- ---- ---- --- ------- 0xe0000000 0xf0000000 0x01 0x07 RWX WB 0xf0000000 0xf0000000 0x01 0x03 RWX Bypass 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/Kconfig29
-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-uboot/Makefile6
-rw-r--r--arch/xtensa/include/asm/initialize_mmu.h107
-rw-r--r--arch/xtensa/include/asm/vectors.h125
-rw-r--r--arch/xtensa/kernel/Makefile2
-rw-r--r--arch/xtensa/kernel/head.S37
-rw-r--r--arch/xtensa/kernel/vectors.S3
-rw-r--r--arch/xtensa/kernel/vmlinux.lds.S48
-rw-r--r--arch/xtensa/mm/mmu.c14
12 files changed, 451 insertions, 86 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index b09de49dbec5..213ac3d9f950 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -103,6 +103,35 @@ config MATH_EMULATION
103 help 103 help
104 Can we use information of configuration file? 104 Can we use information of configuration file?
105 105
106config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
107 bool "Initialize Xtensa MMU inside the Linux kernel code"
108 default y
109 help
110 Earlier version initialized the MMU in the exception vector
111 before jumping to _startup in head.S and had an advantage that
112 it was possible to place a software breakpoint at 'reset' and
113 then enter your normal kernel breakpoints once the MMU was mapped
114 to the kernel mappings (0XC0000000).
115
116 This unfortunately doesn't work for U-Boot and likley also wont
117 work for using KEXEC to have a hot kernel ready for doing a
118 KDUMP.
119
120 So now the MMU is initialized in head.S but it's necessary to
121 use hardware breakpoints (gdb 'hbreak' cmd) to break at _startup.
122 xt-gdb can't place a Software Breakpoint in the 0XD region prior
123 to mapping the MMU and after mapping even if the area of low memory
124 was mapped gdb wouldn't remove the breakpoint on hitting it as the
125 PC wouldn't match. Since Hardware Breakpoints are recommended for
126 Linux configurations it seems reasonable to just assume they exist
127 and leave this older mechanism for unfortunate souls that choose
128 not to follow Tensilica's recommendation.
129
130 Selecting this will cause U-Boot to set the KERNEL Load and Entry
131 address at 0x00003000 instead of the mapped std of 0xD0003000.
132
133 If in doubt, say Y.
134
106endmenu 135endmenu
107 136
108config XTENSA_CALIBRATE_CCOUNT 137config XTENSA_CALIBRATE_CCOUNT
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-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/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/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..c433a56fbff9 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -12,6 +12,8 @@ obj-$(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/head.S b/arch/xtensa/kernel/head.S
index 4566683abc8d..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
@@ -158,8 +173,6 @@ ENTRY(_startup)
158 173
159 isync 174 isync
160 175
161 initialize_mmu
162
163 /* Unpack data sections 176 /* Unpack data sections
164 * 177 *
165 * The linker script used to build the Linux kernel image 178 * The linker script used to build the Linux kernel image
@@ -207,6 +220,10 @@ ENTRY(_startup)
207 220
208 ___flush_dcache_all a2 a3 221 ___flush_dcache_all a2 a3
209#endif 222#endif
223 memw
224 isync
225 ___invalidate_icache_all a2 a3
226 isync
210 227
211 /* Setup stack and enable window exceptions (keep irqs disabled) */ 228 /* Setup stack and enable window exceptions (keep irqs disabled) */
212 229
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S
index 82109b42e240..a7e1d0834c68 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
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/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. */