diff options
author | Chris Zankel <chris@zankel.net> | 2014-08-18 20:30:24 -0400 |
---|---|---|
committer | Chris Zankel <chris@zankel.net> | 2014-08-18 20:30:24 -0400 |
commit | e792290be763932d1b8cdf8a36d7015482a49d07 (patch) | |
tree | 2aec72e1556ef099ff9bd535d21d4477e1db9ddb /arch/xtensa | |
parent | 7d1311b93e58ed55f3a31cc8f94c4b8fe988a2b9 (diff) | |
parent | 9184289c979e78ce466993b53fc951633441e571 (diff) |
Merge tag 'xtensa-for-next-20140815' into for_next
Xtensa improvements for 3.17:
- support highmem on cores with aliasing data cache. Enable highmem on kc705
by default;
- simplify addition of new core variants (no need to modify Kconfig /
Makefiles);
- improve robustness of unaligned access handler and its interaction with
window overflow/underflow exception handlers;
- deprecate atomic and spill registers syscalls;
- clean up Kconfig: remove orphan MATH_EMULATION, sort 'select' statements;
- wire up renameat2 syscall.
Various fixes:
- fix address checks in dma_{alloc,free}_coherent (runtime BUG);
- fix access to THREAD_RA/THREAD_SP/THREAD_DS (debug build breakage);
- fix TLBTEMP_BASE_2 region handling in fast_second_level_miss (runtime
unrecoverable exception);
- fix a6 and a7 handling in fast_syscall_xtensa (runtime userspace register
clobbering);
- fix kernel/user jump out of fast_unaligned (potential runtime unrecoverable
exception);
- replace termios IOCTL code definitions with constants (userspace build
breakage).
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'arch/xtensa')
-rw-r--r-- | arch/xtensa/Kconfig | 92 | ||||
-rw-r--r-- | arch/xtensa/Makefile | 7 | ||||
-rw-r--r-- | arch/xtensa/boot/dts/kc705.dts | 5 | ||||
-rw-r--r-- | arch/xtensa/configs/common_defconfig | 1 | ||||
-rw-r--r-- | arch/xtensa/configs/iss_defconfig | 3 | ||||
-rw-r--r-- | arch/xtensa/configs/s6105_defconfig | 1 | ||||
-rw-r--r-- | arch/xtensa/include/asm/cacheflush.h | 2 | ||||
-rw-r--r-- | arch/xtensa/include/asm/fixmap.h | 30 | ||||
-rw-r--r-- | arch/xtensa/include/asm/highmem.h | 40 | ||||
-rw-r--r-- | arch/xtensa/include/asm/page.h | 14 | ||||
-rw-r--r-- | arch/xtensa/include/asm/pgtable.h | 7 | ||||
-rw-r--r-- | arch/xtensa/include/asm/uaccess.h | 5 | ||||
-rw-r--r-- | arch/xtensa/include/uapi/asm/ioctls.h | 19 | ||||
-rw-r--r-- | arch/xtensa/include/uapi/asm/unistd.h | 5 | ||||
-rw-r--r-- | arch/xtensa/kernel/align.S | 128 | ||||
-rw-r--r-- | arch/xtensa/kernel/entry.S | 54 | ||||
-rw-r--r-- | arch/xtensa/kernel/pci-dma.c | 12 | ||||
-rw-r--r-- | arch/xtensa/kernel/traps.c | 5 | ||||
-rw-r--r-- | arch/xtensa/kernel/vectors.S | 8 | ||||
-rw-r--r-- | arch/xtensa/kernel/vmlinux.lds.S | 4 | ||||
-rw-r--r-- | arch/xtensa/mm/cache.c | 77 | ||||
-rw-r--r-- | arch/xtensa/mm/highmem.c | 41 | ||||
-rw-r--r-- | arch/xtensa/mm/misc.S | 116 | ||||
-rw-r--r-- | arch/xtensa/mm/mmu.c | 38 |
24 files changed, 497 insertions, 217 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3a617af60d46..49c6c3d94449 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -4,24 +4,23 @@ config ZONE_DMA | |||
4 | config XTENSA | 4 | config XTENSA |
5 | def_bool y | 5 | def_bool y |
6 | select ARCH_WANT_FRAME_POINTERS | 6 | select ARCH_WANT_FRAME_POINTERS |
7 | select HAVE_IDE | ||
8 | select GENERIC_ATOMIC64 | ||
9 | select GENERIC_CLOCKEVENTS | ||
10 | select VIRT_TO_BUS | ||
11 | select GENERIC_IRQ_SHOW | ||
12 | select GENERIC_SCHED_CLOCK | ||
13 | select MODULES_USE_ELF_RELA | ||
14 | select GENERIC_PCI_IOMAP | ||
15 | select ARCH_WANT_IPC_PARSE_VERSION | 7 | select ARCH_WANT_IPC_PARSE_VERSION |
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 8 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | select BUILDTIME_EXTABLE_SORT | 9 | select BUILDTIME_EXTABLE_SORT |
18 | select CLONE_BACKWARDS | 10 | select CLONE_BACKWARDS |
19 | select IRQ_DOMAIN | 11 | select COMMON_CLK |
20 | select HAVE_OPROFILE | 12 | select GENERIC_ATOMIC64 |
13 | select GENERIC_CLOCKEVENTS | ||
14 | select GENERIC_IRQ_SHOW | ||
15 | select GENERIC_PCI_IOMAP | ||
16 | select GENERIC_SCHED_CLOCK | ||
21 | select HAVE_FUNCTION_TRACER | 17 | select HAVE_FUNCTION_TRACER |
22 | select HAVE_IRQ_TIME_ACCOUNTING | 18 | select HAVE_IRQ_TIME_ACCOUNTING |
19 | select HAVE_OPROFILE | ||
23 | select HAVE_PERF_EVENTS | 20 | select HAVE_PERF_EVENTS |
24 | select COMMON_CLK | 21 | select IRQ_DOMAIN |
22 | select MODULES_USE_ELF_RELA | ||
23 | select VIRT_TO_BUS | ||
25 | help | 24 | help |
26 | Xtensa processors are 32-bit RISC machines designed by Tensilica | 25 | Xtensa processors are 32-bit RISC machines designed by Tensilica |
27 | primarily for embedded systems. These processors are both | 26 | primarily for embedded systems. These processors are both |
@@ -62,7 +61,9 @@ config TRACE_IRQFLAGS_SUPPORT | |||
62 | def_bool y | 61 | def_bool y |
63 | 62 | ||
64 | config MMU | 63 | config MMU |
65 | def_bool n | 64 | bool |
65 | default n if !XTENSA_VARIANT_CUSTOM | ||
66 | default XTENSA_VARIANT_MMU if XTENSA_VARIANT_CUSTOM | ||
66 | 67 | ||
67 | config VARIANT_IRQ_SWITCH | 68 | config VARIANT_IRQ_SWITCH |
68 | def_bool n | 69 | def_bool n |
@@ -102,8 +103,40 @@ config XTENSA_VARIANT_S6000 | |||
102 | select VARIANT_IRQ_SWITCH | 103 | select VARIANT_IRQ_SWITCH |
103 | select ARCH_REQUIRE_GPIOLIB | 104 | select ARCH_REQUIRE_GPIOLIB |
104 | select XTENSA_CALIBRATE_CCOUNT | 105 | select XTENSA_CALIBRATE_CCOUNT |
106 | |||
107 | config XTENSA_VARIANT_CUSTOM | ||
108 | bool "Custom Xtensa processor configuration" | ||
109 | select MAY_HAVE_SMP | ||
110 | select HAVE_XTENSA_GPIO32 | ||
111 | help | ||
112 | Select this variant to use a custom Xtensa processor configuration. | ||
113 | You will be prompted for a processor variant CORENAME. | ||
105 | endchoice | 114 | endchoice |
106 | 115 | ||
116 | config XTENSA_VARIANT_CUSTOM_NAME | ||
117 | string "Xtensa Processor Custom Core Variant Name" | ||
118 | depends on XTENSA_VARIANT_CUSTOM | ||
119 | help | ||
120 | Provide the name of a custom Xtensa processor variant. | ||
121 | This CORENAME selects arch/xtensa/variant/CORENAME. | ||
122 | Dont forget you have to select MMU if you have one. | ||
123 | |||
124 | config XTENSA_VARIANT_NAME | ||
125 | string | ||
126 | default "dc232b" if XTENSA_VARIANT_DC232B | ||
127 | default "dc233c" if XTENSA_VARIANT_DC233C | ||
128 | default "fsf" if XTENSA_VARIANT_FSF | ||
129 | default "s6000" if XTENSA_VARIANT_S6000 | ||
130 | default XTENSA_VARIANT_CUSTOM_NAME if XTENSA_VARIANT_CUSTOM | ||
131 | |||
132 | config XTENSA_VARIANT_MMU | ||
133 | bool "Core variant has a Full MMU (TLB, Pages, Protection, etc)" | ||
134 | depends on XTENSA_VARIANT_CUSTOM | ||
135 | default y | ||
136 | help | ||
137 | Build a Conventional Kernel with full MMU support, | ||
138 | ie: it supports a TLB with auto-loading, page protection. | ||
139 | |||
107 | config XTENSA_UNALIGNED_USER | 140 | config XTENSA_UNALIGNED_USER |
108 | bool "Unaligned memory access in use space" | 141 | bool "Unaligned memory access in use space" |
109 | help | 142 | help |
@@ -156,13 +189,9 @@ config HOTPLUG_CPU | |||
156 | 189 | ||
157 | Say N if you want to disable CPU hotplug. | 190 | Say N if you want to disable CPU hotplug. |
158 | 191 | ||
159 | config MATH_EMULATION | ||
160 | bool "Math emulation" | ||
161 | help | ||
162 | Can we use information of configuration file? | ||
163 | |||
164 | config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX | 192 | config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX |
165 | bool "Initialize Xtensa MMU inside the Linux kernel code" | 193 | bool "Initialize Xtensa MMU inside the Linux kernel code" |
194 | depends on MMU | ||
166 | default y | 195 | default y |
167 | help | 196 | help |
168 | Earlier version initialized the MMU in the exception vector | 197 | Earlier version initialized the MMU in the exception vector |
@@ -192,6 +221,7 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX | |||
192 | 221 | ||
193 | config HIGHMEM | 222 | config HIGHMEM |
194 | bool "High Memory Support" | 223 | bool "High Memory Support" |
224 | depends on MMU | ||
195 | help | 225 | help |
196 | Linux can use the full amount of RAM in the system by | 226 | Linux can use the full amount of RAM in the system by |
197 | default. However, the default MMUv2 setup only maps the | 227 | default. However, the default MMUv2 setup only maps the |
@@ -208,6 +238,32 @@ config HIGHMEM | |||
208 | 238 | ||
209 | If unsure, say Y. | 239 | If unsure, say Y. |
210 | 240 | ||
241 | config FAST_SYSCALL_XTENSA | ||
242 | bool "Enable fast atomic syscalls" | ||
243 | default n | ||
244 | help | ||
245 | fast_syscall_xtensa is a syscall that can make atomic operations | ||
246 | on UP kernel when processor has no s32c1i support. | ||
247 | |||
248 | This syscall is deprecated. It may have issues when called with | ||
249 | invalid arguments. It is provided only for backwards compatibility. | ||
250 | Only enable it if your userspace software requires it. | ||
251 | |||
252 | If unsure, say N. | ||
253 | |||
254 | config FAST_SYSCALL_SPILL_REGISTERS | ||
255 | bool "Enable spill registers syscall" | ||
256 | default n | ||
257 | help | ||
258 | fast_syscall_spill_registers is a syscall that spills all active | ||
259 | register windows of a calling userspace task onto its stack. | ||
260 | |||
261 | This syscall is deprecated. It may have issues when called with | ||
262 | invalid arguments. It is provided only for backwards compatibility. | ||
263 | Only enable it if your userspace software requires it. | ||
264 | |||
265 | If unsure, say N. | ||
266 | |||
211 | endmenu | 267 | endmenu |
212 | 268 | ||
213 | config XTENSA_CALIBRATE_CCOUNT | 269 | config XTENSA_CALIBRATE_CCOUNT |
@@ -250,12 +306,14 @@ config XTENSA_PLATFORM_ISS | |||
250 | 306 | ||
251 | config XTENSA_PLATFORM_XT2000 | 307 | config XTENSA_PLATFORM_XT2000 |
252 | bool "XT2000" | 308 | bool "XT2000" |
309 | select HAVE_IDE | ||
253 | help | 310 | help |
254 | XT2000 is the name of Tensilica's feature-rich emulation platform. | 311 | XT2000 is the name of Tensilica's feature-rich emulation platform. |
255 | This hardware is capable of running a full Linux distribution. | 312 | This hardware is capable of running a full Linux distribution. |
256 | 313 | ||
257 | config XTENSA_PLATFORM_S6105 | 314 | config XTENSA_PLATFORM_S6105 |
258 | bool "S6105" | 315 | bool "S6105" |
316 | select HAVE_IDE | ||
259 | select SERIAL_CONSOLE | 317 | select SERIAL_CONSOLE |
260 | select NO_IOPORT_MAP | 318 | select NO_IOPORT_MAP |
261 | 319 | ||
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 81250ece3062..472533064b46 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # for more details. | 4 | # for more details. |
5 | # | 5 | # |
6 | # Copyright (C) 2001 - 2005 Tensilica Inc. | 6 | # Copyright (C) 2001 - 2005 Tensilica Inc. |
7 | # Copyright (C) 2014 Cadence Design Systems Inc. | ||
7 | # | 8 | # |
8 | # This file is included by the global makefile so that you can add your own | 9 | # This file is included by the global makefile so that you can add your own |
9 | # architecture-specific flags and dependencies. Remember to do have actions | 10 | # architecture-specific flags and dependencies. Remember to do have actions |
@@ -13,11 +14,7 @@ | |||
13 | # Core configuration. | 14 | # Core configuration. |
14 | # (Use VAR=<xtensa_config> to use another default compiler.) | 15 | # (Use VAR=<xtensa_config> to use another default compiler.) |
15 | 16 | ||
16 | variant-$(CONFIG_XTENSA_VARIANT_FSF) := fsf | 17 | variant-y := $(patsubst "%",%,$(CONFIG_XTENSA_VARIANT_NAME)) |
17 | variant-$(CONFIG_XTENSA_VARIANT_DC232B) := dc232b | ||
18 | variant-$(CONFIG_XTENSA_VARIANT_DC233C) := dc233c | ||
19 | variant-$(CONFIG_XTENSA_VARIANT_S6000) := s6000 | ||
20 | variant-$(CONFIG_XTENSA_VARIANT_LINUX_CUSTOM) := custom | ||
21 | 18 | ||
22 | VARIANT = $(variant-y) | 19 | VARIANT = $(variant-y) |
23 | export VARIANT | 20 | export VARIANT |
diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts index 742a347be67a..c4d17a34ab86 100644 --- a/arch/xtensa/boot/dts/kc705.dts +++ b/arch/xtensa/boot/dts/kc705.dts | |||
@@ -4,8 +4,11 @@ | |||
4 | 4 | ||
5 | / { | 5 | / { |
6 | compatible = "cdns,xtensa-kc705"; | 6 | compatible = "cdns,xtensa-kc705"; |
7 | chosen { | ||
8 | bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=0x38000000"; | ||
9 | }; | ||
7 | memory@0 { | 10 | memory@0 { |
8 | device_type = "memory"; | 11 | device_type = "memory"; |
9 | reg = <0x00000000 0x08000000>; | 12 | reg = <0x00000000 0x38000000>; |
10 | }; | 13 | }; |
11 | }; | 14 | }; |
diff --git a/arch/xtensa/configs/common_defconfig b/arch/xtensa/configs/common_defconfig index f6000fe05119..721df1214bc3 100644 --- a/arch/xtensa/configs/common_defconfig +++ b/arch/xtensa/configs/common_defconfig | |||
@@ -66,7 +66,6 @@ CONFIG_XTENSA_ARCH_LINUX_BE=y | |||
66 | CONFIG_MMU=y | 66 | CONFIG_MMU=y |
67 | # CONFIG_XTENSA_UNALIGNED_USER is not set | 67 | # CONFIG_XTENSA_UNALIGNED_USER is not set |
68 | # CONFIG_PREEMPT is not set | 68 | # CONFIG_PREEMPT is not set |
69 | # CONFIG_MATH_EMULATION is not set | ||
70 | # CONFIG_HIGHMEM is not set | 69 | # CONFIG_HIGHMEM is not set |
71 | 70 | ||
72 | # | 71 | # |
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig index 1493c68352d1..b966baf82cae 100644 --- a/arch/xtensa/configs/iss_defconfig +++ b/arch/xtensa/configs/iss_defconfig | |||
@@ -146,7 +146,6 @@ CONFIG_XTENSA_VARIANT_FSF=y | |||
146 | # CONFIG_XTENSA_VARIANT_S6000 is not set | 146 | # CONFIG_XTENSA_VARIANT_S6000 is not set |
147 | # CONFIG_XTENSA_UNALIGNED_USER is not set | 147 | # CONFIG_XTENSA_UNALIGNED_USER is not set |
148 | # CONFIG_PREEMPT is not set | 148 | # CONFIG_PREEMPT is not set |
149 | # CONFIG_MATH_EMULATION is not set | ||
150 | CONFIG_XTENSA_CALIBRATE_CCOUNT=y | 149 | CONFIG_XTENSA_CALIBRATE_CCOUNT=y |
151 | CONFIG_SERIAL_CONSOLE=y | 150 | CONFIG_SERIAL_CONSOLE=y |
152 | CONFIG_XTENSA_ISS_NETWORK=y | 151 | CONFIG_XTENSA_ISS_NETWORK=y |
@@ -308,7 +307,7 @@ CONFIG_MISC_DEVICES=y | |||
308 | # EEPROM support | 307 | # EEPROM support |
309 | # | 308 | # |
310 | # CONFIG_EEPROM_93CX6 is not set | 309 | # CONFIG_EEPROM_93CX6 is not set |
311 | CONFIG_HAVE_IDE=y | 310 | # CONFIG_HAVE_IDE is not set |
312 | # CONFIG_IDE is not set | 311 | # CONFIG_IDE is not set |
313 | 312 | ||
314 | # | 313 | # |
diff --git a/arch/xtensa/configs/s6105_defconfig b/arch/xtensa/configs/s6105_defconfig index 12a492ab6d17..9471265b8ca6 100644 --- a/arch/xtensa/configs/s6105_defconfig +++ b/arch/xtensa/configs/s6105_defconfig | |||
@@ -109,7 +109,6 @@ CONFIG_VARIANT_IRQ_SWITCH=y | |||
109 | CONFIG_XTENSA_VARIANT_S6000=y | 109 | CONFIG_XTENSA_VARIANT_S6000=y |
110 | # CONFIG_XTENSA_UNALIGNED_USER is not set | 110 | # CONFIG_XTENSA_UNALIGNED_USER is not set |
111 | CONFIG_PREEMPT=y | 111 | CONFIG_PREEMPT=y |
112 | # CONFIG_MATH_EMULATION is not set | ||
113 | # CONFIG_HIGHMEM is not set | 112 | # CONFIG_HIGHMEM is not set |
114 | CONFIG_XTENSA_CALIBRATE_CCOUNT=y | 113 | CONFIG_XTENSA_CALIBRATE_CCOUNT=y |
115 | CONFIG_SERIAL_CONSOLE=y | 114 | CONFIG_SERIAL_CONSOLE=y |
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h index 555a98a18453..e72aaca7a77f 100644 --- a/arch/xtensa/include/asm/cacheflush.h +++ b/arch/xtensa/include/asm/cacheflush.h | |||
@@ -37,6 +37,7 @@ | |||
37 | * specials for cache aliasing: | 37 | * specials for cache aliasing: |
38 | * | 38 | * |
39 | * __flush_invalidate_dcache_page_alias(vaddr,paddr) | 39 | * __flush_invalidate_dcache_page_alias(vaddr,paddr) |
40 | * __invalidate_dcache_page_alias(vaddr,paddr) | ||
40 | * __invalidate_icache_page_alias(vaddr,paddr) | 41 | * __invalidate_icache_page_alias(vaddr,paddr) |
41 | */ | 42 | */ |
42 | 43 | ||
@@ -62,6 +63,7 @@ extern void __flush_invalidate_dcache_range(unsigned long, unsigned long); | |||
62 | 63 | ||
63 | #if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) | 64 | #if defined(CONFIG_MMU) && (DCACHE_WAY_SIZE > PAGE_SIZE) |
64 | extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); | 65 | extern void __flush_invalidate_dcache_page_alias(unsigned long, unsigned long); |
66 | extern void __invalidate_dcache_page_alias(unsigned long, unsigned long); | ||
65 | #else | 67 | #else |
66 | static inline void __flush_invalidate_dcache_page_alias(unsigned long virt, | 68 | static inline void __flush_invalidate_dcache_page_alias(unsigned long virt, |
67 | unsigned long phys) { } | 69 | unsigned long phys) { } |
diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h index 9f6c33d0428a..62b507deea9d 100644 --- a/arch/xtensa/include/asm/fixmap.h +++ b/arch/xtensa/include/asm/fixmap.h | |||
@@ -23,8 +23,8 @@ | |||
23 | * Here we define all the compile-time 'special' virtual | 23 | * Here we define all the compile-time 'special' virtual |
24 | * addresses. The point is to have a constant address at | 24 | * addresses. The point is to have a constant address at |
25 | * compile time, but to set the physical address only | 25 | * compile time, but to set the physical address only |
26 | * in the boot process. We allocate these special addresses | 26 | * in the boot process. We allocate these special addresses |
27 | * from the end of the consistent memory region backwards. | 27 | * from the start of the consistent memory region upwards. |
28 | * Also this lets us do fail-safe vmalloc(), we | 28 | * Also this lets us do fail-safe vmalloc(), we |
29 | * can guarantee that these special addresses and | 29 | * can guarantee that these special addresses and |
30 | * vmalloc()-ed addresses never overlap. | 30 | * vmalloc()-ed addresses never overlap. |
@@ -38,7 +38,8 @@ enum fixed_addresses { | |||
38 | #ifdef CONFIG_HIGHMEM | 38 | #ifdef CONFIG_HIGHMEM |
39 | /* reserved pte's for temporary kernel mappings */ | 39 | /* reserved pte's for temporary kernel mappings */ |
40 | FIX_KMAP_BEGIN, | 40 | FIX_KMAP_BEGIN, |
41 | FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, | 41 | FIX_KMAP_END = FIX_KMAP_BEGIN + |
42 | (KM_TYPE_NR * NR_CPUS * DCACHE_N_COLORS) - 1, | ||
42 | #endif | 43 | #endif |
43 | __end_of_fixed_addresses | 44 | __end_of_fixed_addresses |
44 | }; | 45 | }; |
@@ -47,7 +48,28 @@ enum fixed_addresses { | |||
47 | #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) | 48 | #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) |
48 | #define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) | 49 | #define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) |
49 | 50 | ||
50 | #include <asm-generic/fixmap.h> | 51 | #define __fix_to_virt(x) (FIXADDR_START + ((x) << PAGE_SHIFT)) |
52 | #define __virt_to_fix(x) (((x) - FIXADDR_START) >> PAGE_SHIFT) | ||
53 | |||
54 | #ifndef __ASSEMBLY__ | ||
55 | /* | ||
56 | * 'index to address' translation. If anyone tries to use the idx | ||
57 | * directly without translation, we catch the bug with a NULL-deference | ||
58 | * kernel oops. Illegal ranges of incoming indices are caught too. | ||
59 | */ | ||
60 | static __always_inline unsigned long fix_to_virt(const unsigned int idx) | ||
61 | { | ||
62 | BUILD_BUG_ON(idx >= __end_of_fixed_addresses); | ||
63 | return __fix_to_virt(idx); | ||
64 | } | ||
65 | |||
66 | static inline unsigned long virt_to_fix(const unsigned long vaddr) | ||
67 | { | ||
68 | BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); | ||
69 | return __virt_to_fix(vaddr); | ||
70 | } | ||
71 | |||
72 | #endif | ||
51 | 73 | ||
52 | #define kmap_get_fixmap_pte(vaddr) \ | 74 | #define kmap_get_fixmap_pte(vaddr) \ |
53 | pte_offset_kernel( \ | 75 | pte_offset_kernel( \ |
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 2653ef5d55f1..2c7901edffaf 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h | |||
@@ -12,19 +12,55 @@ | |||
12 | #ifndef _XTENSA_HIGHMEM_H | 12 | #ifndef _XTENSA_HIGHMEM_H |
13 | #define _XTENSA_HIGHMEM_H | 13 | #define _XTENSA_HIGHMEM_H |
14 | 14 | ||
15 | #include <linux/wait.h> | ||
15 | #include <asm/cacheflush.h> | 16 | #include <asm/cacheflush.h> |
16 | #include <asm/fixmap.h> | 17 | #include <asm/fixmap.h> |
17 | #include <asm/kmap_types.h> | 18 | #include <asm/kmap_types.h> |
18 | #include <asm/pgtable.h> | 19 | #include <asm/pgtable.h> |
19 | 20 | ||
20 | #define PKMAP_BASE (FIXADDR_START - PMD_SIZE) | 21 | #define PKMAP_BASE ((FIXADDR_START - \ |
21 | #define LAST_PKMAP PTRS_PER_PTE | 22 | (LAST_PKMAP + 1) * PAGE_SIZE) & PMD_MASK) |
23 | #define LAST_PKMAP (PTRS_PER_PTE * DCACHE_N_COLORS) | ||
22 | #define LAST_PKMAP_MASK (LAST_PKMAP - 1) | 24 | #define LAST_PKMAP_MASK (LAST_PKMAP - 1) |
23 | #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) | 25 | #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) |
24 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | 26 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) |
25 | 27 | ||
26 | #define kmap_prot PAGE_KERNEL | 28 | #define kmap_prot PAGE_KERNEL |
27 | 29 | ||
30 | #if DCACHE_WAY_SIZE > PAGE_SIZE | ||
31 | #define get_pkmap_color get_pkmap_color | ||
32 | static inline int get_pkmap_color(struct page *page) | ||
33 | { | ||
34 | return DCACHE_ALIAS(page_to_phys(page)); | ||
35 | } | ||
36 | |||
37 | extern unsigned int last_pkmap_nr_arr[]; | ||
38 | |||
39 | static inline unsigned int get_next_pkmap_nr(unsigned int color) | ||
40 | { | ||
41 | last_pkmap_nr_arr[color] = | ||
42 | (last_pkmap_nr_arr[color] + DCACHE_N_COLORS) & LAST_PKMAP_MASK; | ||
43 | return last_pkmap_nr_arr[color] + color; | ||
44 | } | ||
45 | |||
46 | static inline int no_more_pkmaps(unsigned int pkmap_nr, unsigned int color) | ||
47 | { | ||
48 | return pkmap_nr < DCACHE_N_COLORS; | ||
49 | } | ||
50 | |||
51 | static inline int get_pkmap_entries_count(unsigned int color) | ||
52 | { | ||
53 | return LAST_PKMAP / DCACHE_N_COLORS; | ||
54 | } | ||
55 | |||
56 | extern wait_queue_head_t pkmap_map_wait_arr[]; | ||
57 | |||
58 | static inline wait_queue_head_t *get_pkmap_wait_queue_head(unsigned int color) | ||
59 | { | ||
60 | return pkmap_map_wait_arr + color; | ||
61 | } | ||
62 | #endif | ||
63 | |||
28 | extern pte_t *pkmap_page_table; | 64 | extern pte_t *pkmap_page_table; |
29 | 65 | ||
30 | void *kmap_high(struct page *page); | 66 | void *kmap_high(struct page *page); |
diff --git a/arch/xtensa/include/asm/page.h b/arch/xtensa/include/asm/page.h index 47f582333f6b..abe24c6f8b2f 100644 --- a/arch/xtensa/include/asm/page.h +++ b/arch/xtensa/include/asm/page.h | |||
@@ -78,7 +78,9 @@ | |||
78 | # define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) | 78 | # define DCACHE_ALIAS_EQ(a,b) ((((a) ^ (b)) & DCACHE_ALIAS_MASK) == 0) |
79 | #else | 79 | #else |
80 | # define DCACHE_ALIAS_ORDER 0 | 80 | # define DCACHE_ALIAS_ORDER 0 |
81 | # define DCACHE_ALIAS(a) ((void)(a), 0) | ||
81 | #endif | 82 | #endif |
83 | #define DCACHE_N_COLORS (1 << DCACHE_ALIAS_ORDER) | ||
82 | 84 | ||
83 | #if ICACHE_WAY_SIZE > PAGE_SIZE | 85 | #if ICACHE_WAY_SIZE > PAGE_SIZE |
84 | # define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT) | 86 | # define ICACHE_ALIAS_ORDER (ICACHE_WAY_SHIFT - PAGE_SHIFT) |
@@ -134,6 +136,7 @@ static inline __attribute_const__ int get_order(unsigned long size) | |||
134 | #endif | 136 | #endif |
135 | 137 | ||
136 | struct page; | 138 | struct page; |
139 | struct vm_area_struct; | ||
137 | extern void clear_page(void *page); | 140 | extern void clear_page(void *page); |
138 | extern void copy_page(void *to, void *from); | 141 | extern void copy_page(void *to, void *from); |
139 | 142 | ||
@@ -143,8 +146,15 @@ extern void copy_page(void *to, void *from); | |||
143 | */ | 146 | */ |
144 | 147 | ||
145 | #if DCACHE_WAY_SIZE > PAGE_SIZE | 148 | #if DCACHE_WAY_SIZE > PAGE_SIZE |
146 | extern void clear_user_page(void*, unsigned long, struct page*); | 149 | extern void clear_page_alias(void *vaddr, unsigned long paddr); |
147 | extern void copy_user_page(void*, void*, unsigned long, struct page*); | 150 | extern void copy_page_alias(void *to, void *from, |
151 | unsigned long to_paddr, unsigned long from_paddr); | ||
152 | |||
153 | #define clear_user_highpage clear_user_highpage | ||
154 | void clear_user_highpage(struct page *page, unsigned long vaddr); | ||
155 | #define __HAVE_ARCH_COPY_USER_HIGHPAGE | ||
156 | void copy_user_highpage(struct page *to, struct page *from, | ||
157 | unsigned long vaddr, struct vm_area_struct *vma); | ||
148 | #else | 158 | #else |
149 | # define clear_user_page(page, vaddr, pg) clear_page(page) | 159 | # define clear_user_page(page, vaddr, pg) clear_page(page) |
150 | # define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | 160 | # define copy_user_page(to, from, vaddr, pg) copy_page(to, from) |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 4b0ca35a93b1..b2173e5da601 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -67,7 +67,12 @@ | |||
67 | #define VMALLOC_START 0xC0000000 | 67 | #define VMALLOC_START 0xC0000000 |
68 | #define VMALLOC_END 0xC7FEFFFF | 68 | #define VMALLOC_END 0xC7FEFFFF |
69 | #define TLBTEMP_BASE_1 0xC7FF0000 | 69 | #define TLBTEMP_BASE_1 0xC7FF0000 |
70 | #define TLBTEMP_BASE_2 0xC7FF8000 | 70 | #define TLBTEMP_BASE_2 (TLBTEMP_BASE_1 + DCACHE_WAY_SIZE) |
71 | #if 2 * DCACHE_WAY_SIZE > ICACHE_WAY_SIZE | ||
72 | #define TLBTEMP_SIZE (2 * DCACHE_WAY_SIZE) | ||
73 | #else | ||
74 | #define TLBTEMP_SIZE ICACHE_WAY_SIZE | ||
75 | #endif | ||
71 | 76 | ||
72 | /* | 77 | /* |
73 | * For the Xtensa architecture, the PTE layout is as follows: | 78 | * For the Xtensa architecture, the PTE layout is as follows: |
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h index fd686dc45d1a..c7211e7e182d 100644 --- a/arch/xtensa/include/asm/uaccess.h +++ b/arch/xtensa/include/asm/uaccess.h | |||
@@ -52,7 +52,12 @@ | |||
52 | */ | 52 | */ |
53 | .macro get_fs ad, sp | 53 | .macro get_fs ad, sp |
54 | GET_CURRENT(\ad,\sp) | 54 | GET_CURRENT(\ad,\sp) |
55 | #if THREAD_CURRENT_DS > 1020 | ||
56 | addi \ad, \ad, TASK_THREAD | ||
57 | l32i \ad, \ad, THREAD_CURRENT_DS - TASK_THREAD | ||
58 | #else | ||
55 | l32i \ad, \ad, THREAD_CURRENT_DS | 59 | l32i \ad, \ad, THREAD_CURRENT_DS |
60 | #endif | ||
56 | .endm | 61 | .endm |
57 | 62 | ||
58 | /* | 63 | /* |
diff --git a/arch/xtensa/include/uapi/asm/ioctls.h b/arch/xtensa/include/uapi/asm/ioctls.h index b4cb1100c0fb..a47909f0c34b 100644 --- a/arch/xtensa/include/uapi/asm/ioctls.h +++ b/arch/xtensa/include/uapi/asm/ioctls.h | |||
@@ -28,17 +28,17 @@ | |||
28 | #define TCSETSW 0x5403 | 28 | #define TCSETSW 0x5403 |
29 | #define TCSETSF 0x5404 | 29 | #define TCSETSF 0x5404 |
30 | 30 | ||
31 | #define TCGETA _IOR('t', 23, struct termio) | 31 | #define TCGETA 0x80127417 /* _IOR('t', 23, struct termio) */ |
32 | #define TCSETA _IOW('t', 24, struct termio) | 32 | #define TCSETA 0x40127418 /* _IOW('t', 24, struct termio) */ |
33 | #define TCSETAW _IOW('t', 25, struct termio) | 33 | #define TCSETAW 0x40127419 /* _IOW('t', 25, struct termio) */ |
34 | #define TCSETAF _IOW('t', 28, struct termio) | 34 | #define TCSETAF 0x4012741C /* _IOW('t', 28, struct termio) */ |
35 | 35 | ||
36 | #define TCSBRK _IO('t', 29) | 36 | #define TCSBRK _IO('t', 29) |
37 | #define TCXONC _IO('t', 30) | 37 | #define TCXONC _IO('t', 30) |
38 | #define TCFLSH _IO('t', 31) | 38 | #define TCFLSH _IO('t', 31) |
39 | 39 | ||
40 | #define TIOCSWINSZ _IOW('t', 103, struct winsize) | 40 | #define TIOCSWINSZ 0x40087467 /* _IOW('t', 103, struct winsize) */ |
41 | #define TIOCGWINSZ _IOR('t', 104, struct winsize) | 41 | #define TIOCGWINSZ 0x80087468 /* _IOR('t', 104, struct winsize) */ |
42 | #define TIOCSTART _IO('t', 110) /* start output, like ^Q */ | 42 | #define TIOCSTART _IO('t', 110) /* start output, like ^Q */ |
43 | #define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ | 43 | #define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ |
44 | #define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ | 44 | #define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ |
@@ -88,7 +88,6 @@ | |||
88 | #define TIOCSETD _IOW('T', 35, int) | 88 | #define TIOCSETD _IOW('T', 35, int) |
89 | #define TIOCGETD _IOR('T', 36, int) | 89 | #define TIOCGETD _IOR('T', 36, int) |
90 | #define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/ | 90 | #define TCSBRKP _IOW('T', 37, int) /* Needed for POSIX tcsendbreak()*/ |
91 | #define TIOCTTYGSTRUCT _IOR('T', 38, struct tty_struct) /* For debugging only*/ | ||
92 | #define TIOCSBRK _IO('T', 39) /* BSD compatibility */ | 91 | #define TIOCSBRK _IO('T', 39) /* BSD compatibility */ |
93 | #define TIOCCBRK _IO('T', 40) /* BSD compatibility */ | 92 | #define TIOCCBRK _IO('T', 40) /* BSD compatibility */ |
94 | #define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/ | 93 | #define TIOCGSID _IOR('T', 41, pid_t) /* Return the session ID of FD*/ |
@@ -114,8 +113,10 @@ | |||
114 | #define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */ | 113 | #define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* Get line status reg. */ |
115 | /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ | 114 | /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ |
116 | # define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | 115 | # define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ |
117 | #define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* Get multiport config */ | 116 | #define TIOCSERGETMULTI 0x80a8545a /* Get multiport config */ |
118 | #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ | 117 | /* _IOR('T', 90, struct serial_multiport_struct) */ |
118 | #define TIOCSERSETMULTI 0x40a8545b /* Set multiport config */ | ||
119 | /* _IOW('T', 91, struct serial_multiport_struct) */ | ||
119 | 120 | ||
120 | #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ | 121 | #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ |
121 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | 122 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ |
diff --git a/arch/xtensa/include/uapi/asm/unistd.h b/arch/xtensa/include/uapi/asm/unistd.h index b9395529f02d..8883fc877c5c 100644 --- a/arch/xtensa/include/uapi/asm/unistd.h +++ b/arch/xtensa/include/uapi/asm/unistd.h | |||
@@ -739,7 +739,10 @@ __SYSCALL(334, sys_sched_setattr, 2) | |||
739 | #define __NR_sched_getattr 335 | 739 | #define __NR_sched_getattr 335 |
740 | __SYSCALL(335, sys_sched_getattr, 3) | 740 | __SYSCALL(335, sys_sched_getattr, 3) |
741 | 741 | ||
742 | #define __NR_syscall_count 336 | 742 | #define __NR_renameat2 336 |
743 | __SYSCALL(336, sys_renameat2, 5) | ||
744 | |||
745 | #define __NR_syscall_count 337 | ||
743 | 746 | ||
744 | /* | 747 | /* |
745 | * sysxtensa syscall handler | 748 | * sysxtensa syscall handler |
diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index d4cef6039a5c..890004af03a9 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S | |||
@@ -8,6 +8,7 @@ | |||
8 | * this archive for more details. | 8 | * this archive for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica, Inc. | 10 | * Copyright (C) 2001 - 2005 Tensilica, Inc. |
11 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
11 | * | 12 | * |
12 | * Rewritten by Chris Zankel <chris@zankel.net> | 13 | * Rewritten by Chris Zankel <chris@zankel.net> |
13 | * | 14 | * |
@@ -174,6 +175,10 @@ ENTRY(fast_unaligned) | |||
174 | s32i a0, a2, PT_AREG2 | 175 | s32i a0, a2, PT_AREG2 |
175 | s32i a3, a2, PT_AREG3 | 176 | s32i a3, a2, PT_AREG3 |
176 | 177 | ||
178 | rsr a3, excsave1 | ||
179 | movi a4, fast_unaligned_fixup | ||
180 | s32i a4, a3, EXC_TABLE_FIXUP | ||
181 | |||
177 | /* Keep value of SAR in a0 */ | 182 | /* Keep value of SAR in a0 */ |
178 | 183 | ||
179 | rsr a0, sar | 184 | rsr a0, sar |
@@ -225,10 +230,6 @@ ENTRY(fast_unaligned) | |||
225 | addx8 a5, a6, a5 | 230 | addx8 a5, a6, a5 |
226 | jx a5 # jump into table | 231 | jx a5 # jump into table |
227 | 232 | ||
228 | /* Invalid instruction, CRITICAL! */ | ||
229 | .Linvalid_instruction_load: | ||
230 | j .Linvalid_instruction | ||
231 | |||
232 | /* Load: Load memory address. */ | 233 | /* Load: Load memory address. */ |
233 | 234 | ||
234 | .Lload: movi a3, ~3 | 235 | .Lload: movi a3, ~3 |
@@ -272,18 +273,6 @@ ENTRY(fast_unaligned) | |||
272 | /* Set target register. */ | 273 | /* Set target register. */ |
273 | 274 | ||
274 | 1: | 275 | 1: |
275 | |||
276 | #if XCHAL_HAVE_LOOPS | ||
277 | rsr a5, lend # check if we reached LEND | ||
278 | bne a7, a5, 1f | ||
279 | rsr a5, lcount # and LCOUNT != 0 | ||
280 | beqz a5, 1f | ||
281 | addi a5, a5, -1 # decrement LCOUNT and set | ||
282 | rsr a7, lbeg # set PC to LBEGIN | ||
283 | wsr a5, lcount | ||
284 | #endif | ||
285 | |||
286 | 1: wsr a7, epc1 # skip load instruction | ||
287 | extui a4, a4, INSN_T, 4 # extract target register | 276 | extui a4, a4, INSN_T, 4 # extract target register |
288 | movi a5, .Lload_table | 277 | movi a5, .Lload_table |
289 | addx8 a4, a4, a5 | 278 | addx8 a4, a4, a5 |
@@ -326,6 +315,35 @@ ENTRY(fast_unaligned) | |||
326 | mov a3, a14 ; _j 1f; .align 8 | 315 | mov a3, a14 ; _j 1f; .align 8 |
327 | mov a3, a15 ; _j 1f; .align 8 | 316 | mov a3, a15 ; _j 1f; .align 8 |
328 | 317 | ||
318 | /* We cannot handle this exception. */ | ||
319 | |||
320 | .extern _kernel_exception | ||
321 | .Linvalid_instruction_load: | ||
322 | .Linvalid_instruction_store: | ||
323 | |||
324 | movi a4, 0 | ||
325 | rsr a3, excsave1 | ||
326 | s32i a4, a3, EXC_TABLE_FIXUP | ||
327 | |||
328 | /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ | ||
329 | |||
330 | l32i a8, a2, PT_AREG8 | ||
331 | l32i a7, a2, PT_AREG7 | ||
332 | l32i a6, a2, PT_AREG6 | ||
333 | l32i a5, a2, PT_AREG5 | ||
334 | l32i a4, a2, PT_AREG4 | ||
335 | wsr a0, sar | ||
336 | mov a1, a2 | ||
337 | |||
338 | rsr a0, ps | ||
339 | bbsi.l a0, PS_UM_BIT, 2f # jump if user mode | ||
340 | |||
341 | movi a0, _kernel_exception | ||
342 | jx a0 | ||
343 | |||
344 | 2: movi a0, _user_exception | ||
345 | jx a0 | ||
346 | |||
329 | 1: # a7: instruction pointer, a4: instruction, a3: value | 347 | 1: # a7: instruction pointer, a4: instruction, a3: value |
330 | 348 | ||
331 | movi a6, 0 # mask: ffffffff:00000000 | 349 | movi a6, 0 # mask: ffffffff:00000000 |
@@ -353,17 +371,6 @@ ENTRY(fast_unaligned) | |||
353 | /* Get memory address */ | 371 | /* Get memory address */ |
354 | 372 | ||
355 | 1: | 373 | 1: |
356 | #if XCHAL_HAVE_LOOPS | ||
357 | rsr a4, lend # check if we reached LEND | ||
358 | bne a7, a4, 1f | ||
359 | rsr a4, lcount # and LCOUNT != 0 | ||
360 | beqz a4, 1f | ||
361 | addi a4, a4, -1 # decrement LCOUNT and set | ||
362 | rsr a7, lbeg # set PC to LBEGIN | ||
363 | wsr a4, lcount | ||
364 | #endif | ||
365 | |||
366 | 1: wsr a7, epc1 # skip store instruction | ||
367 | movi a4, ~3 | 374 | movi a4, ~3 |
368 | and a4, a4, a8 # align memory address | 375 | and a4, a4, a8 # align memory address |
369 | 376 | ||
@@ -375,25 +382,25 @@ ENTRY(fast_unaligned) | |||
375 | #endif | 382 | #endif |
376 | 383 | ||
377 | __ssa8r a8 | 384 | __ssa8r a8 |
378 | __src_b a7, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) | 385 | __src_b a8, a5, a6 # lo-mask F..F0..0 (BE) 0..0F..F (LE) |
379 | __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE) | 386 | __src_b a6, a6, a5 # hi-mask 0..0F..F (BE) F..F0..0 (LE) |
380 | #ifdef UNALIGNED_USER_EXCEPTION | 387 | #ifdef UNALIGNED_USER_EXCEPTION |
381 | l32e a5, a4, -8 | 388 | l32e a5, a4, -8 |
382 | #else | 389 | #else |
383 | l32i a5, a4, 0 # load lower address word | 390 | l32i a5, a4, 0 # load lower address word |
384 | #endif | 391 | #endif |
385 | and a5, a5, a7 # mask | 392 | and a5, a5, a8 # mask |
386 | __sh a7, a3 # shift value | 393 | __sh a8, a3 # shift value |
387 | or a5, a5, a7 # or with original value | 394 | or a5, a5, a8 # or with original value |
388 | #ifdef UNALIGNED_USER_EXCEPTION | 395 | #ifdef UNALIGNED_USER_EXCEPTION |
389 | s32e a5, a4, -8 | 396 | s32e a5, a4, -8 |
390 | l32e a7, a4, -4 | 397 | l32e a8, a4, -4 |
391 | #else | 398 | #else |
392 | s32i a5, a4, 0 # store | 399 | s32i a5, a4, 0 # store |
393 | l32i a7, a4, 4 # same for upper address word | 400 | l32i a8, a4, 4 # same for upper address word |
394 | #endif | 401 | #endif |
395 | __sl a5, a3 | 402 | __sl a5, a3 |
396 | and a6, a7, a6 | 403 | and a6, a8, a6 |
397 | or a6, a6, a5 | 404 | or a6, a6, a5 |
398 | #ifdef UNALIGNED_USER_EXCEPTION | 405 | #ifdef UNALIGNED_USER_EXCEPTION |
399 | s32e a6, a4, -4 | 406 | s32e a6, a4, -4 |
@@ -401,9 +408,27 @@ ENTRY(fast_unaligned) | |||
401 | s32i a6, a4, 4 | 408 | s32i a6, a4, 4 |
402 | #endif | 409 | #endif |
403 | 410 | ||
404 | /* Done. restore stack and return */ | ||
405 | |||
406 | .Lexit: | 411 | .Lexit: |
412 | #if XCHAL_HAVE_LOOPS | ||
413 | rsr a4, lend # check if we reached LEND | ||
414 | bne a7, a4, 1f | ||
415 | rsr a4, lcount # and LCOUNT != 0 | ||
416 | beqz a4, 1f | ||
417 | addi a4, a4, -1 # decrement LCOUNT and set | ||
418 | rsr a7, lbeg # set PC to LBEGIN | ||
419 | wsr a4, lcount | ||
420 | #endif | ||
421 | |||
422 | 1: wsr a7, epc1 # skip emulated instruction | ||
423 | |||
424 | /* Update icount if we're single-stepping in userspace. */ | ||
425 | rsr a4, icountlevel | ||
426 | beqz a4, 1f | ||
427 | bgeui a4, LOCKLEVEL + 1, 1f | ||
428 | rsr a4, icount | ||
429 | addi a4, a4, 1 | ||
430 | wsr a4, icount | ||
431 | 1: | ||
407 | movi a4, 0 | 432 | movi a4, 0 |
408 | rsr a3, excsave1 | 433 | rsr a3, excsave1 |
409 | s32i a4, a3, EXC_TABLE_FIXUP | 434 | s32i a4, a3, EXC_TABLE_FIXUP |
@@ -424,31 +449,40 @@ ENTRY(fast_unaligned) | |||
424 | l32i a2, a2, PT_AREG2 | 449 | l32i a2, a2, PT_AREG2 |
425 | rfe | 450 | rfe |
426 | 451 | ||
427 | /* We cannot handle this exception. */ | 452 | ENDPROC(fast_unaligned) |
428 | 453 | ||
429 | .extern _kernel_exception | 454 | ENTRY(fast_unaligned_fixup) |
430 | .Linvalid_instruction_store: | ||
431 | .Linvalid_instruction: | ||
432 | 455 | ||
433 | /* Restore a4...a8 and SAR, set SP, and jump to default exception. */ | 456 | l32i a2, a3, EXC_TABLE_DOUBLE_SAVE |
457 | wsr a3, excsave1 | ||
434 | 458 | ||
435 | l32i a8, a2, PT_AREG8 | 459 | l32i a8, a2, PT_AREG8 |
436 | l32i a7, a2, PT_AREG7 | 460 | l32i a7, a2, PT_AREG7 |
437 | l32i a6, a2, PT_AREG6 | 461 | l32i a6, a2, PT_AREG6 |
438 | l32i a5, a2, PT_AREG5 | 462 | l32i a5, a2, PT_AREG5 |
439 | l32i a4, a2, PT_AREG4 | 463 | l32i a4, a2, PT_AREG4 |
464 | l32i a0, a2, PT_AREG2 | ||
465 | xsr a0, depc # restore depc and a0 | ||
440 | wsr a0, sar | 466 | wsr a0, sar |
441 | mov a1, a2 | 467 | |
468 | rsr a0, exccause | ||
469 | s32i a0, a2, PT_DEPC # mark as a regular exception | ||
442 | 470 | ||
443 | rsr a0, ps | 471 | rsr a0, ps |
444 | bbsi.l a2, PS_UM_BIT, 1f # jump if user mode | 472 | bbsi.l a0, PS_UM_BIT, 1f # jump if user mode |
445 | 473 | ||
446 | movi a0, _kernel_exception | 474 | rsr a0, exccause |
475 | addx4 a0, a0, a3 # find entry in table | ||
476 | l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler | ||
477 | l32i a3, a2, PT_AREG3 | ||
447 | jx a0 | 478 | jx a0 |
448 | 479 | 1: | |
449 | 1: movi a0, _user_exception | 480 | rsr a0, exccause |
481 | addx4 a0, a0, a3 # find entry in table | ||
482 | l32i a0, a0, EXC_TABLE_FAST_USER # load handler | ||
483 | l32i a3, a2, PT_AREG3 | ||
450 | jx a0 | 484 | jx a0 |
451 | 485 | ||
452 | ENDPROC(fast_unaligned) | 486 | ENDPROC(fast_unaligned_fixup) |
453 | 487 | ||
454 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ | 488 | #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ |
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S index ef7f4990722b..82bbfa5a05b3 100644 --- a/arch/xtensa/kernel/entry.S +++ b/arch/xtensa/kernel/entry.S | |||
@@ -986,6 +986,8 @@ ENDPROC(fast_syscall_unrecoverable) | |||
986 | * j done | 986 | * j done |
987 | */ | 987 | */ |
988 | 988 | ||
989 | #ifdef CONFIG_FAST_SYSCALL_XTENSA | ||
990 | |||
989 | #define TRY \ | 991 | #define TRY \ |
990 | .section __ex_table, "a"; \ | 992 | .section __ex_table, "a"; \ |
991 | .word 66f, 67f; \ | 993 | .word 66f, 67f; \ |
@@ -1001,9 +1003,8 @@ ENTRY(fast_syscall_xtensa) | |||
1001 | movi a7, 4 # sizeof(unsigned int) | 1003 | movi a7, 4 # sizeof(unsigned int) |
1002 | access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp | 1004 | access_ok a3, a7, a0, a2, .Leac # a0: scratch reg, a2: sp |
1003 | 1005 | ||
1004 | addi a6, a6, -1 # assuming SYS_XTENSA_ATOMIC_SET = 1 | 1006 | _bgeui a6, SYS_XTENSA_COUNT, .Lill |
1005 | _bgeui a6, SYS_XTENSA_COUNT - 1, .Lill | 1007 | _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP, .Lnswp |
1006 | _bnei a6, SYS_XTENSA_ATOMIC_CMP_SWP - 1, .Lnswp | ||
1007 | 1008 | ||
1008 | /* Fall through for ATOMIC_CMP_SWP. */ | 1009 | /* Fall through for ATOMIC_CMP_SWP. */ |
1009 | 1010 | ||
@@ -1015,27 +1016,26 @@ TRY s32i a5, a3, 0 # different, modify value | |||
1015 | l32i a7, a2, PT_AREG7 # restore a7 | 1016 | l32i a7, a2, PT_AREG7 # restore a7 |
1016 | l32i a0, a2, PT_AREG0 # restore a0 | 1017 | l32i a0, a2, PT_AREG0 # restore a0 |
1017 | movi a2, 1 # and return 1 | 1018 | movi a2, 1 # and return 1 |
1018 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1019 | rfe | 1019 | rfe |
1020 | 1020 | ||
1021 | 1: l32i a7, a2, PT_AREG7 # restore a7 | 1021 | 1: l32i a7, a2, PT_AREG7 # restore a7 |
1022 | l32i a0, a2, PT_AREG0 # restore a0 | 1022 | l32i a0, a2, PT_AREG0 # restore a0 |
1023 | movi a2, 0 # return 0 (note that we cannot set | 1023 | movi a2, 0 # return 0 (note that we cannot set |
1024 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1025 | rfe | 1024 | rfe |
1026 | 1025 | ||
1027 | .Lnswp: /* Atomic set, add, and exg_add. */ | 1026 | .Lnswp: /* Atomic set, add, and exg_add. */ |
1028 | 1027 | ||
1029 | TRY l32i a7, a3, 0 # orig | 1028 | TRY l32i a7, a3, 0 # orig |
1029 | addi a6, a6, -SYS_XTENSA_ATOMIC_SET | ||
1030 | add a0, a4, a7 # + arg | 1030 | add a0, a4, a7 # + arg |
1031 | moveqz a0, a4, a6 # set | 1031 | moveqz a0, a4, a6 # set |
1032 | addi a6, a6, SYS_XTENSA_ATOMIC_SET | ||
1032 | TRY s32i a0, a3, 0 # write new value | 1033 | TRY s32i a0, a3, 0 # write new value |
1033 | 1034 | ||
1034 | mov a0, a2 | 1035 | mov a0, a2 |
1035 | mov a2, a7 | 1036 | mov a2, a7 |
1036 | l32i a7, a0, PT_AREG7 # restore a7 | 1037 | l32i a7, a0, PT_AREG7 # restore a7 |
1037 | l32i a0, a0, PT_AREG0 # restore a0 | 1038 | l32i a0, a0, PT_AREG0 # restore a0 |
1038 | addi a6, a6, 1 # restore a6 (really necessary?) | ||
1039 | rfe | 1039 | rfe |
1040 | 1040 | ||
1041 | CATCH | 1041 | CATCH |
@@ -1044,13 +1044,25 @@ CATCH | |||
1044 | movi a2, -EFAULT | 1044 | movi a2, -EFAULT |
1045 | rfe | 1045 | rfe |
1046 | 1046 | ||
1047 | .Lill: l32i a7, a2, PT_AREG0 # restore a7 | 1047 | .Lill: l32i a7, a2, PT_AREG7 # restore a7 |
1048 | l32i a0, a2, PT_AREG0 # restore a0 | 1048 | l32i a0, a2, PT_AREG0 # restore a0 |
1049 | movi a2, -EINVAL | 1049 | movi a2, -EINVAL |
1050 | rfe | 1050 | rfe |
1051 | 1051 | ||
1052 | ENDPROC(fast_syscall_xtensa) | 1052 | ENDPROC(fast_syscall_xtensa) |
1053 | 1053 | ||
1054 | #else /* CONFIG_FAST_SYSCALL_XTENSA */ | ||
1055 | |||
1056 | ENTRY(fast_syscall_xtensa) | ||
1057 | |||
1058 | l32i a0, a2, PT_AREG0 # restore a0 | ||
1059 | movi a2, -ENOSYS | ||
1060 | rfe | ||
1061 | |||
1062 | ENDPROC(fast_syscall_xtensa) | ||
1063 | |||
1064 | #endif /* CONFIG_FAST_SYSCALL_XTENSA */ | ||
1065 | |||
1054 | 1066 | ||
1055 | /* fast_syscall_spill_registers. | 1067 | /* fast_syscall_spill_registers. |
1056 | * | 1068 | * |
@@ -1066,6 +1078,8 @@ ENDPROC(fast_syscall_xtensa) | |||
1066 | * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. | 1078 | * Note: We assume the stack pointer is EXC_TABLE_KSTK in the fixup handler. |
1067 | */ | 1079 | */ |
1068 | 1080 | ||
1081 | #ifdef CONFIG_FAST_SYSCALL_SPILL_REGISTERS | ||
1082 | |||
1069 | ENTRY(fast_syscall_spill_registers) | 1083 | ENTRY(fast_syscall_spill_registers) |
1070 | 1084 | ||
1071 | /* Register a FIXUP handler (pass current wb as a parameter) */ | 1085 | /* Register a FIXUP handler (pass current wb as a parameter) */ |
@@ -1400,6 +1414,18 @@ ENTRY(fast_syscall_spill_registers_fixup_return) | |||
1400 | 1414 | ||
1401 | ENDPROC(fast_syscall_spill_registers_fixup_return) | 1415 | ENDPROC(fast_syscall_spill_registers_fixup_return) |
1402 | 1416 | ||
1417 | #else /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */ | ||
1418 | |||
1419 | ENTRY(fast_syscall_spill_registers) | ||
1420 | |||
1421 | l32i a0, a2, PT_AREG0 # restore a0 | ||
1422 | movi a2, -ENOSYS | ||
1423 | rfe | ||
1424 | |||
1425 | ENDPROC(fast_syscall_spill_registers) | ||
1426 | |||
1427 | #endif /* CONFIG_FAST_SYSCALL_SPILL_REGISTERS */ | ||
1428 | |||
1403 | #ifdef CONFIG_MMU | 1429 | #ifdef CONFIG_MMU |
1404 | /* | 1430 | /* |
1405 | * We should never get here. Bail out! | 1431 | * We should never get here. Bail out! |
@@ -1565,7 +1591,7 @@ ENTRY(fast_second_level_miss) | |||
1565 | rsr a0, excvaddr | 1591 | rsr a0, excvaddr |
1566 | bltu a0, a3, 2f | 1592 | bltu a0, a3, 2f |
1567 | 1593 | ||
1568 | addi a1, a0, -(2 << (DCACHE_ALIAS_ORDER + PAGE_SHIFT)) | 1594 | addi a1, a0, -TLBTEMP_SIZE |
1569 | bgeu a1, a3, 2f | 1595 | bgeu a1, a3, 2f |
1570 | 1596 | ||
1571 | /* Check if we have to restore an ITLB mapping. */ | 1597 | /* Check if we have to restore an ITLB mapping. */ |
@@ -1820,7 +1846,6 @@ ENTRY(_switch_to) | |||
1820 | 1846 | ||
1821 | entry a1, 16 | 1847 | entry a1, 16 |
1822 | 1848 | ||
1823 | mov a10, a2 # preserve 'prev' (a2) | ||
1824 | mov a11, a3 # and 'next' (a3) | 1849 | mov a11, a3 # and 'next' (a3) |
1825 | 1850 | ||
1826 | l32i a4, a2, TASK_THREAD_INFO | 1851 | l32i a4, a2, TASK_THREAD_INFO |
@@ -1828,8 +1853,14 @@ ENTRY(_switch_to) | |||
1828 | 1853 | ||
1829 | save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER | 1854 | save_xtregs_user a4 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
1830 | 1855 | ||
1831 | s32i a0, a10, THREAD_RA # save return address | 1856 | #if THREAD_RA > 1020 || THREAD_SP > 1020 |
1832 | s32i a1, a10, THREAD_SP # save stack pointer | 1857 | addi a10, a2, TASK_THREAD |
1858 | s32i a0, a10, THREAD_RA - TASK_THREAD # save return address | ||
1859 | s32i a1, a10, THREAD_SP - TASK_THREAD # save stack pointer | ||
1860 | #else | ||
1861 | s32i a0, a2, THREAD_RA # save return address | ||
1862 | s32i a1, a2, THREAD_SP # save stack pointer | ||
1863 | #endif | ||
1833 | 1864 | ||
1834 | /* Disable ints while we manipulate the stack pointer. */ | 1865 | /* Disable ints while we manipulate the stack pointer. */ |
1835 | 1866 | ||
@@ -1870,7 +1901,6 @@ ENTRY(_switch_to) | |||
1870 | load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER | 1901 | load_xtregs_user a5 a6 a8 a9 a12 a13 THREAD_XTREGS_USER |
1871 | 1902 | ||
1872 | wsr a14, ps | 1903 | wsr a14, ps |
1873 | mov a2, a10 # return 'prev' | ||
1874 | rsync | 1904 | rsync |
1875 | 1905 | ||
1876 | retw | 1906 | retw |
diff --git a/arch/xtensa/kernel/pci-dma.c b/arch/xtensa/kernel/pci-dma.c index 2d9cc6dbfd78..e8b76b8e4b29 100644 --- a/arch/xtensa/kernel/pci-dma.c +++ b/arch/xtensa/kernel/pci-dma.c | |||
@@ -49,9 +49,8 @@ dma_alloc_coherent(struct device *dev,size_t size,dma_addr_t *handle,gfp_t flag) | |||
49 | 49 | ||
50 | /* We currently don't support coherent memory outside KSEG */ | 50 | /* We currently don't support coherent memory outside KSEG */ |
51 | 51 | ||
52 | if (ret < XCHAL_KSEG_CACHED_VADDR | 52 | BUG_ON(ret < XCHAL_KSEG_CACHED_VADDR || |
53 | || ret >= XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE) | 53 | ret > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1); |
54 | BUG(); | ||
55 | 54 | ||
56 | 55 | ||
57 | if (ret != 0) { | 56 | if (ret != 0) { |
@@ -68,10 +67,11 @@ EXPORT_SYMBOL(dma_alloc_coherent); | |||
68 | void dma_free_coherent(struct device *hwdev, size_t size, | 67 | void dma_free_coherent(struct device *hwdev, size_t size, |
69 | void *vaddr, dma_addr_t dma_handle) | 68 | void *vaddr, dma_addr_t dma_handle) |
70 | { | 69 | { |
71 | long addr=(long)vaddr+XCHAL_KSEG_CACHED_VADDR-XCHAL_KSEG_BYPASS_VADDR; | 70 | unsigned long addr = (unsigned long)vaddr + |
71 | XCHAL_KSEG_CACHED_VADDR - XCHAL_KSEG_BYPASS_VADDR; | ||
72 | 72 | ||
73 | if (addr < 0 || addr >= XCHAL_KSEG_SIZE) | 73 | BUG_ON(addr < XCHAL_KSEG_CACHED_VADDR || |
74 | BUG(); | 74 | addr > XCHAL_KSEG_CACHED_VADDR + XCHAL_KSEG_SIZE - 1); |
75 | 75 | ||
76 | free_pages(addr, get_order(size)); | 76 | free_pages(addr, get_order(size)); |
77 | } | 77 | } |
diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index eebbfd8c26fc..9d2f45f010ef 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c | |||
@@ -101,9 +101,8 @@ static dispatch_init_table_t __initdata dispatch_init_table[] = { | |||
101 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION | 101 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION |
102 | #ifdef CONFIG_XTENSA_UNALIGNED_USER | 102 | #ifdef CONFIG_XTENSA_UNALIGNED_USER |
103 | { EXCCAUSE_UNALIGNED, USER, fast_unaligned }, | 103 | { EXCCAUSE_UNALIGNED, USER, fast_unaligned }, |
104 | #else | ||
105 | { EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, | ||
106 | #endif | 104 | #endif |
105 | { EXCCAUSE_UNALIGNED, 0, do_unaligned_user }, | ||
107 | { EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, | 106 | { EXCCAUSE_UNALIGNED, KRNL, fast_unaligned }, |
108 | #endif | 107 | #endif |
109 | #ifdef CONFIG_MMU | 108 | #ifdef CONFIG_MMU |
@@ -264,7 +263,6 @@ do_illegal_instruction(struct pt_regs *regs) | |||
264 | */ | 263 | */ |
265 | 264 | ||
266 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION | 265 | #if XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION |
267 | #ifndef CONFIG_XTENSA_UNALIGNED_USER | ||
268 | void | 266 | void |
269 | do_unaligned_user (struct pt_regs *regs) | 267 | do_unaligned_user (struct pt_regs *regs) |
270 | { | 268 | { |
@@ -286,7 +284,6 @@ do_unaligned_user (struct pt_regs *regs) | |||
286 | 284 | ||
287 | } | 285 | } |
288 | #endif | 286 | #endif |
289 | #endif | ||
290 | 287 | ||
291 | void | 288 | void |
292 | do_debug(struct pt_regs *regs) | 289 | do_debug(struct pt_regs *regs) |
diff --git a/arch/xtensa/kernel/vectors.S b/arch/xtensa/kernel/vectors.S index 8453e6e39895..1b397a902292 100644 --- a/arch/xtensa/kernel/vectors.S +++ b/arch/xtensa/kernel/vectors.S | |||
@@ -454,8 +454,14 @@ _DoubleExceptionVector_WindowOverflow: | |||
454 | s32i a0, a2, PT_DEPC | 454 | s32i a0, a2, PT_DEPC |
455 | 455 | ||
456 | _DoubleExceptionVector_handle_exception: | 456 | _DoubleExceptionVector_handle_exception: |
457 | addi a0, a0, -EXCCAUSE_UNALIGNED | ||
458 | beqz a0, 2f | ||
457 | addx4 a0, a0, a3 | 459 | addx4 a0, a0, a3 |
458 | l32i a0, a0, EXC_TABLE_FAST_USER | 460 | l32i a0, a0, EXC_TABLE_FAST_USER + 4 * EXCCAUSE_UNALIGNED |
461 | xsr a3, excsave1 | ||
462 | jx a0 | ||
463 | 2: | ||
464 | movi a0, user_exception | ||
459 | xsr a3, excsave1 | 465 | xsr a3, excsave1 |
460 | jx a0 | 466 | jx a0 |
461 | 467 | ||
diff --git a/arch/xtensa/kernel/vmlinux.lds.S b/arch/xtensa/kernel/vmlinux.lds.S index d16db6df86f8..fc1bc2ba8d5d 100644 --- a/arch/xtensa/kernel/vmlinux.lds.S +++ b/arch/xtensa/kernel/vmlinux.lds.S | |||
@@ -269,13 +269,13 @@ SECTIONS | |||
269 | .UserExceptionVector.literal) | 269 | .UserExceptionVector.literal) |
270 | SECTION_VECTOR (_DoubleExceptionVector_literal, | 270 | SECTION_VECTOR (_DoubleExceptionVector_literal, |
271 | .DoubleExceptionVector.literal, | 271 | .DoubleExceptionVector.literal, |
272 | DOUBLEEXC_VECTOR_VADDR - 40, | 272 | DOUBLEEXC_VECTOR_VADDR - 48, |
273 | SIZEOF(.UserExceptionVector.text), | 273 | SIZEOF(.UserExceptionVector.text), |
274 | .UserExceptionVector.text) | 274 | .UserExceptionVector.text) |
275 | SECTION_VECTOR (_DoubleExceptionVector_text, | 275 | SECTION_VECTOR (_DoubleExceptionVector_text, |
276 | .DoubleExceptionVector.text, | 276 | .DoubleExceptionVector.text, |
277 | DOUBLEEXC_VECTOR_VADDR, | 277 | DOUBLEEXC_VECTOR_VADDR, |
278 | 40, | 278 | 48, |
279 | .DoubleExceptionVector.literal) | 279 | .DoubleExceptionVector.literal) |
280 | 280 | ||
281 | . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; | 281 | . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3; |
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index 63cbb867dadd..d75aa1476da7 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c | |||
@@ -59,9 +59,68 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) | 62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) |
63 | #error "HIGHMEM is not supported on cores with aliasing cache." | 63 | static inline void kmap_invalidate_coherent(struct page *page, |
64 | #endif | 64 | unsigned long vaddr) |
65 | { | ||
66 | if (!DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) { | ||
67 | unsigned long kvaddr; | ||
68 | |||
69 | if (!PageHighMem(page)) { | ||
70 | kvaddr = (unsigned long)page_to_virt(page); | ||
71 | |||
72 | __invalidate_dcache_page(kvaddr); | ||
73 | } else { | ||
74 | kvaddr = TLBTEMP_BASE_1 + | ||
75 | (page_to_phys(page) & DCACHE_ALIAS_MASK); | ||
76 | |||
77 | __invalidate_dcache_page_alias(kvaddr, | ||
78 | page_to_phys(page)); | ||
79 | } | ||
80 | } | ||
81 | } | ||
82 | |||
83 | static inline void *coherent_kvaddr(struct page *page, unsigned long base, | ||
84 | unsigned long vaddr, unsigned long *paddr) | ||
85 | { | ||
86 | if (PageHighMem(page) || !DCACHE_ALIAS_EQ(page_to_phys(page), vaddr)) { | ||
87 | *paddr = page_to_phys(page); | ||
88 | return (void *)(base + (vaddr & DCACHE_ALIAS_MASK)); | ||
89 | } else { | ||
90 | *paddr = 0; | ||
91 | return page_to_virt(page); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | void clear_user_highpage(struct page *page, unsigned long vaddr) | ||
96 | { | ||
97 | unsigned long paddr; | ||
98 | void *kvaddr = coherent_kvaddr(page, TLBTEMP_BASE_1, vaddr, &paddr); | ||
99 | |||
100 | pagefault_disable(); | ||
101 | kmap_invalidate_coherent(page, vaddr); | ||
102 | set_bit(PG_arch_1, &page->flags); | ||
103 | clear_page_alias(kvaddr, paddr); | ||
104 | pagefault_enable(); | ||
105 | } | ||
106 | |||
107 | void copy_user_highpage(struct page *dst, struct page *src, | ||
108 | unsigned long vaddr, struct vm_area_struct *vma) | ||
109 | { | ||
110 | unsigned long dst_paddr, src_paddr; | ||
111 | void *dst_vaddr = coherent_kvaddr(dst, TLBTEMP_BASE_1, vaddr, | ||
112 | &dst_paddr); | ||
113 | void *src_vaddr = coherent_kvaddr(src, TLBTEMP_BASE_2, vaddr, | ||
114 | &src_paddr); | ||
115 | |||
116 | pagefault_disable(); | ||
117 | kmap_invalidate_coherent(dst, vaddr); | ||
118 | set_bit(PG_arch_1, &dst->flags); | ||
119 | copy_page_alias(dst_vaddr, src_vaddr, dst_paddr, src_paddr); | ||
120 | pagefault_enable(); | ||
121 | } | ||
122 | |||
123 | #endif /* DCACHE_WAY_SIZE > PAGE_SIZE */ | ||
65 | 124 | ||
66 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 125 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
67 | 126 | ||
@@ -103,7 +162,8 @@ void flush_dcache_page(struct page *page) | |||
103 | if (!alias && !mapping) | 162 | if (!alias && !mapping) |
104 | return; | 163 | return; |
105 | 164 | ||
106 | __flush_invalidate_dcache_page((long)page_address(page)); | 165 | virt = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); |
166 | __flush_invalidate_dcache_page_alias(virt, phys); | ||
107 | 167 | ||
108 | virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK); | 168 | virt = TLBTEMP_BASE_1 + (temp & DCACHE_ALIAS_MASK); |
109 | 169 | ||
@@ -168,13 +228,12 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
168 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 228 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
169 | 229 | ||
170 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { | 230 | if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { |
171 | |||
172 | unsigned long paddr = (unsigned long) page_address(page); | ||
173 | unsigned long phys = page_to_phys(page); | 231 | unsigned long phys = page_to_phys(page); |
174 | unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | 232 | unsigned long tmp; |
175 | |||
176 | __flush_invalidate_dcache_page(paddr); | ||
177 | 233 | ||
234 | tmp = TLBTEMP_BASE_1 + (phys & DCACHE_ALIAS_MASK); | ||
235 | __flush_invalidate_dcache_page_alias(tmp, phys); | ||
236 | tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); | ||
178 | __flush_invalidate_dcache_page_alias(tmp, phys); | 237 | __flush_invalidate_dcache_page_alias(tmp, phys); |
179 | __invalidate_icache_page_alias(tmp, phys); | 238 | __invalidate_icache_page_alias(tmp, phys); |
180 | 239 | ||
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c index 17a8c0d6fd17..8cfb71ec0937 100644 --- a/arch/xtensa/mm/highmem.c +++ b/arch/xtensa/mm/highmem.c | |||
@@ -14,23 +14,45 @@ | |||
14 | 14 | ||
15 | static pte_t *kmap_pte; | 15 | static pte_t *kmap_pte; |
16 | 16 | ||
17 | #if DCACHE_WAY_SIZE > PAGE_SIZE | ||
18 | unsigned int last_pkmap_nr_arr[DCACHE_N_COLORS]; | ||
19 | wait_queue_head_t pkmap_map_wait_arr[DCACHE_N_COLORS]; | ||
20 | |||
21 | static void __init kmap_waitqueues_init(void) | ||
22 | { | ||
23 | unsigned int i; | ||
24 | |||
25 | for (i = 0; i < ARRAY_SIZE(pkmap_map_wait_arr); ++i) | ||
26 | init_waitqueue_head(pkmap_map_wait_arr + i); | ||
27 | } | ||
28 | #else | ||
29 | static inline void kmap_waitqueues_init(void) | ||
30 | { | ||
31 | } | ||
32 | #endif | ||
33 | |||
34 | static inline enum fixed_addresses kmap_idx(int type, unsigned long color) | ||
35 | { | ||
36 | return (type + KM_TYPE_NR * smp_processor_id()) * DCACHE_N_COLORS + | ||
37 | color; | ||
38 | } | ||
39 | |||
17 | void *kmap_atomic(struct page *page) | 40 | void *kmap_atomic(struct page *page) |
18 | { | 41 | { |
19 | enum fixed_addresses idx; | 42 | enum fixed_addresses idx; |
20 | unsigned long vaddr; | 43 | unsigned long vaddr; |
21 | int type; | ||
22 | 44 | ||
23 | pagefault_disable(); | 45 | pagefault_disable(); |
24 | if (!PageHighMem(page)) | 46 | if (!PageHighMem(page)) |
25 | return page_address(page); | 47 | return page_address(page); |
26 | 48 | ||
27 | type = kmap_atomic_idx_push(); | 49 | idx = kmap_idx(kmap_atomic_idx_push(), |
28 | idx = type + KM_TYPE_NR * smp_processor_id(); | 50 | DCACHE_ALIAS(page_to_phys(page))); |
29 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 51 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
30 | #ifdef CONFIG_DEBUG_HIGHMEM | 52 | #ifdef CONFIG_DEBUG_HIGHMEM |
31 | BUG_ON(!pte_none(*(kmap_pte - idx))); | 53 | BUG_ON(!pte_none(*(kmap_pte + idx))); |
32 | #endif | 54 | #endif |
33 | set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); | 55 | set_pte(kmap_pte + idx, mk_pte(page, PAGE_KERNEL_EXEC)); |
34 | 56 | ||
35 | return (void *)vaddr; | 57 | return (void *)vaddr; |
36 | } | 58 | } |
@@ -38,12 +60,10 @@ EXPORT_SYMBOL(kmap_atomic); | |||
38 | 60 | ||
39 | void __kunmap_atomic(void *kvaddr) | 61 | void __kunmap_atomic(void *kvaddr) |
40 | { | 62 | { |
41 | int idx, type; | ||
42 | |||
43 | if (kvaddr >= (void *)FIXADDR_START && | 63 | if (kvaddr >= (void *)FIXADDR_START && |
44 | kvaddr < (void *)FIXADDR_TOP) { | 64 | kvaddr < (void *)FIXADDR_TOP) { |
45 | type = kmap_atomic_idx(); | 65 | int idx = kmap_idx(kmap_atomic_idx(), |
46 | idx = type + KM_TYPE_NR * smp_processor_id(); | 66 | DCACHE_ALIAS((unsigned long)kvaddr)); |
47 | 67 | ||
48 | /* | 68 | /* |
49 | * Force other mappings to Oops if they'll try to access this | 69 | * Force other mappings to Oops if they'll try to access this |
@@ -51,7 +71,7 @@ void __kunmap_atomic(void *kvaddr) | |||
51 | * is a bad idea also, in case the page changes cacheability | 71 | * is a bad idea also, in case the page changes cacheability |
52 | * attributes or becomes a protected page in a hypervisor. | 72 | * attributes or becomes a protected page in a hypervisor. |
53 | */ | 73 | */ |
54 | pte_clear(&init_mm, kvaddr, kmap_pte - idx); | 74 | pte_clear(&init_mm, kvaddr, kmap_pte + idx); |
55 | local_flush_tlb_kernel_range((unsigned long)kvaddr, | 75 | local_flush_tlb_kernel_range((unsigned long)kvaddr, |
56 | (unsigned long)kvaddr + PAGE_SIZE); | 76 | (unsigned long)kvaddr + PAGE_SIZE); |
57 | 77 | ||
@@ -69,4 +89,5 @@ void __init kmap_init(void) | |||
69 | /* cache the first kmap pte */ | 89 | /* cache the first kmap pte */ |
70 | kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); | 90 | kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); |
71 | kmap_pte = kmap_get_fixmap_pte(kmap_vstart); | 91 | kmap_pte = kmap_get_fixmap_pte(kmap_vstart); |
92 | kmap_waitqueues_init(); | ||
72 | } | 93 | } |
diff --git a/arch/xtensa/mm/misc.S b/arch/xtensa/mm/misc.S index 1f68558dbcc2..11a01c3e9cea 100644 --- a/arch/xtensa/mm/misc.S +++ b/arch/xtensa/mm/misc.S | |||
@@ -110,41 +110,24 @@ ENTRY(__tlbtemp_mapping_start) | |||
110 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) | 110 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) |
111 | 111 | ||
112 | /* | 112 | /* |
113 | * clear_user_page (void *addr, unsigned long vaddr, struct page *page) | 113 | * clear_page_alias(void *addr, unsigned long paddr) |
114 | * a2 a3 a4 | 114 | * a2 a3 |
115 | */ | 115 | */ |
116 | 116 | ||
117 | ENTRY(clear_user_page) | 117 | ENTRY(clear_page_alias) |
118 | 118 | ||
119 | entry a1, 32 | 119 | entry a1, 32 |
120 | 120 | ||
121 | /* Mark page dirty and determine alias. */ | 121 | /* Skip setting up a temporary DTLB if not aliased low page. */ |
122 | 122 | ||
123 | movi a7, (1 << PG_ARCH_1) | 123 | movi a5, PAGE_OFFSET |
124 | l32i a5, a4, PAGE_FLAGS | 124 | movi a6, 0 |
125 | xor a6, a2, a3 | 125 | beqz a3, 1f |
126 | extui a3, a3, PAGE_SHIFT, DCACHE_ALIAS_ORDER | ||
127 | extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER | ||
128 | or a5, a5, a7 | ||
129 | slli a3, a3, PAGE_SHIFT | ||
130 | s32i a5, a4, PAGE_FLAGS | ||
131 | 126 | ||
132 | /* Skip setting up a temporary DTLB if not aliased. */ | 127 | /* Setup a temporary DTLB for the addr. */ |
133 | |||
134 | beqz a6, 1f | ||
135 | |||
136 | /* Invalidate kernel page. */ | ||
137 | |||
138 | mov a10, a2 | ||
139 | call8 __invalidate_dcache_page | ||
140 | |||
141 | /* Setup a temporary DTLB with the color of the VPN */ | ||
142 | |||
143 | movi a4, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff | ||
144 | movi a5, TLBTEMP_BASE_1 # virt | ||
145 | add a6, a2, a4 # ppn | ||
146 | add a2, a5, a3 # add 'color' | ||
147 | 128 | ||
129 | addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) | ||
130 | mov a4, a2 | ||
148 | wdtlb a6, a2 | 131 | wdtlb a6, a2 |
149 | dsync | 132 | dsync |
150 | 133 | ||
@@ -165,62 +148,43 @@ ENTRY(clear_user_page) | |||
165 | 148 | ||
166 | /* We need to invalidate the temporary idtlb entry, if any. */ | 149 | /* We need to invalidate the temporary idtlb entry, if any. */ |
167 | 150 | ||
168 | 1: addi a2, a2, -PAGE_SIZE | 151 | 1: idtlb a4 |
169 | idtlb a2 | ||
170 | dsync | 152 | dsync |
171 | 153 | ||
172 | retw | 154 | retw |
173 | 155 | ||
174 | ENDPROC(clear_user_page) | 156 | ENDPROC(clear_page_alias) |
175 | 157 | ||
176 | /* | 158 | /* |
177 | * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) | 159 | * copy_page_alias(void *to, void *from, |
178 | * a2 a3 a4 a5 | 160 | * a2 a3 |
161 | * unsigned long to_paddr, unsigned long from_paddr) | ||
162 | * a4 a5 | ||
179 | */ | 163 | */ |
180 | 164 | ||
181 | ENTRY(copy_user_page) | 165 | ENTRY(copy_page_alias) |
182 | 166 | ||
183 | entry a1, 32 | 167 | entry a1, 32 |
184 | 168 | ||
185 | /* Mark page dirty and determine alias for destination. */ | 169 | /* Skip setting up a temporary DTLB for destination if not aliased. */ |
186 | |||
187 | movi a8, (1 << PG_ARCH_1) | ||
188 | l32i a9, a5, PAGE_FLAGS | ||
189 | xor a6, a2, a4 | ||
190 | xor a7, a3, a4 | ||
191 | extui a4, a4, PAGE_SHIFT, DCACHE_ALIAS_ORDER | ||
192 | extui a6, a6, PAGE_SHIFT, DCACHE_ALIAS_ORDER | ||
193 | extui a7, a7, PAGE_SHIFT, DCACHE_ALIAS_ORDER | ||
194 | or a9, a9, a8 | ||
195 | slli a4, a4, PAGE_SHIFT | ||
196 | s32i a9, a5, PAGE_FLAGS | ||
197 | movi a5, ((PAGE_KERNEL | _PAGE_HW_WRITE) - PAGE_OFFSET) & 0xffffffff | ||
198 | |||
199 | beqz a6, 1f | ||
200 | |||
201 | /* Invalidate dcache */ | ||
202 | |||
203 | mov a10, a2 | ||
204 | call8 __invalidate_dcache_page | ||
205 | 170 | ||
206 | /* Setup a temporary DTLB with a matching color. */ | 171 | movi a6, 0 |
172 | movi a7, 0 | ||
173 | beqz a4, 1f | ||
207 | 174 | ||
208 | movi a8, TLBTEMP_BASE_1 # base | 175 | /* Setup a temporary DTLB for destination. */ |
209 | add a6, a2, a5 # ppn | ||
210 | add a2, a8, a4 # add 'color' | ||
211 | 176 | ||
177 | addi a6, a4, (PAGE_KERNEL | _PAGE_HW_WRITE) | ||
212 | wdtlb a6, a2 | 178 | wdtlb a6, a2 |
213 | dsync | 179 | dsync |
214 | 180 | ||
215 | /* Skip setting up a temporary DTLB for destination if not aliased. */ | 181 | /* Skip setting up a temporary DTLB for source if not aliased. */ |
216 | 182 | ||
217 | 1: beqz a7, 1f | 183 | 1: beqz a5, 1f |
218 | 184 | ||
219 | /* Setup a temporary DTLB with a matching color. */ | 185 | /* Setup a temporary DTLB for source. */ |
220 | 186 | ||
221 | movi a8, TLBTEMP_BASE_2 # base | 187 | addi a7, a5, PAGE_KERNEL |
222 | add a7, a3, a5 # ppn | ||
223 | add a3, a8, a4 | ||
224 | addi a8, a3, 1 # way1 | 188 | addi a8, a3, 1 # way1 |
225 | 189 | ||
226 | wdtlb a7, a8 | 190 | wdtlb a7, a8 |
@@ -271,7 +235,7 @@ ENTRY(copy_user_page) | |||
271 | 235 | ||
272 | retw | 236 | retw |
273 | 237 | ||
274 | ENDPROC(copy_user_page) | 238 | ENDPROC(copy_page_alias) |
275 | 239 | ||
276 | #endif | 240 | #endif |
277 | 241 | ||
@@ -300,6 +264,30 @@ ENTRY(__flush_invalidate_dcache_page_alias) | |||
300 | retw | 264 | retw |
301 | 265 | ||
302 | ENDPROC(__flush_invalidate_dcache_page_alias) | 266 | ENDPROC(__flush_invalidate_dcache_page_alias) |
267 | |||
268 | /* | ||
269 | * void __invalidate_dcache_page_alias (addr, phys) | ||
270 | * a2 a3 | ||
271 | */ | ||
272 | |||
273 | ENTRY(__invalidate_dcache_page_alias) | ||
274 | |||
275 | entry sp, 16 | ||
276 | |||
277 | movi a7, 0 # required for exception handler | ||
278 | addi a6, a3, (PAGE_KERNEL | _PAGE_HW_WRITE) | ||
279 | mov a4, a2 | ||
280 | wdtlb a6, a2 | ||
281 | dsync | ||
282 | |||
283 | ___invalidate_dcache_page a2 a3 | ||
284 | |||
285 | idtlb a4 | ||
286 | dsync | ||
287 | |||
288 | retw | ||
289 | |||
290 | ENDPROC(__invalidate_dcache_page_alias) | ||
303 | #endif | 291 | #endif |
304 | 292 | ||
305 | ENTRY(__tlbtemp_mapping_itlb) | 293 | ENTRY(__tlbtemp_mapping_itlb) |
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 3429b483d9f8..abe4513eb0dd 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -18,32 +18,38 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | 19 | ||
20 | #if defined(CONFIG_HIGHMEM) | 20 | #if defined(CONFIG_HIGHMEM) |
21 | static void * __init init_pmd(unsigned long vaddr) | 21 | static void * __init init_pmd(unsigned long vaddr, unsigned long n_pages) |
22 | { | 22 | { |
23 | pgd_t *pgd = pgd_offset_k(vaddr); | 23 | pgd_t *pgd = pgd_offset_k(vaddr); |
24 | pmd_t *pmd = pmd_offset(pgd, vaddr); | 24 | pmd_t *pmd = pmd_offset(pgd, vaddr); |
25 | pte_t *pte; | ||
26 | unsigned long i; | ||
25 | 27 | ||
26 | if (pmd_none(*pmd)) { | 28 | n_pages = ALIGN(n_pages, PTRS_PER_PTE); |
27 | unsigned i; | ||
28 | pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); | ||
29 | 29 | ||
30 | for (i = 0; i < 1024; i++) | 30 | pr_debug("%s: vaddr: 0x%08lx, n_pages: %ld\n", |
31 | pte_clear(NULL, 0, pte + i); | 31 | __func__, vaddr, n_pages); |
32 | 32 | ||
33 | set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); | 33 | pte = alloc_bootmem_low_pages(n_pages * sizeof(pte_t)); |
34 | BUG_ON(pte != pte_offset_kernel(pmd, 0)); | 34 | |
35 | pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", | 35 | for (i = 0; i < n_pages; ++i) |
36 | __func__, vaddr, pmd, pte); | 36 | pte_clear(NULL, 0, pte + i); |
37 | return pte; | 37 | |
38 | } else { | 38 | for (i = 0; i < n_pages; i += PTRS_PER_PTE, ++pmd) { |
39 | return pte_offset_kernel(pmd, 0); | 39 | pte_t *cur_pte = pte + i; |
40 | |||
41 | BUG_ON(!pmd_none(*pmd)); | ||
42 | set_pmd(pmd, __pmd(((unsigned long)cur_pte) & PAGE_MASK)); | ||
43 | BUG_ON(cur_pte != pte_offset_kernel(pmd, 0)); | ||
44 | pr_debug("%s: pmd: 0x%p, pte: 0x%p\n", | ||
45 | __func__, pmd, cur_pte); | ||
40 | } | 46 | } |
47 | return pte; | ||
41 | } | 48 | } |
42 | 49 | ||
43 | static void __init fixedrange_init(void) | 50 | static void __init fixedrange_init(void) |
44 | { | 51 | { |
45 | BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); | 52 | init_pmd(__fix_to_virt(0), __end_of_fixed_addresses); |
46 | init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); | ||
47 | } | 53 | } |
48 | #endif | 54 | #endif |
49 | 55 | ||
@@ -52,7 +58,7 @@ void __init paging_init(void) | |||
52 | memset(swapper_pg_dir, 0, PAGE_SIZE); | 58 | memset(swapper_pg_dir, 0, PAGE_SIZE); |
53 | #ifdef CONFIG_HIGHMEM | 59 | #ifdef CONFIG_HIGHMEM |
54 | fixedrange_init(); | 60 | fixedrange_init(); |
55 | pkmap_page_table = init_pmd(PKMAP_BASE); | 61 | pkmap_page_table = init_pmd(PKMAP_BASE, LAST_PKMAP); |
56 | kmap_init(); | 62 | kmap_init(); |
57 | #endif | 63 | #endif |
58 | } | 64 | } |