diff options
-rw-r--r-- | arch/xtensa/Kconfig | 29 | ||||
-rw-r--r-- | arch/xtensa/boot/boot-elf/Makefile | 1 | ||||
-rw-r--r-- | arch/xtensa/boot/boot-elf/boot.lds.S | 64 | ||||
-rw-r--r-- | arch/xtensa/boot/boot-elf/bootstrap.S | 101 | ||||
-rw-r--r-- | arch/xtensa/boot/boot-uboot/Makefile | 6 | ||||
-rw-r--r-- | arch/xtensa/include/asm/initialize_mmu.h | 107 | ||||
-rw-r--r-- | arch/xtensa/include/asm/vectors.h | 125 | ||||
-rw-r--r-- | arch/xtensa/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/xtensa/kernel/head.S | 37 | ||||
-rw-r--r-- | arch/xtensa/kernel/vectors.S | 3 | ||||
-rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 48 | ||||
-rw-r--r-- | arch/xtensa/mm/mmu.c | 14 |
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 | ||
106 | config 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 | |||
106 | endmenu | 135 | endmenu |
107 | 136 | ||
108 | config XTENSA_CALIBRATE_CCOUNT | 137 | config 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 | ||
13 | export OBJCOPY_ARGS | 13 | export OBJCOPY_ARGS |
14 | export CPPFLAGS_boot.lds += -P -C | 14 | export CPPFLAGS_boot.lds += -P -C |
15 | export KBUILD_AFLAGS += -mtext-section-literals | ||
15 | 16 | ||
16 | boot-y := bootstrap.o | 17 | boot-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> | ||
2 | OUTPUT_ARCH(xtensa) | 16 | OUTPUT_ARCH(xtensa) |
3 | ENTRY(_ResetVector) | 17 | ENTRY(_ResetVector) |
4 | 18 | ||
5 | SECTIONS | 19 | SECTIONS |
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 |
12 | RomInitAddr: | 36 | RomInitAddr: |
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 | ||
14 | RomBootParam: | 43 | RomBootParam: |
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 | ||
16 | reset: | 75 | reset: |
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 | ||
7 | UIMAGE_LOADADDR = 0xd0001000 | 7 | ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX |
8 | UIMAGE_LOADADDR = 0x00003000 | ||
9 | else | ||
10 | UIMAGE_LOADADDR = 0xd0003000 | ||
11 | endif | ||
8 | UIMAGE_COMPRESSION = gzip | 12 | UIMAGE_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 | ||
68 | 1: movi a2, 0x10000000 | ||
69 | movi a3, 0x18000000 | ||
70 | add a2, a2, a0 | ||
71 | 9: 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 | */ | ||
103 | 2: movi a4, 0x20000000 | ||
104 | add a5, a2, a4 | ||
105 | 3: 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 | |||
142 | 1: | ||
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 | |||
12 | obj-$(CONFIG_PCI) += pci.o | 12 | obj-$(CONFIG_PCI) += pci.o |
13 | obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o | 13 | obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o |
14 | 14 | ||
15 | AFLAGS_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 | |||
51 | ENTRY(_start) | 53 | ENTRY(_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 |
55 | 1: .word _startup | 65 | .global _SetupMMU |
56 | 2: 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 | ||
59 | ENDPROC(_start) | 77 | ENDPROC(_start) |
60 | 78 | ||
61 | .section .init.text, "ax" | 79 | __INIT |
80 | .literal_position | ||
62 | 81 | ||
63 | ENTRY(_startup) | 82 | ENTRY(_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> |
23 | OUTPUT_ARCH(xtensa) | 24 | OUTPUT_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 | */ |
25 | void __init init_mmu(void) | 25 | void __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. */ |