aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:30:33 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:30:33 -0400
commitd4d1cda6ef48a99dee5c0f3334a556845e84dd92 (patch)
treebac31a64294592e718226e9f7231c9a9bf490cd9 /arch/xtensa
parent7728f036adb25f8f7f8e36ffa9cecf6ba3ddae91 (diff)
parent0eb5afb3bae69a18bb4a8dbcbd361c4403fb54cd (diff)
Merge tag 'xtensa-next-20130710' of git://github.com/czankel/xtensa-linux
Pull Xtensa updates from Chris Zankel. * tag 'xtensa-next-20130710' of git://github.com/czankel/xtensa-linux: (22 commits) xtensa: remove the second argument of __bio_kmap_atomic() xtensa: add static function tracer support xtensa: Flat DeviceTree copy not future-safe xtensa: check TLB sanity on return to userspace xtensa: adjust boot parameters address when INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is selected xtensa: bootparams: fix typo xtensa: tell git to ignore generated .dtb files xtensa: ccount based sched_clock xtensa: ccount based clockevent implementation xtensa: consolidate ccount access routines xtensa: cleanup ccount frequency tracking xtensa: timex.h: remove unused symbols xtensa: tell git to ignore copied zlib source files xtensa: fix section mismatch in pcibios_fixup_bus xtensa: ISS: fix section mismatch in iss_net_setup arch: xtensa: include: asm: compiling issue, need cmpxchg64() defined. xtensa: xtfpga: fix section mismatch xtensa: remove unused platform_init_irq() xtensa: tell git to ignore generated files xtensa: flush TLB entries for pages of non-current mm correctly ...
Diffstat (limited to 'arch/xtensa')
-rw-r--r--arch/xtensa/Kconfig3
-rw-r--r--arch/xtensa/Kconfig.debug10
-rw-r--r--arch/xtensa/boot/.gitignore3
-rw-r--r--arch/xtensa/boot/boot-elf/.gitignore1
-rw-r--r--arch/xtensa/boot/lib/.gitignore3
-rw-r--r--arch/xtensa/boot/lib/Makefile7
-rw-r--r--arch/xtensa/include/asm/bootparam.h2
-rw-r--r--arch/xtensa/include/asm/cmpxchg.h1
-rw-r--r--arch/xtensa/include/asm/delay.h13
-rw-r--r--arch/xtensa/include/asm/ftrace.h17
-rw-r--r--arch/xtensa/include/asm/pgtable.h140
-rw-r--r--arch/xtensa/include/asm/platform.h5
-rw-r--r--arch/xtensa/include/asm/timex.h12
-rw-r--r--arch/xtensa/kernel/.gitignore1
-rw-r--r--arch/xtensa/kernel/Makefile1
-rw-r--r--arch/xtensa/kernel/entry.S16
-rw-r--r--arch/xtensa/kernel/head.S9
-rw-r--r--arch/xtensa/kernel/mcount.S50
-rw-r--r--arch/xtensa/kernel/pci.c10
-rw-r--r--arch/xtensa/kernel/platform.c3
-rw-r--r--arch/xtensa/kernel/setup.c8
-rw-r--r--arch/xtensa/kernel/time.c123
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c4
-rw-r--r--arch/xtensa/mm/tlb.c120
-rw-r--r--arch/xtensa/platforms/iss/network.c2
-rw-r--r--arch/xtensa/platforms/iss/simdisk.c4
-rw-r--r--arch/xtensa/platforms/xtfpga/setup.c5
-rw-r--r--arch/xtensa/variants/s6000/delay.c6
28 files changed, 433 insertions, 146 deletions
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 0a1b95f81a32..7ea6451a3a33 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -6,10 +6,12 @@ config XTENSA
6 select ARCH_WANT_FRAME_POINTERS 6 select ARCH_WANT_FRAME_POINTERS
7 select HAVE_IDE 7 select HAVE_IDE
8 select GENERIC_ATOMIC64 8 select GENERIC_ATOMIC64
9 select GENERIC_CLOCKEVENTS
9 select HAVE_GENERIC_HARDIRQS 10 select HAVE_GENERIC_HARDIRQS
10 select VIRT_TO_BUS 11 select VIRT_TO_BUS
11 select GENERIC_IRQ_SHOW 12 select GENERIC_IRQ_SHOW
12 select GENERIC_CPU_DEVICES 13 select GENERIC_CPU_DEVICES
14 select GENERIC_SCHED_CLOCK
13 select MODULES_USE_ELF_RELA 15 select MODULES_USE_ELF_RELA
14 select GENERIC_PCI_IOMAP 16 select GENERIC_PCI_IOMAP
15 select ARCH_WANT_IPC_PARSE_VERSION 17 select ARCH_WANT_IPC_PARSE_VERSION
@@ -17,6 +19,7 @@ config XTENSA
17 select CLONE_BACKWARDS 19 select CLONE_BACKWARDS
18 select IRQ_DOMAIN 20 select IRQ_DOMAIN
19 select HAVE_OPROFILE 21 select HAVE_OPROFILE
22 select HAVE_FUNCTION_TRACER
20 help 23 help
21 Xtensa processors are 32-bit RISC machines designed by Tensilica 24 Xtensa processors are 32-bit RISC machines designed by Tensilica
22 primarily for embedded systems. These processors are both 25 primarily for embedded systems. These processors are both
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug
index a34010e0e51c..af7da74d535f 100644
--- a/arch/xtensa/Kconfig.debug
+++ b/arch/xtensa/Kconfig.debug
@@ -2,6 +2,16 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config DEBUG_TLB_SANITY
6 bool "Debug TLB sanity"
7 depends on DEBUG_KERNEL
8 help
9 Enable this to turn on TLB sanity check on each entry to userspace.
10 This check can spot missing TLB invalidation/wrong PTE permissions/
11 premature page freeing.
12
13 If unsure, say N.
14
5config LD_NO_RELAX 15config LD_NO_RELAX
6 bool "Disable linker relaxation" 16 bool "Disable linker relaxation"
7 default n 17 default n
diff --git a/arch/xtensa/boot/.gitignore b/arch/xtensa/boot/.gitignore
new file mode 100644
index 000000000000..be7655998b26
--- /dev/null
+++ b/arch/xtensa/boot/.gitignore
@@ -0,0 +1,3 @@
1uImage
2zImage.redboot
3*.dtb
diff --git a/arch/xtensa/boot/boot-elf/.gitignore b/arch/xtensa/boot/boot-elf/.gitignore
new file mode 100644
index 000000000000..5ff8fbb8561b
--- /dev/null
+++ b/arch/xtensa/boot/boot-elf/.gitignore
@@ -0,0 +1 @@
boot.lds
diff --git a/arch/xtensa/boot/lib/.gitignore b/arch/xtensa/boot/lib/.gitignore
new file mode 100644
index 000000000000..1629a6167755
--- /dev/null
+++ b/arch/xtensa/boot/lib/.gitignore
@@ -0,0 +1,3 @@
1inffast.c
2inflate.c
3inftrees.c
diff --git a/arch/xtensa/boot/lib/Makefile b/arch/xtensa/boot/lib/Makefile
index ad8952e8a07f..6868f2ca6af8 100644
--- a/arch/xtensa/boot/lib/Makefile
+++ b/arch/xtensa/boot/lib/Makefile
@@ -7,6 +7,13 @@ zlib := inffast.c inflate.c inftrees.c
7lib-y += $(zlib:.c=.o) zmem.o 7lib-y += $(zlib:.c=.o) zmem.o
8 8
9ccflags-y := -Ilib/zlib_inflate 9ccflags-y := -Ilib/zlib_inflate
10ifdef CONFIG_FUNCTION_TRACER
11CFLAGS_REMOVE_inflate.o = -pg
12CFLAGS_REMOVE_zmem.o = -pg
13CFLAGS_REMOVE_inftrees.o = -pg
14CFLAGS_REMOVE_inffast.o = -pg
15endif
16
10 17
11quiet_cmd_copy_zlib = COPY $@ 18quiet_cmd_copy_zlib = COPY $@
12 cmd_copy_zlib = cat $< > $@ 19 cmd_copy_zlib = cat $< > $@
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h
index 0c25799facab..23392c5630ce 100644
--- a/arch/xtensa/include/asm/bootparam.h
+++ b/arch/xtensa/include/asm/bootparam.h
@@ -20,7 +20,7 @@
20#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/ 20#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/
21#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */ 21#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */
22#define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ 22#define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */
23#define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ 23#define BP_TAG_SERIAL_BAUDRATE 0x1004 /* baud rate of current console. */
24#define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ 24#define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */
25#define BP_TAG_FDT 0x1006 /* flat device tree addr */ 25#define BP_TAG_FDT 0x1006 /* flat device tree addr */
26 26
diff --git a/arch/xtensa/include/asm/cmpxchg.h b/arch/xtensa/include/asm/cmpxchg.h
index d9ab131bc1aa..370b26f38414 100644
--- a/arch/xtensa/include/asm/cmpxchg.h
+++ b/arch/xtensa/include/asm/cmpxchg.h
@@ -93,6 +93,7 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr,
93 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\ 93 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
94 (unsigned long)(n), sizeof(*(ptr)))) 94 (unsigned long)(n), sizeof(*(ptr))))
95#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) 95#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
96#define cmpxchg64(ptr, o, n) cmpxchg64_local((ptr), (o), (n))
96 97
97/* 98/*
98 * xchg_u32 99 * xchg_u32
diff --git a/arch/xtensa/include/asm/delay.h b/arch/xtensa/include/asm/delay.h
index 61fc5faeb46c..3899610c1dff 100644
--- a/arch/xtensa/include/asm/delay.h
+++ b/arch/xtensa/include/asm/delay.h
@@ -12,7 +12,7 @@
12#ifndef _XTENSA_DELAY_H 12#ifndef _XTENSA_DELAY_H
13#define _XTENSA_DELAY_H 13#define _XTENSA_DELAY_H
14 14
15#include <asm/processor.h> 15#include <asm/timex.h>
16#include <asm/param.h> 16#include <asm/param.h>
17 17
18extern unsigned long loops_per_jiffy; 18extern unsigned long loops_per_jiffy;
@@ -24,24 +24,17 @@ static inline void __delay(unsigned long loops)
24 : "=r" (loops) : "0" (loops)); 24 : "=r" (loops) : "0" (loops));
25} 25}
26 26
27static __inline__ u32 xtensa_get_ccount(void)
28{
29 u32 ccount;
30 asm volatile ("rsr %0, ccount\n" : "=r" (ccount));
31 return ccount;
32}
33
34/* For SMP/NUMA systems, change boot_cpu_data to something like 27/* For SMP/NUMA systems, change boot_cpu_data to something like
35 * local_cpu_data->... where local_cpu_data points to the current 28 * local_cpu_data->... where local_cpu_data points to the current
36 * cpu. */ 29 * cpu. */
37 30
38static __inline__ void udelay (unsigned long usecs) 31static __inline__ void udelay (unsigned long usecs)
39{ 32{
40 unsigned long start = xtensa_get_ccount(); 33 unsigned long start = get_ccount();
41 unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ)); 34 unsigned long cycles = usecs * (loops_per_jiffy / (1000000UL / HZ));
42 35
43 /* Note: all variables are unsigned (can wrap around)! */ 36 /* Note: all variables are unsigned (can wrap around)! */
44 while (((unsigned long)xtensa_get_ccount()) - start < cycles) 37 while (((unsigned long)get_ccount()) - start < cycles)
45 ; 38 ;
46} 39}
47 40
diff --git a/arch/xtensa/include/asm/ftrace.h b/arch/xtensa/include/asm/ftrace.h
index 36dc7a684397..73cc3f482304 100644
--- a/arch/xtensa/include/asm/ftrace.h
+++ b/arch/xtensa/include/asm/ftrace.h
@@ -13,6 +13,7 @@
13#include <asm/processor.h> 13#include <asm/processor.h>
14 14
15#define HAVE_ARCH_CALLER_ADDR 15#define HAVE_ARCH_CALLER_ADDR
16#ifndef __ASSEMBLY__
16#define CALLER_ADDR0 ({ unsigned long a0, a1; \ 17#define CALLER_ADDR0 ({ unsigned long a0, a1; \
17 __asm__ __volatile__ ( \ 18 __asm__ __volatile__ ( \
18 "mov %0, a0\n" \ 19 "mov %0, a0\n" \
@@ -24,10 +25,22 @@ extern unsigned long return_address(unsigned level);
24#define CALLER_ADDR1 return_address(1) 25#define CALLER_ADDR1 return_address(1)
25#define CALLER_ADDR2 return_address(2) 26#define CALLER_ADDR2 return_address(2)
26#define CALLER_ADDR3 return_address(3) 27#define CALLER_ADDR3 return_address(3)
27#else 28#else /* CONFIG_FRAME_POINTER */
28#define CALLER_ADDR1 (0) 29#define CALLER_ADDR1 (0)
29#define CALLER_ADDR2 (0) 30#define CALLER_ADDR2 (0)
30#define CALLER_ADDR3 (0) 31#define CALLER_ADDR3 (0)
31#endif 32#endif /* CONFIG_FRAME_POINTER */
33#endif /* __ASSEMBLY__ */
34
35#ifdef CONFIG_FUNCTION_TRACER
36
37#define MCOUNT_ADDR ((unsigned long)(_mcount))
38#define MCOUNT_INSN_SIZE 3
39
40#ifndef __ASSEMBLY__
41extern void _mcount(void);
42#define mcount _mcount
43#endif /* __ASSEMBLY__ */
44#endif /* CONFIG_FUNCTION_TRACER */
32 45
33#endif /* _XTENSA_FTRACE_H */ 46#endif /* _XTENSA_FTRACE_H */
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h
index 8f017eb309bd..0fdf5d043f82 100644
--- a/arch/xtensa/include/asm/pgtable.h
+++ b/arch/xtensa/include/asm/pgtable.h
@@ -5,7 +5,7 @@
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * Copyright (C) 2001 - 2007 Tensilica Inc. 8 * Copyright (C) 2001 - 2013 Tensilica Inc.
9 */ 9 */
10 10
11#ifndef _XTENSA_PGTABLE_H 11#ifndef _XTENSA_PGTABLE_H
@@ -64,41 +64,82 @@
64 * Virtual memory area. We keep a distance to other memory regions to be 64 * Virtual memory area. We keep a distance to other memory regions to be
65 * on the safe side. We also use this area for cache aliasing. 65 * on the safe side. We also use this area for cache aliasing.
66 */ 66 */
67
68#define VMALLOC_START 0xC0000000 67#define VMALLOC_START 0xC0000000
69#define VMALLOC_END 0xC7FEFFFF 68#define VMALLOC_END 0xC7FEFFFF
70#define TLBTEMP_BASE_1 0xC7FF0000 69#define TLBTEMP_BASE_1 0xC7FF0000
71#define TLBTEMP_BASE_2 0xC7FF8000 70#define TLBTEMP_BASE_2 0xC7FF8000
72 71
73/* 72/*
74 * Xtensa Linux config PTE layout (when present): 73 * For the Xtensa architecture, the PTE layout is as follows:
75 * 31-12: PPN 74 *
76 * 11-6: Software 75 * 31------12 11 10-9 8-6 5-4 3-2 1-0
77 * 5-4: RING 76 * +-----------------------------------------+
78 * 3-0: CA 77 * | | Software | HARDWARE |
78 * | PPN | ADW | RI |Attribute|
79 * +-----------------------------------------+
80 * pte_none | MBZ | 01 | 11 | 00 |
81 * +-----------------------------------------+
82 * present | PPN | 0 | 00 | ADW | RI | CA | wx |
83 * +- - - - - - - - - - - - - - - - - - - - -+
84 * (PAGE_NONE)| PPN | 0 | 00 | ADW | 01 | 11 | 11 |
85 * +-----------------------------------------+
86 * swap | index | type | 01 | 11 | 00 |
87 * +- - - - - - - - - - - - - - - - - - - - -+
88 * file | file offset | 01 | 11 | 10 |
89 * +-----------------------------------------+
90 *
91 * For T1050 hardware and earlier the layout differs for present and (PAGE_NONE)
92 * +-----------------------------------------+
93 * present | PPN | 0 | 00 | ADW | RI | CA | w1 |
94 * +-----------------------------------------+
95 * (PAGE_NONE)| PPN | 0 | 00 | ADW | 01 | 01 | 00 |
96 * +-----------------------------------------+
79 * 97 *
80 * Similar to the Alpha and MIPS ports, we need to keep track of the ref 98 * Legend:
81 * and mod bits in software. We have a software "you can read 99 * PPN Physical Page Number
82 * from this page" bit, and a hardware one which actually lets the 100 * ADW software: accessed (young) / dirty / writable
83 * process read from the page. On the same token we have a software 101 * RI ring (0=privileged, 1=user, 2 and 3 are unused)
84 * writable bit and the real hardware one which actually lets the 102 * CA cache attribute: 00 bypass, 01 writeback, 10 writethrough
85 * process write to the page. 103 * (11 is invalid and used to mark pages that are not present)
104 * w page is writable (hw)
105 * x page is executable (hw)
106 * index swap offset / PAGE_SIZE (bit 11-31: 21 bits -> 8 GB)
107 * (note that the index is always non-zero)
108 * type swap type (5 bits -> 32 types)
109 * file offset 26-bit offset into the file, in increments of PAGE_SIZE
86 * 110 *
87 * See further below for PTE layout for swapped-out pages. 111 * Notes:
112 * - (PROT_NONE) is a special case of 'present' but causes an exception for
113 * any access (read, write, and execute).
114 * - 'multihit-exception' has the highest priority of all MMU exceptions,
115 * so the ring must be set to 'RING_USER' even for 'non-present' pages.
116 * - on older hardware, the exectuable flag was not supported and
117 * used as a 'valid' flag, so it needs to be always set.
118 * - we need to keep track of certain flags in software (dirty and young)
119 * to do this, we use write exceptions and have a separate software w-flag.
120 * - attribute value 1101 (and 1111 on T1050 and earlier) is reserved
88 */ 121 */
89 122
123#define _PAGE_ATTRIB_MASK 0xf
124
90#define _PAGE_HW_EXEC (1<<0) /* hardware: page is executable */ 125#define _PAGE_HW_EXEC (1<<0) /* hardware: page is executable */
91#define _PAGE_HW_WRITE (1<<1) /* hardware: page is writable */ 126#define _PAGE_HW_WRITE (1<<1) /* hardware: page is writable */
92 127
93#define _PAGE_FILE (1<<1) /* non-linear mapping, if !present */
94#define _PAGE_PROTNONE (3<<0) /* special case for VM_PROT_NONE */
95
96/* None of these cache modes include MP coherency: */
97#define _PAGE_CA_BYPASS (0<<2) /* bypass, non-speculative */ 128#define _PAGE_CA_BYPASS (0<<2) /* bypass, non-speculative */
98#define _PAGE_CA_WB (1<<2) /* write-back */ 129#define _PAGE_CA_WB (1<<2) /* write-back */
99#define _PAGE_CA_WT (2<<2) /* write-through */ 130#define _PAGE_CA_WT (2<<2) /* write-through */
100#define _PAGE_CA_MASK (3<<2) 131#define _PAGE_CA_MASK (3<<2)
101#define _PAGE_INVALID (3<<2) 132#define _PAGE_CA_INVALID (3<<2)
133
134/* We use invalid attribute values to distinguish special pte entries */
135#if XCHAL_HW_VERSION_MAJOR < 2000
136#define _PAGE_HW_VALID 0x01 /* older HW needed this bit set */
137#define _PAGE_NONE 0x04
138#else
139#define _PAGE_HW_VALID 0x00
140#define _PAGE_NONE 0x0f
141#endif
142#define _PAGE_FILE (1<<1) /* file mapped page, only if !present */
102 143
103#define _PAGE_USER (1<<4) /* user access (ring=1) */ 144#define _PAGE_USER (1<<4) /* user access (ring=1) */
104 145
@@ -108,19 +149,12 @@
108#define _PAGE_DIRTY (1<<7) /* software: page dirty */ 149#define _PAGE_DIRTY (1<<7) /* software: page dirty */
109#define _PAGE_ACCESSED (1<<8) /* software: page accessed (read) */ 150#define _PAGE_ACCESSED (1<<8) /* software: page accessed (read) */
110 151
111/* On older HW revisions, we always have to set bit 0 */
112#if XCHAL_HW_VERSION_MAJOR < 2000
113# define _PAGE_VALID (1<<0)
114#else
115# define _PAGE_VALID 0
116#endif
117
118#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
119#define _PAGE_PRESENT (_PAGE_VALID | _PAGE_CA_WB | _PAGE_ACCESSED)
120
121#ifdef CONFIG_MMU 152#ifdef CONFIG_MMU
122 153
123#define PAGE_NONE __pgprot(_PAGE_INVALID | _PAGE_USER | _PAGE_PROTNONE) 154#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
155#define _PAGE_PRESENT (_PAGE_HW_VALID | _PAGE_CA_WB | _PAGE_ACCESSED)
156
157#define PAGE_NONE __pgprot(_PAGE_NONE | _PAGE_USER)
124#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER) 158#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER)
125#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_HW_EXEC) 159#define PAGE_COPY_EXEC __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_HW_EXEC)
126#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER) 160#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER)
@@ -132,9 +166,9 @@
132#define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC) 166#define PAGE_KERNEL_EXEC __pgprot(_PAGE_PRESENT|_PAGE_HW_WRITE|_PAGE_HW_EXEC)
133 167
134#if (DCACHE_WAY_SIZE > PAGE_SIZE) 168#if (DCACHE_WAY_SIZE > PAGE_SIZE)
135# define _PAGE_DIRECTORY (_PAGE_VALID | _PAGE_ACCESSED) 169# define _PAGE_DIRECTORY (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_BYPASS)
136#else 170#else
137# define _PAGE_DIRECTORY (_PAGE_VALID | _PAGE_ACCESSED | _PAGE_CA_WB) 171# define _PAGE_DIRECTORY (_PAGE_HW_VALID | _PAGE_ACCESSED | _PAGE_CA_WB)
138#endif 172#endif
139 173
140#else /* no mmu */ 174#else /* no mmu */
@@ -202,12 +236,16 @@ static inline void pgtable_cache_init(void) { }
202/* 236/*
203 * pte status. 237 * pte status.
204 */ 238 */
205#define pte_none(pte) (pte_val(pte) == _PAGE_INVALID) 239# define pte_none(pte) (pte_val(pte) == (_PAGE_CA_INVALID | _PAGE_USER))
206#define pte_present(pte) \ 240#if XCHAL_HW_VERSION_MAJOR < 2000
207 (((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_INVALID) \ 241# define pte_present(pte) ((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID)
208 || ((pte_val(pte) & _PAGE_PROTNONE) == _PAGE_PROTNONE)) 242#else
243# define pte_present(pte) \
244 (((pte_val(pte) & _PAGE_CA_MASK) != _PAGE_CA_INVALID) \
245 || ((pte_val(pte) & _PAGE_ATTRIB_MASK) == _PAGE_NONE))
246#endif
209#define pte_clear(mm,addr,ptep) \ 247#define pte_clear(mm,addr,ptep) \
210 do { update_pte(ptep, __pte(_PAGE_INVALID)); } while(0) 248 do { update_pte(ptep, __pte(_PAGE_CA_INVALID | _PAGE_USER)); } while (0)
211 249
212#define pmd_none(pmd) (!pmd_val(pmd)) 250#define pmd_none(pmd) (!pmd_val(pmd))
213#define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK) 251#define pmd_present(pmd) (pmd_val(pmd) & PAGE_MASK)
@@ -328,35 +366,23 @@ ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
328 366
329 367
330/* 368/*
331 * Encode and decode a swap entry. 369 * Encode and decode a swap and file entry.
332 *
333 * Format of swap pte:
334 * bit 0 MBZ
335 * bit 1 page-file (must be zero)
336 * bits 2 - 3 page hw access mode (must be 11: _PAGE_INVALID)
337 * bits 4 - 5 ring protection (must be 01: _PAGE_USER)
338 * bits 6 - 10 swap type (5 bits -> 32 types)
339 * bits 11 - 31 swap offset / PAGE_SIZE (21 bits -> 8GB)
340
341 * Format of file pte:
342 * bit 0 MBZ
343 * bit 1 page-file (must be one: _PAGE_FILE)
344 * bits 2 - 3 page hw access mode (must be 11: _PAGE_INVALID)
345 * bits 4 - 5 ring protection (must be 01: _PAGE_USER)
346 * bits 6 - 31 file offset / PAGE_SIZE
347 */ 370 */
371#define SWP_TYPE_BITS 5
372#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS)
348 373
349#define __swp_type(entry) (((entry).val >> 6) & 0x1f) 374#define __swp_type(entry) (((entry).val >> 6) & 0x1f)
350#define __swp_offset(entry) ((entry).val >> 11) 375#define __swp_offset(entry) ((entry).val >> 11)
351#define __swp_entry(type,offs) \ 376#define __swp_entry(type,offs) \
352 ((swp_entry_t) {((type) << 6) | ((offs) << 11) | _PAGE_INVALID}) 377 ((swp_entry_t){((type) << 6) | ((offs) << 11) | \
378 _PAGE_CA_INVALID | _PAGE_USER})
353#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) 379#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
354#define __swp_entry_to_pte(x) ((pte_t) { (x).val }) 380#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
355 381
356#define PTE_FILE_MAX_BITS 28 382#define PTE_FILE_MAX_BITS 26
357#define pte_to_pgoff(pte) (pte_val(pte) >> 4) 383#define pte_to_pgoff(pte) (pte_val(pte) >> 6)
358#define pgoff_to_pte(off) \ 384#define pgoff_to_pte(off) \
359 ((pte_t) { ((off) << 4) | _PAGE_INVALID | _PAGE_FILE }) 385 ((pte_t) { ((off) << 6) | _PAGE_CA_INVALID | _PAGE_FILE | _PAGE_USER })
360 386
361#endif /* !defined (__ASSEMBLY__) */ 387#endif /* !defined (__ASSEMBLY__) */
362 388
diff --git a/arch/xtensa/include/asm/platform.h b/arch/xtensa/include/asm/platform.h
index ec098b68fb9a..32e98f27ce97 100644
--- a/arch/xtensa/include/asm/platform.h
+++ b/arch/xtensa/include/asm/platform.h
@@ -30,11 +30,6 @@ extern void platform_init(bp_tag_t*);
30extern void platform_setup (char **); 30extern void platform_setup (char **);
31 31
32/* 32/*
33 * platform_init_irq is called from init_IRQ.
34 */
35extern void platform_init_irq (void);
36
37/*
38 * platform_restart is called to restart the system. 33 * platform_restart is called to restart the system.
39 */ 34 */
40extern void platform_restart (void); 35extern void platform_restart (void);
diff --git a/arch/xtensa/include/asm/timex.h b/arch/xtensa/include/asm/timex.h
index 3d35e5d0367e..69f901713fb6 100644
--- a/arch/xtensa/include/asm/timex.h
+++ b/arch/xtensa/include/asm/timex.h
@@ -35,19 +35,11 @@
35# error "Bad timer number for Linux configurations!" 35# error "Bad timer number for Linux configurations!"
36#endif 36#endif
37 37
38#define LINUX_TIMER_MASK (1L << LINUX_TIMER_INT)
39
40#define CLOCK_TICK_RATE 1193180 /* (everyone is using this value) */
41#define CLOCK_TICK_FACTOR 20 /* Factor of both 10^6 and CLOCK_TICK_RATE */
42
43#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT 38#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
44extern unsigned long ccount_per_jiffy; 39extern unsigned long ccount_freq;
45extern unsigned long nsec_per_ccount; 40#define CCOUNT_PER_JIFFY (ccount_freq / HZ)
46#define CCOUNT_PER_JIFFY ccount_per_jiffy
47#define NSEC_PER_CCOUNT nsec_per_ccount
48#else 41#else
49#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ)) 42#define CCOUNT_PER_JIFFY (CONFIG_XTENSA_CPU_CLOCK*(1000000UL/HZ))
50#define NSEC_PER_CCOUNT (1000UL / CONFIG_XTENSA_CPU_CLOCK)
51#endif 43#endif
52 44
53 45
diff --git a/arch/xtensa/kernel/.gitignore b/arch/xtensa/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/xtensa/kernel/.gitignore
@@ -0,0 +1 @@
vmlinux.lds
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 1e7fc87a94bb..f90265ec1ccc 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -11,6 +11,7 @@ obj-y := align.o coprocessor.o entry.o irq.o pci-dma.o platform.o process.o \
11obj-$(CONFIG_KGDB) += xtensa-stub.o 11obj-$(CONFIG_KGDB) += xtensa-stub.o
12obj-$(CONFIG_PCI) += pci.o 12obj-$(CONFIG_PCI) += pci.o
13obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o 13obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
14obj-$(CONFIG_FUNCTION_TRACER) += mcount.o
14 15
15AFLAGS_head.o += -mtext-section-literals 16AFLAGS_head.o += -mtext-section-literals
16 17
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 5082507d5631..9298742f0fd0 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -458,7 +458,7 @@ common_exception_return:
458 458
459 _bbsi.l a4, TIF_NEED_RESCHED, 3f 459 _bbsi.l a4, TIF_NEED_RESCHED, 3f
460 _bbsi.l a4, TIF_NOTIFY_RESUME, 2f 460 _bbsi.l a4, TIF_NOTIFY_RESUME, 2f
461 _bbci.l a4, TIF_SIGPENDING, 4f 461 _bbci.l a4, TIF_SIGPENDING, 5f
462 462
4632: l32i a4, a1, PT_DEPC 4632: l32i a4, a1, PT_DEPC
464 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f 464 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
@@ -476,6 +476,13 @@ common_exception_return:
476 callx4 a4 476 callx4 a4
477 j 1b 477 j 1b
478 478
4795:
480#ifdef CONFIG_DEBUG_TLB_SANITY
481 l32i a4, a1, PT_DEPC
482 bgeui a4, VALID_DOUBLE_EXCEPTION_ADDRESS, 4f
483 movi a4, check_tlb_sanity
484 callx4 a4
485#endif
4794: /* Restore optional registers. */ 4864: /* Restore optional registers. */
480 487
481 load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT 488 load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT
@@ -1792,10 +1799,15 @@ ENTRY(fast_store_prohibited)
1792 l32i a0, a0, 0 1799 l32i a0, a0, 0
1793 beqz a0, 2f 1800 beqz a0, 2f
1794 1801
1795 /* Note that we assume _PAGE_WRITABLE_BIT is only set if pte is valid.*/ 1802 /*
1803 * Note that we test _PAGE_WRITABLE_BIT only if PTE is present
1804 * and is not PAGE_NONE. See pgtable.h for possible PTE layouts.
1805 */
1796 1806
1797 _PTE_OFFSET(a0, a1, a4) 1807 _PTE_OFFSET(a0, a1, a4)
1798 l32i a4, a0, 0 # read pteval 1808 l32i a4, a0, 0 # read pteval
1809 movi a1, _PAGE_CA_INVALID
1810 ball a4, a1, 2f
1799 bbci.l a4, _PAGE_WRITABLE_BIT, 2f 1811 bbci.l a4, _PAGE_WRITABLE_BIT, 2f
1800 1812
1801 movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE 1813 movi a1, _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_HW_WRITE
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index ef12c0e6fa25..7d740ebbe198 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -68,6 +68,15 @@ _SetupMMU:
68 68
69#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX 69#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
70 initialize_mmu 70 initialize_mmu
71#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
72 rsr a2, excsave1
73 movi a3, 0x08000000
74 bgeu a2, a3, 1f
75 movi a3, 0xd0000000
76 add a2, a2, a3
77 wsr a2, excsave1
781:
79#endif
71#endif 80#endif
72 .end no-absolute-literals 81 .end no-absolute-literals
73 82
diff --git a/arch/xtensa/kernel/mcount.S b/arch/xtensa/kernel/mcount.S
new file mode 100644
index 000000000000..0eeda2e4a25e
--- /dev/null
+++ b/arch/xtensa/kernel/mcount.S
@@ -0,0 +1,50 @@
1/*
2 * arch/xtensa/kernel/mcount.S
3 *
4 * Xtensa specific mcount support
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) 2013 Tensilica Inc.
11 */
12
13#include <linux/linkage.h>
14#include <asm/ftrace.h>
15
16/*
17 * Entry condition:
18 *
19 * a2: a0 of the caller
20 */
21
22ENTRY(_mcount)
23
24 entry a1, 16
25
26 movi a4, ftrace_trace_function
27 l32i a4, a4, 0
28 movi a3, ftrace_stub
29 bne a3, a4, 1f
30 retw
31
321: xor a7, a2, a1
33 movi a3, 0x3fffffff
34 and a7, a7, a3
35 xor a7, a7, a1
36
37 xor a6, a0, a1
38 and a6, a6, a3
39 xor a6, a6, a1
40 addi a6, a6, -MCOUNT_INSN_SIZE
41 callx4 a4
42
43 retw
44
45ENDPROC(_mcount)
46
47ENTRY(ftrace_stub)
48 entry a1, 16
49 retw
50ENDPROC(ftrace_stub)
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c
index 126c18839409..5b3403388d7f 100644
--- a/arch/xtensa/kernel/pci.c
+++ b/arch/xtensa/kernel/pci.c
@@ -77,9 +77,9 @@ pcibios_align_resource(void *data, const struct resource *res,
77 77
78 if (res->flags & IORESOURCE_IO) { 78 if (res->flags & IORESOURCE_IO) {
79 if (size > 0x100) { 79 if (size > 0x100) {
80 printk(KERN_ERR "PCI: I/O Region %s/%d too large" 80 pr_err("PCI: I/O Region %s/%d too large (%u bytes)\n",
81 " (%ld bytes)\n", pci_name(dev), 81 pci_name(dev), dev->resource - res,
82 dev->resource - res, size); 82 size);
83 } 83 }
84 84
85 if (start & 0x300) 85 if (start & 0x300)
@@ -174,7 +174,7 @@ static int __init pcibios_init(void)
174 struct pci_controller *pci_ctrl; 174 struct pci_controller *pci_ctrl;
175 struct list_head resources; 175 struct list_head resources;
176 struct pci_bus *bus; 176 struct pci_bus *bus;
177 int next_busno = 0, i; 177 int next_busno = 0;
178 178
179 printk("PCI: Probing PCI hardware\n"); 179 printk("PCI: Probing PCI hardware\n");
180 180
@@ -197,7 +197,7 @@ static int __init pcibios_init(void)
197 197
198subsys_initcall(pcibios_init); 198subsys_initcall(pcibios_init);
199 199
200void __init pcibios_fixup_bus(struct pci_bus *bus) 200void pcibios_fixup_bus(struct pci_bus *bus)
201{ 201{
202 if (bus->parent) { 202 if (bus->parent) {
203 /* This is a subordinate bridge */ 203 /* This is a subordinate bridge */
diff --git a/arch/xtensa/kernel/platform.c b/arch/xtensa/kernel/platform.c
index 2bd6c351f37c..1cf008284dd2 100644
--- a/arch/xtensa/kernel/platform.c
+++ b/arch/xtensa/kernel/platform.c
@@ -29,7 +29,6 @@
29 */ 29 */
30 30
31_F(void, setup, (char** cmd), { }); 31_F(void, setup, (char** cmd), { });
32_F(void, init_irq, (void), { });
33_F(void, restart, (void), { while(1); }); 32_F(void, restart, (void), { while(1); });
34_F(void, halt, (void), { while(1); }); 33_F(void, halt, (void), { while(1); });
35_F(void, power_off, (void), { while(1); }); 34_F(void, power_off, (void), { while(1); });
@@ -42,6 +41,6 @@ _F(void, pcibios_init, (void), { });
42_F(void, calibrate_ccount, (void), 41_F(void, calibrate_ccount, (void),
43{ 42{
44 pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n"); 43 pr_err("ERROR: Cannot calibrate cpu frequency! Assuming 10MHz.\n");
45 ccount_per_jiffy = 10 * (1000000UL/HZ); 44 ccount_freq = 10 * 1000000UL;
46}); 45});
47#endif 46#endif
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 6dd25ecde3f5..42a8bba0b0ea 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -152,8 +152,8 @@ static int __init parse_tag_initrd(const bp_tag_t* tag)
152{ 152{
153 meminfo_t* mi; 153 meminfo_t* mi;
154 mi = (meminfo_t*)(tag->data); 154 mi = (meminfo_t*)(tag->data);
155 initrd_start = (void*)(mi->start); 155 initrd_start = __va(mi->start);
156 initrd_end = (void*)(mi->end); 156 initrd_end = __va(mi->end);
157 157
158 return 0; 158 return 0;
159} 159}
@@ -164,7 +164,7 @@ __tagtable(BP_TAG_INITRD, parse_tag_initrd);
164 164
165static int __init parse_tag_fdt(const bp_tag_t *tag) 165static int __init parse_tag_fdt(const bp_tag_t *tag)
166{ 166{
167 dtb_start = (void *)(tag->data[0]); 167 dtb_start = __va(tag->data[0]);
168 return 0; 168 return 0;
169} 169}
170 170
@@ -256,7 +256,7 @@ void __init early_init_devtree(void *params)
256static void __init copy_devtree(void) 256static void __init copy_devtree(void)
257{ 257{
258 void *alloc = early_init_dt_alloc_memory_arch( 258 void *alloc = early_init_dt_alloc_memory_arch(
259 be32_to_cpu(initial_boot_params->totalsize), 0); 259 be32_to_cpu(initial_boot_params->totalsize), 8);
260 if (alloc) { 260 if (alloc) {
261 memcpy(alloc, initial_boot_params, 261 memcpy(alloc, initial_boot_params,
262 be32_to_cpu(initial_boot_params->totalsize)); 262 be32_to_cpu(initial_boot_params->totalsize));
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index ffb474104311..bdbb17312526 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -16,6 +16,7 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/time.h> 17#include <linux/time.h>
18#include <linux/clocksource.h> 18#include <linux/clocksource.h>
19#include <linux/clockchips.h>
19#include <linux/interrupt.h> 20#include <linux/interrupt.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/init.h> 22#include <linux/init.h>
@@ -23,13 +24,13 @@
23#include <linux/profile.h> 24#include <linux/profile.h>
24#include <linux/delay.h> 25#include <linux/delay.h>
25#include <linux/irqdomain.h> 26#include <linux/irqdomain.h>
27#include <linux/sched_clock.h>
26 28
27#include <asm/timex.h> 29#include <asm/timex.h>
28#include <asm/platform.h> 30#include <asm/platform.h>
29 31
30#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT 32#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
31unsigned long ccount_per_jiffy; /* per 1/HZ */ 33unsigned long ccount_freq; /* ccount Hz */
32unsigned long nsec_per_ccount; /* nsec per ccount increment */
33#endif 34#endif
34 35
35static cycle_t ccount_read(struct clocksource *cs) 36static cycle_t ccount_read(struct clocksource *cs)
@@ -37,6 +38,11 @@ static cycle_t ccount_read(struct clocksource *cs)
37 return (cycle_t)get_ccount(); 38 return (cycle_t)get_ccount();
38} 39}
39 40
41static u32 notrace ccount_sched_clock_read(void)
42{
43 return get_ccount();
44}
45
40static struct clocksource ccount_clocksource = { 46static struct clocksource ccount_clocksource = {
41 .name = "ccount", 47 .name = "ccount",
42 .rating = 200, 48 .rating = 200,
@@ -44,29 +50,98 @@ static struct clocksource ccount_clocksource = {
44 .mask = CLOCKSOURCE_MASK(32), 50 .mask = CLOCKSOURCE_MASK(32),
45}; 51};
46 52
53static int ccount_timer_set_next_event(unsigned long delta,
54 struct clock_event_device *dev);
55static void ccount_timer_set_mode(enum clock_event_mode mode,
56 struct clock_event_device *evt);
57static struct ccount_timer_t {
58 struct clock_event_device evt;
59 int irq_enabled;
60} ccount_timer = {
61 .evt = {
62 .name = "ccount_clockevent",
63 .features = CLOCK_EVT_FEAT_ONESHOT,
64 .rating = 300,
65 .set_next_event = ccount_timer_set_next_event,
66 .set_mode = ccount_timer_set_mode,
67 },
68};
69
70static int ccount_timer_set_next_event(unsigned long delta,
71 struct clock_event_device *dev)
72{
73 unsigned long flags, next;
74 int ret = 0;
75
76 local_irq_save(flags);
77 next = get_ccount() + delta;
78 set_linux_timer(next);
79 if (next - get_ccount() > delta)
80 ret = -ETIME;
81 local_irq_restore(flags);
82
83 return ret;
84}
85
86static void ccount_timer_set_mode(enum clock_event_mode mode,
87 struct clock_event_device *evt)
88{
89 struct ccount_timer_t *timer =
90 container_of(evt, struct ccount_timer_t, evt);
91
92 /*
93 * There is no way to disable the timer interrupt at the device level,
94 * only at the intenable register itself. Since enable_irq/disable_irq
95 * calls are nested, we need to make sure that these calls are
96 * balanced.
97 */
98 switch (mode) {
99 case CLOCK_EVT_MODE_SHUTDOWN:
100 case CLOCK_EVT_MODE_UNUSED:
101 if (timer->irq_enabled) {
102 disable_irq(evt->irq);
103 timer->irq_enabled = 0;
104 }
105 break;
106 case CLOCK_EVT_MODE_RESUME:
107 case CLOCK_EVT_MODE_ONESHOT:
108 if (!timer->irq_enabled) {
109 enable_irq(evt->irq);
110 timer->irq_enabled = 1;
111 }
112 default:
113 break;
114 }
115}
116
47static irqreturn_t timer_interrupt(int irq, void *dev_id); 117static irqreturn_t timer_interrupt(int irq, void *dev_id);
48static struct irqaction timer_irqaction = { 118static struct irqaction timer_irqaction = {
49 .handler = timer_interrupt, 119 .handler = timer_interrupt,
50 .flags = IRQF_DISABLED, 120 .flags = IRQF_TIMER,
51 .name = "timer", 121 .name = "timer",
122 .dev_id = &ccount_timer,
52}; 123};
53 124
54void __init time_init(void) 125void __init time_init(void)
55{ 126{
56 unsigned int irq;
57#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT 127#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
58 printk("Calibrating CPU frequency "); 128 printk("Calibrating CPU frequency ");
59 platform_calibrate_ccount(); 129 platform_calibrate_ccount();
60 printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ), 130 printk("%d.%02d MHz\n", (int)ccount_freq/1000000,
61 (int)(ccount_per_jiffy/(10000/HZ))%100); 131 (int)(ccount_freq/10000)%100);
62#endif 132#endif
63 clocksource_register_hz(&ccount_clocksource, CCOUNT_PER_JIFFY * HZ); 133 clocksource_register_hz(&ccount_clocksource, CCOUNT_PER_JIFFY * HZ);
64 134
65 /* Initialize the linux timer interrupt. */ 135 ccount_timer.evt.cpumask = cpumask_of(0);
136 ccount_timer.evt.irq = irq_create_mapping(NULL, LINUX_TIMER_INT);
137 if (WARN(!ccount_timer.evt.irq, "error: can't map timer irq"))
138 return;
139 clockevents_config_and_register(&ccount_timer.evt, ccount_freq, 0xf,
140 0xffffffff);
141 setup_irq(ccount_timer.evt.irq, &timer_irqaction);
142 ccount_timer.irq_enabled = 1;
66 143
67 irq = irq_create_mapping(NULL, LINUX_TIMER_INT); 144 setup_sched_clock(ccount_sched_clock_read, 32, ccount_freq);
68 setup_irq(irq, &timer_irqaction);
69 set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY);
70} 145}
71 146
72/* 147/*
@@ -75,36 +150,14 @@ void __init time_init(void)
75 150
76irqreturn_t timer_interrupt (int irq, void *dev_id) 151irqreturn_t timer_interrupt (int irq, void *dev_id)
77{ 152{
153 struct ccount_timer_t *timer = dev_id;
154 struct clock_event_device *evt = &timer->evt;
78 155
79 unsigned long next; 156 evt->event_handler(evt);
80
81 next = get_linux_timer();
82
83again:
84 while ((signed long)(get_ccount() - next) > 0) {
85
86 profile_tick(CPU_PROFILING);
87#ifndef CONFIG_SMP
88 update_process_times(user_mode(get_irq_regs()));
89#endif
90
91 xtime_update(1); /* Linux handler in kernel/time/timekeeping */
92
93 /* Note that writing CCOMPARE clears the interrupt. */
94
95 next += CCOUNT_PER_JIFFY;
96 set_linux_timer(next);
97 }
98 157
99 /* Allow platform to do something useful (Wdog). */ 158 /* Allow platform to do something useful (Wdog). */
100
101 platform_heartbeat(); 159 platform_heartbeat();
102 160
103 /* Make sure we didn't miss any tick... */
104
105 if ((signed long)(get_ccount() - next) > 0)
106 goto again;
107
108 return IRQ_HANDLED; 161 return IRQ_HANDLED;
109} 162}
110 163
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index 42c53c87c204..d8507f812f46 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -124,3 +124,7 @@ extern long common_exception_return;
124extern long _spill_registers; 124extern long _spill_registers;
125EXPORT_SYMBOL(common_exception_return); 125EXPORT_SYMBOL(common_exception_return);
126EXPORT_SYMBOL(_spill_registers); 126EXPORT_SYMBOL(_spill_registers);
127
128#ifdef CONFIG_FUNCTION_TRACER
129EXPORT_SYMBOL(_mcount);
130#endif
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c
index 5411aa67c68e..ca9d2366bf12 100644
--- a/arch/xtensa/mm/tlb.c
+++ b/arch/xtensa/mm/tlb.c
@@ -64,7 +64,7 @@ void flush_tlb_mm(struct mm_struct *mm)
64{ 64{
65 if (mm == current->active_mm) { 65 if (mm == current->active_mm) {
66 unsigned long flags; 66 unsigned long flags;
67 local_save_flags(flags); 67 local_irq_save(flags);
68 __get_new_mmu_context(mm); 68 __get_new_mmu_context(mm);
69 __load_mmu_context(mm); 69 __load_mmu_context(mm);
70 local_irq_restore(flags); 70 local_irq_restore(flags);
@@ -94,7 +94,7 @@ void flush_tlb_range (struct vm_area_struct *vma,
94 printk("[tlbrange<%02lx,%08lx,%08lx>]\n", 94 printk("[tlbrange<%02lx,%08lx,%08lx>]\n",
95 (unsigned long)mm->context, start, end); 95 (unsigned long)mm->context, start, end);
96#endif 96#endif
97 local_save_flags(flags); 97 local_irq_save(flags);
98 98
99 if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) { 99 if (end-start + (PAGE_SIZE-1) <= _TLB_ENTRIES << PAGE_SHIFT) {
100 int oldpid = get_rasid_register(); 100 int oldpid = get_rasid_register();
@@ -128,9 +128,10 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
128 if(mm->context == NO_CONTEXT) 128 if(mm->context == NO_CONTEXT)
129 return; 129 return;
130 130
131 local_save_flags(flags); 131 local_irq_save(flags);
132 132
133 oldpid = get_rasid_register(); 133 oldpid = get_rasid_register();
134 set_rasid_register(ASID_INSERT(mm->context));
134 135
135 if (vma->vm_flags & VM_EXEC) 136 if (vma->vm_flags & VM_EXEC)
136 invalidate_itlb_mapping(page); 137 invalidate_itlb_mapping(page);
@@ -140,3 +141,116 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page)
140 141
141 local_irq_restore(flags); 142 local_irq_restore(flags);
142} 143}
144
145#ifdef CONFIG_DEBUG_TLB_SANITY
146
147static unsigned get_pte_for_vaddr(unsigned vaddr)
148{
149 struct task_struct *task = get_current();
150 struct mm_struct *mm = task->mm;
151 pgd_t *pgd;
152 pmd_t *pmd;
153 pte_t *pte;
154
155 if (!mm)
156 mm = task->active_mm;
157 pgd = pgd_offset(mm, vaddr);
158 if (pgd_none_or_clear_bad(pgd))
159 return 0;
160 pmd = pmd_offset(pgd, vaddr);
161 if (pmd_none_or_clear_bad(pmd))
162 return 0;
163 pte = pte_offset_map(pmd, vaddr);
164 if (!pte)
165 return 0;
166 return pte_val(*pte);
167}
168
169enum {
170 TLB_SUSPICIOUS = 1,
171 TLB_INSANE = 2,
172};
173
174static void tlb_insane(void)
175{
176 BUG_ON(1);
177}
178
179static void tlb_suspicious(void)
180{
181 WARN_ON(1);
182}
183
184/*
185 * Check that TLB entries with kernel ASID (1) have kernel VMA (>= TASK_SIZE),
186 * and TLB entries with user ASID (>=4) have VMA < TASK_SIZE.
187 *
188 * Check that valid TLB entries either have the same PA as the PTE, or PTE is
189 * marked as non-present. Non-present PTE and the page with non-zero refcount
190 * and zero mapcount is normal for batched TLB flush operation. Zero refcount
191 * means that the page was freed prematurely. Non-zero mapcount is unusual,
192 * but does not necessary means an error, thus marked as suspicious.
193 */
194static int check_tlb_entry(unsigned w, unsigned e, bool dtlb)
195{
196 unsigned tlbidx = w | (e << PAGE_SHIFT);
197 unsigned r0 = dtlb ?
198 read_dtlb_virtual(tlbidx) : read_itlb_virtual(tlbidx);
199 unsigned vpn = (r0 & PAGE_MASK) | (e << PAGE_SHIFT);
200 unsigned pte = get_pte_for_vaddr(vpn);
201 unsigned mm_asid = (get_rasid_register() >> 8) & ASID_MASK;
202 unsigned tlb_asid = r0 & ASID_MASK;
203 bool kernel = tlb_asid == 1;
204 int rc = 0;
205
206 if (tlb_asid > 0 && ((vpn < TASK_SIZE) == kernel)) {
207 pr_err("%cTLB: way: %u, entry: %u, VPN %08x in %s PTE\n",
208 dtlb ? 'D' : 'I', w, e, vpn,
209 kernel ? "kernel" : "user");
210 rc |= TLB_INSANE;
211 }
212
213 if (tlb_asid == mm_asid) {
214 unsigned r1 = dtlb ? read_dtlb_translation(tlbidx) :
215 read_itlb_translation(tlbidx);
216 if ((pte ^ r1) & PAGE_MASK) {
217 pr_err("%cTLB: way: %u, entry: %u, mapping: %08x->%08x, PTE: %08x\n",
218 dtlb ? 'D' : 'I', w, e, r0, r1, pte);
219 if (pte == 0 || !pte_present(__pte(pte))) {
220 struct page *p = pfn_to_page(r1 >> PAGE_SHIFT);
221 pr_err("page refcount: %d, mapcount: %d\n",
222 page_count(p),
223 page_mapcount(p));
224 if (!page_count(p))
225 rc |= TLB_INSANE;
226 else if (page_mapped(p))
227 rc |= TLB_SUSPICIOUS;
228 } else {
229 rc |= TLB_INSANE;
230 }
231 }
232 }
233 return rc;
234}
235
236void check_tlb_sanity(void)
237{
238 unsigned long flags;
239 unsigned w, e;
240 int bug = 0;
241
242 local_irq_save(flags);
243 for (w = 0; w < DTLB_ARF_WAYS; ++w)
244 for (e = 0; e < (1 << XCHAL_DTLB_ARF_ENTRIES_LOG2); ++e)
245 bug |= check_tlb_entry(w, e, true);
246 for (w = 0; w < ITLB_ARF_WAYS; ++w)
247 for (e = 0; e < (1 << XCHAL_ITLB_ARF_ENTRIES_LOG2); ++e)
248 bug |= check_tlb_entry(w, e, false);
249 if (bug & TLB_INSANE)
250 tlb_insane();
251 if (bug & TLB_SUSPICIOUS)
252 tlb_suspicious();
253 local_irq_restore(flags);
254}
255
256#endif /* CONFIG_DEBUG_TLB_SANITY */
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index 7d0fea6d7f20..56f88b7afe2f 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -700,7 +700,7 @@ struct iss_net_init {
700 700
701#define ERR KERN_ERR "iss_net_setup: " 701#define ERR KERN_ERR "iss_net_setup: "
702 702
703static int iss_net_setup(char *str) 703static int __init iss_net_setup(char *str)
704{ 704{
705 struct iss_net_private *device = NULL; 705 struct iss_net_private *device = NULL;
706 struct iss_net_init *new; 706 struct iss_net_init *new;
diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c
index c0edb35424ce..8c6e819cd8ed 100644
--- a/arch/xtensa/platforms/iss/simdisk.c
+++ b/arch/xtensa/platforms/iss/simdisk.c
@@ -108,13 +108,13 @@ static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio)
108 sector_t sector = bio->bi_sector; 108 sector_t sector = bio->bi_sector;
109 109
110 bio_for_each_segment(bvec, bio, i) { 110 bio_for_each_segment(bvec, bio, i) {
111 char *buffer = __bio_kmap_atomic(bio, i, KM_USER0); 111 char *buffer = __bio_kmap_atomic(bio, i);
112 unsigned len = bvec->bv_len >> SECTOR_SHIFT; 112 unsigned len = bvec->bv_len >> SECTOR_SHIFT;
113 113
114 simdisk_transfer(dev, sector, len, buffer, 114 simdisk_transfer(dev, sector, len, buffer,
115 bio_data_dir(bio) == WRITE); 115 bio_data_dir(bio) == WRITE);
116 sector += len; 116 sector += len;
117 __bio_kunmap_atomic(bio, KM_USER0); 117 __bio_kunmap_atomic(bio);
118 } 118 }
119 return 0; 119 return 0;
120} 120}
diff --git a/arch/xtensa/platforms/xtfpga/setup.c b/arch/xtensa/platforms/xtfpga/setup.c
index 96ef8eeb064e..74bb74fa3f87 100644
--- a/arch/xtensa/platforms/xtfpga/setup.c
+++ b/arch/xtensa/platforms/xtfpga/setup.c
@@ -163,7 +163,7 @@ void platform_heartbeat(void)
163 163
164#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT 164#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
165 165
166void platform_calibrate_ccount(void) 166void __init platform_calibrate_ccount(void)
167{ 167{
168 long clk_freq = 0; 168 long clk_freq = 0;
169#ifdef CONFIG_OF 169#ifdef CONFIG_OF
@@ -179,8 +179,7 @@ void platform_calibrate_ccount(void)
179 if (!clk_freq) 179 if (!clk_freq)
180 clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; 180 clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR;
181 181
182 ccount_per_jiffy = clk_freq / HZ; 182 ccount_freq = clk_freq;
183 nsec_per_ccount = 1000000000UL / clk_freq;
184} 183}
185 184
186#endif 185#endif
diff --git a/arch/xtensa/variants/s6000/delay.c b/arch/xtensa/variants/s6000/delay.c
index 54b2b573f166..39154563ee17 100644
--- a/arch/xtensa/variants/s6000/delay.c
+++ b/arch/xtensa/variants/s6000/delay.c
@@ -1,4 +1,3 @@
1#include <asm/delay.h>
2#include <asm/timex.h> 1#include <asm/timex.h>
3#include <asm/io.h> 2#include <asm/io.h>
4#include <variant/hardware.h> 3#include <variant/hardware.h>
@@ -17,11 +16,10 @@ void platform_calibrate_ccount(void)
17 "1: l32i %0, %2, 0 ;" 16 "1: l32i %0, %2, 0 ;"
18 " beq %0, %1, 1b ;" 17 " beq %0, %1, 1b ;"
19 : "=&a"(u) : "a"(t), "a"(tstamp)); 18 : "=&a"(u) : "a"(t), "a"(tstamp));
20 b = xtensa_get_ccount(); 19 b = get_ccount();
21 if (i == LOOPS) 20 if (i == LOOPS)
22 a = b; 21 a = b;
23 } while (--i >= 0); 22 } while (--i >= 0);
24 b -= a; 23 b -= a;
25 nsec_per_ccount = (LOOPS * 10000) / b; 24 ccount_freq = b * (100000UL / LOOPS);
26 ccount_per_jiffy = b * (100000UL / (LOOPS * HZ));
27} 25}