aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /arch/arm/kernel
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r--arch/arm/kernel/Makefile14
-rw-r--r--arch/arm/kernel/armksyms.c24
-rw-r--r--arch/arm/kernel/asm-offsets.c13
-rw-r--r--arch/arm/kernel/bios32.c30
-rw-r--r--arch/arm/kernel/calls.S16
-rw-r--r--arch/arm/kernel/crash_dump.c3
-rw-r--r--arch/arm/kernel/debug.S52
-rw-r--r--arch/arm/kernel/devtree.c148
-rw-r--r--arch/arm/kernel/ecard.c34
-rw-r--r--arch/arm/kernel/elf.c17
-rw-r--r--arch/arm/kernel/entry-armv.S74
-rw-r--r--arch/arm/kernel/entry-common.S232
-rw-r--r--arch/arm/kernel/entry-header.S33
-rw-r--r--arch/arm/kernel/etm.c20
-rw-r--r--arch/arm/kernel/fiq.c55
-rw-r--r--arch/arm/kernel/fiqasm.S49
-rw-r--r--arch/arm/kernel/ftrace.c281
-rw-r--r--arch/arm/kernel/head-common.S291
-rw-r--r--arch/arm/kernel/head-nommu.S8
-rw-r--r--arch/arm/kernel/head.S526
-rw-r--r--arch/arm/kernel/hw_breakpoint.c978
-rw-r--r--arch/arm/kernel/irq.c139
-rw-r--r--arch/arm/kernel/iwmmxt.S55
-rw-r--r--arch/arm/kernel/kgdb.c2
-rw-r--r--arch/arm/kernel/kprobes-decode.c787
-rw-r--r--arch/arm/kernel/kprobes.c3
-rw-r--r--arch/arm/kernel/leds.c28
-rw-r--r--arch/arm/kernel/machine_kexec.c40
-rw-r--r--arch/arm/kernel/module.c187
-rw-r--r--arch/arm/kernel/perf_event.c2716
-rw-r--r--arch/arm/kernel/perf_event_v6.c672
-rw-r--r--arch/arm/kernel/perf_event_v7.c918
-rw-r--r--arch/arm/kernel/perf_event_xscale.c807
-rw-r--r--arch/arm/kernel/pj4-cp0.c94
-rw-r--r--arch/arm/kernel/pmu.c22
-rw-r--r--arch/arm/kernel/process.c49
-rw-r--r--arch/arm/kernel/ptrace.c946
-rw-r--r--arch/arm/kernel/ptrace.h37
-rw-r--r--arch/arm/kernel/relocate_kernel.S2
-rw-r--r--arch/arm/kernel/return_address.c1
-rw-r--r--arch/arm/kernel/sched_clock.c74
-rw-r--r--arch/arm/kernel/setup.c275
-rw-r--r--arch/arm/kernel/signal.c103
-rw-r--r--arch/arm/kernel/sleep.S142
-rw-r--r--arch/arm/kernel/smp.c469
-rw-r--r--arch/arm/kernel/smp_scu.c23
-rw-r--r--arch/arm/kernel/smp_tlb.c139
-rw-r--r--arch/arm/kernel/smp_twd.c26
-rw-r--r--arch/arm/kernel/stacktrace.c11
-rw-r--r--arch/arm/kernel/swp_emulate.c267
-rw-r--r--arch/arm/kernel/sys_oabi-compat.c2
-rw-r--r--arch/arm/kernel/tcm.c2
-rw-r--r--arch/arm/kernel/time.c47
-rw-r--r--arch/arm/kernel/traps.c43
-rw-r--r--arch/arm/kernel/unwind.c4
-rw-r--r--arch/arm/kernel/vmlinux.lds.S59
56 files changed, 7403 insertions, 4686 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 980b78e31328..a5b31af5c2b8 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -5,7 +5,7 @@
5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) 5CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET)
6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) 6AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
7 7
8ifdef CONFIG_DYNAMIC_FTRACE 8ifdef CONFIG_FUNCTION_TRACER
9CFLAGS_REMOVE_ftrace.o = -pg 9CFLAGS_REMOVE_ftrace.o = -pg
10endif 10endif
11 11
@@ -24,15 +24,18 @@ obj-$(CONFIG_OC_ETM) += etm.o
24 24
25obj-$(CONFIG_ISA_DMA_API) += dma.o 25obj-$(CONFIG_ISA_DMA_API) += dma.o
26obj-$(CONFIG_ARCH_ACORN) += ecard.o 26obj-$(CONFIG_ARCH_ACORN) += ecard.o
27obj-$(CONFIG_FIQ) += fiq.o 27obj-$(CONFIG_FIQ) += fiq.o fiqasm.o
28obj-$(CONFIG_MODULES) += armksyms.o module.o 28obj-$(CONFIG_MODULES) += armksyms.o module.o
29obj-$(CONFIG_ARTHUR) += arthur.o 29obj-$(CONFIG_ARTHUR) += arthur.o
30obj-$(CONFIG_ISA_DMA) += dma-isa.o 30obj-$(CONFIG_ISA_DMA) += dma-isa.o
31obj-$(CONFIG_PCI) += bios32.o isa.o 31obj-$(CONFIG_PCI) += bios32.o isa.o
32obj-$(CONFIG_SMP) += smp.o 32obj-$(CONFIG_PM_SLEEP) += sleep.o
33obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
34obj-$(CONFIG_SMP) += smp.o smp_tlb.o
33obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o 35obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
34obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o 36obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
35obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 37obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
38obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
36obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o 39obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
37obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o 40obj-$(CONFIG_KPROBES) += kprobes.o kprobes-decode.o
38obj-$(CONFIG_ATAGS_PROC) += atags.o 41obj-$(CONFIG_ATAGS_PROC) += atags.o
@@ -41,7 +44,11 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
41obj-$(CONFIG_KGDB) += kgdb.o 44obj-$(CONFIG_KGDB) += kgdb.o
42obj-$(CONFIG_ARM_UNWIND) += unwind.o 45obj-$(CONFIG_ARM_UNWIND) += unwind.o
43obj-$(CONFIG_HAVE_TCM) += tcm.o 46obj-$(CONFIG_HAVE_TCM) += tcm.o
47obj-$(CONFIG_OF) += devtree.o
44obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 48obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
49obj-$(CONFIG_SWP_EMULATE) += swp_emulate.o
50CFLAGS_swp_emulate.o := -Wa,-march=armv7-a
51obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
45 52
46obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 53obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
47AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 54AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
@@ -49,6 +56,7 @@ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
49obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o 56obj-$(CONFIG_CPU_XSCALE) += xscale-cp0.o
50obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o 57obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
51obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o 58obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
59obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
52obj-$(CONFIG_IWMMXT) += iwmmxt.o 60obj-$(CONFIG_IWMMXT) += iwmmxt.o
53obj-$(CONFIG_CPU_HAS_PMU) += pmu.o 61obj-$(CONFIG_CPU_HAS_PMU) += pmu.o
54obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o 62obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 8214bfebfaca..acca35aebe28 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -140,24 +140,18 @@ EXPORT_SYMBOL(__aeabi_ulcmp);
140#endif 140#endif
141 141
142 /* bitops */ 142 /* bitops */
143EXPORT_SYMBOL(_set_bit_le); 143EXPORT_SYMBOL(_set_bit);
144EXPORT_SYMBOL(_test_and_set_bit_le); 144EXPORT_SYMBOL(_test_and_set_bit);
145EXPORT_SYMBOL(_clear_bit_le); 145EXPORT_SYMBOL(_clear_bit);
146EXPORT_SYMBOL(_test_and_clear_bit_le); 146EXPORT_SYMBOL(_test_and_clear_bit);
147EXPORT_SYMBOL(_change_bit_le); 147EXPORT_SYMBOL(_change_bit);
148EXPORT_SYMBOL(_test_and_change_bit_le); 148EXPORT_SYMBOL(_test_and_change_bit);
149EXPORT_SYMBOL(_find_first_zero_bit_le); 149EXPORT_SYMBOL(_find_first_zero_bit_le);
150EXPORT_SYMBOL(_find_next_zero_bit_le); 150EXPORT_SYMBOL(_find_next_zero_bit_le);
151EXPORT_SYMBOL(_find_first_bit_le); 151EXPORT_SYMBOL(_find_first_bit_le);
152EXPORT_SYMBOL(_find_next_bit_le); 152EXPORT_SYMBOL(_find_next_bit_le);
153 153
154#ifdef __ARMEB__ 154#ifdef __ARMEB__
155EXPORT_SYMBOL(_set_bit_be);
156EXPORT_SYMBOL(_test_and_set_bit_be);
157EXPORT_SYMBOL(_clear_bit_be);
158EXPORT_SYMBOL(_test_and_clear_bit_be);
159EXPORT_SYMBOL(_change_bit_be);
160EXPORT_SYMBOL(_test_and_change_bit_be);
161EXPORT_SYMBOL(_find_first_zero_bit_be); 155EXPORT_SYMBOL(_find_first_zero_bit_be);
162EXPORT_SYMBOL(_find_next_zero_bit_be); 156EXPORT_SYMBOL(_find_next_zero_bit_be);
163EXPORT_SYMBOL(_find_first_bit_be); 157EXPORT_SYMBOL(_find_first_bit_be);
@@ -165,6 +159,12 @@ EXPORT_SYMBOL(_find_next_bit_be);
165#endif 159#endif
166 160
167#ifdef CONFIG_FUNCTION_TRACER 161#ifdef CONFIG_FUNCTION_TRACER
162#ifdef CONFIG_OLD_MCOUNT
168EXPORT_SYMBOL(mcount); 163EXPORT_SYMBOL(mcount);
164#endif
169EXPORT_SYMBOL(__gnu_mcount_nc); 165EXPORT_SYMBOL(__gnu_mcount_nc);
170#endif 166#endif
167
168#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
169EXPORT_SYMBOL(__pv_phys_offset);
170#endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 85f2a019f77b..927522cfc12e 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -13,6 +13,9 @@
13#include <linux/sched.h> 13#include <linux/sched.h>
14#include <linux/mm.h> 14#include <linux/mm.h>
15#include <linux/dma-mapping.h> 15#include <linux/dma-mapping.h>
16#include <asm/cacheflush.h>
17#include <asm/glue-df.h>
18#include <asm/glue-pf.h>
16#include <asm/mach/arch.h> 19#include <asm/mach/arch.h>
17#include <asm/thread_info.h> 20#include <asm/thread_info.h>
18#include <asm/memory.h> 21#include <asm/memory.h>
@@ -102,8 +105,6 @@ int main(void)
102 DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); 105 DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc));
103 DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); 106 DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr));
104 DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); 107 DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name));
105 DEFINE(MACHINFO_PHYSIO, offsetof(struct machine_desc, phys_io));
106 DEFINE(MACHINFO_PGOFFIO, offsetof(struct machine_desc, io_pg_offst));
107 BLANK(); 108 BLANK();
108 DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); 109 DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list));
109 DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush)); 110 DEFINE(PROCINFO_INITFUNC, offsetof(struct proc_info_list, __cpu_flush));
@@ -116,6 +117,14 @@ int main(void)
116#ifdef MULTI_PABORT 117#ifdef MULTI_PABORT
117 DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort)); 118 DEFINE(PROCESSOR_PABT_FUNC, offsetof(struct processor, _prefetch_abort));
118#endif 119#endif
120#ifdef MULTI_CPU
121 DEFINE(CPU_SLEEP_SIZE, offsetof(struct processor, suspend_size));
122 DEFINE(CPU_DO_SUSPEND, offsetof(struct processor, do_suspend));
123 DEFINE(CPU_DO_RESUME, offsetof(struct processor, do_resume));
124#endif
125#ifdef MULTI_CACHE
126 DEFINE(CACHE_FLUSH_KERN_ALL, offsetof(struct cpu_cache_fns, flush_kern_all));
127#endif
119 BLANK(); 128 BLANK();
120 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL); 129 DEFINE(DMA_BIDIRECTIONAL, DMA_BIDIRECTIONAL);
121 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE); 130 DEFINE(DMA_TO_DEVICE, DMA_TO_DEVICE);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index c6273a3bfc25..e4ee050aad7d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -159,31 +159,6 @@ static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
159DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285); 159DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285);
160 160
161/* 161/*
162 * Same as above. The PrPMC800 carrier board for the PrPMC1100
163 * card maps the host-bridge @ 00:01:00 for some reason and it
164 * ends up getting scanned. Note that we only want to do this
165 * fixup when we find the IXP4xx on a PrPMC system, which is why
166 * we check the machine type. We could be running on a board
167 * with an IXP4xx target device and we don't want to kill the
168 * resources in that case.
169 */
170static void __devinit pci_fixup_prpmc1100(struct pci_dev *dev)
171{
172 int i;
173
174 if (machine_is_prpmc1100()) {
175 dev->class &= 0xff;
176 dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
177 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
178 dev->resource[i].start = 0;
179 dev->resource[i].end = 0;
180 dev->resource[i].flags = 0;
181 }
182 }
183}
184DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP4XX, pci_fixup_prpmc1100);
185
186/*
187 * PCI IDE controllers use non-standard I/O port decoding, respect it. 162 * PCI IDE controllers use non-standard I/O port decoding, respect it.
188 */ 163 */
189static void __devinit pci_fixup_ide_bases(struct pci_dev *dev) 164static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
@@ -583,6 +558,11 @@ void __init pci_common_init(struct hw_pci *hw)
583 * Assign resources. 558 * Assign resources.
584 */ 559 */
585 pci_bus_assign_resources(bus); 560 pci_bus_assign_resources(bus);
561
562 /*
563 * Enable bridges
564 */
565 pci_enable_bridges(bus);
586 } 566 }
587 567
588 /* 568 /*
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index b99087ac85b9..ed2ae934127e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -379,17 +379,23 @@
379 CALL(sys_fanotify_init) 379 CALL(sys_fanotify_init)
380 CALL(sys_fanotify_mark) 380 CALL(sys_fanotify_mark)
381 CALL(sys_prlimit64) 381 CALL(sys_prlimit64)
382/* 370 */ CALL(sys_set_rt_task_param) 382/* 370 */ CALL(sys_name_to_handle_at)
383 CALL(sys_open_by_handle_at)
384 CALL(sys_clock_adjtime)
385 CALL(sys_syncfs)
386 CALL(sys_sendmmsg)
387/* 375 */ CALL(sys_setns)
388 CALL(sys_set_rt_task_param)
383 CALL(sys_get_rt_task_param) 389 CALL(sys_get_rt_task_param)
384 CALL(sys_complete_job) 390 CALL(sys_complete_job)
385 CALL(sys_od_open) 391 CALL(sys_od_open)
386 CALL(sys_od_close) 392/* 380 */ CALL(sys_od_close)
387/* 375 */ CALL(sys_litmus_lock) 393 CALL(sys_litmus_lock)
388 CALL(sys_litmus_unlock) 394 CALL(sys_litmus_unlock)
389 CALL(sys_query_job_no) 395 CALL(sys_query_job_no)
390 CALL(sys_wait_for_job_release) 396 CALL(sys_wait_for_job_release)
391 CALL(sys_wait_for_ts_release) 397/* 385 */ CALL(sys_wait_for_ts_release)
392/* 380 */ CALL(sys_release_ts) 398 CALL(sys_release_ts)
393 CALL(sys_null_call) 399 CALL(sys_null_call)
394#ifndef syscalls_counted 400#ifndef syscalls_counted
395.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 401.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
index cd3b853a8a6d..90c50d4b43f7 100644
--- a/arch/arm/kernel/crash_dump.c
+++ b/arch/arm/kernel/crash_dump.c
@@ -18,9 +18,6 @@
18#include <linux/uaccess.h> 18#include <linux/uaccess.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20
21/* stores the physical address of elf header of crash image */
22unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
23
24/** 21/**
25 * copy_oldmem_page() - copy one page from old kernel memory 22 * copy_oldmem_page() - copy one page from old kernel memory
26 * @pfn: page frame number to be copied 23 * @pfn: page frame number to be copied
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index a38b4879441d..bcd66e00bdbe 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -22,11 +22,11 @@
22#if defined(CONFIG_DEBUG_ICEDCC) 22#if defined(CONFIG_DEBUG_ICEDCC)
23 @@ debug using ARM EmbeddedICE DCC channel 23 @@ debug using ARM EmbeddedICE DCC channel
24 24
25#if defined(CONFIG_CPU_V6) 25 .macro addruart, rp, rv
26
27 .macro addruart, rx, tmp
28 .endm 26 .endm
29 27
28#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
29
30 .macro senduart, rd, rx 30 .macro senduart, rd, rx
31 mcr p14, 0, \rd, c0, c5, 0 31 mcr p14, 0, \rd, c0, c5, 0
32 .endm 32 .endm
@@ -49,31 +49,8 @@
491002: 491002:
50 .endm 50 .endm
51 51
52#elif defined(CONFIG_CPU_V7)
53
54 .macro addruart, rx, tmp
55 .endm
56
57 .macro senduart, rd, rx
58 mcr p14, 0, \rd, c0, c5, 0
59 .endm
60
61 .macro busyuart, rd, rx
62busy: mrc p14, 0, pc, c0, c1, 0
63 bcs busy
64 .endm
65
66 .macro waituart, rd, rx
67wait: mrc p14, 0, pc, c0, c1, 0
68 bcs wait
69
70 .endm
71
72#elif defined(CONFIG_CPU_XSCALE) 52#elif defined(CONFIG_CPU_XSCALE)
73 53
74 .macro addruart, rx, tmp
75 .endm
76
77 .macro senduart, rd, rx 54 .macro senduart, rd, rx
78 mcr p14, 0, \rd, c8, c0, 0 55 mcr p14, 0, \rd, c8, c0, 0
79 .endm 56 .endm
@@ -98,9 +75,6 @@ wait: mrc p14, 0, pc, c0, c1, 0
98 75
99#else 76#else
100 77
101 .macro addruart, rx, tmp
102 .endm
103
104 .macro senduart, rd, rx 78 .macro senduart, rd, rx
105 mcr p14, 0, \rd, c1, c0, 0 79 mcr p14, 0, \rd, c1, c0, 0
106 .endm 80 .endm
@@ -130,6 +104,22 @@ wait: mrc p14, 0, pc, c0, c1, 0
130#include <mach/debug-macro.S> 104#include <mach/debug-macro.S>
131#endif /* CONFIG_DEBUG_ICEDCC */ 105#endif /* CONFIG_DEBUG_ICEDCC */
132 106
107#ifdef CONFIG_MMU
108 .macro addruart_current, rx, tmp1, tmp2
109 addruart \tmp1, \tmp2
110 mrc p15, 0, \rx, c1, c0
111 tst \rx, #1
112 moveq \rx, \tmp1
113 movne \rx, \tmp2
114 .endm
115
116#else /* !CONFIG_MMU */
117 .macro addruart_current, rx, tmp1, tmp2
118 addruart \rx, \tmp1
119 .endm
120
121#endif /* CONFIG_MMU */
122
133/* 123/*
134 * Useful debugging routines 124 * Useful debugging routines
135 */ 125 */
@@ -164,7 +154,7 @@ ENDPROC(printhex2)
164 .ltorg 154 .ltorg
165 155
166ENTRY(printascii) 156ENTRY(printascii)
167 addruart r3, r1 157 addruart_current r3, r1, r2
168 b 2f 158 b 2f
1691: waituart r2, r3 1591: waituart r2, r3
170 senduart r1, r3 160 senduart r1, r3
@@ -180,7 +170,7 @@ ENTRY(printascii)
180ENDPROC(printascii) 170ENDPROC(printascii)
181 171
182ENTRY(printch) 172ENTRY(printch)
183 addruart r3, r1 173 addruart_current r3, r1, r2
184 mov r1, r0 174 mov r1, r0
185 mov r0, #0 175 mov r0, #0
186 b 1b 176 b 1b
diff --git a/arch/arm/kernel/devtree.c b/arch/arm/kernel/devtree.c
new file mode 100644
index 000000000000..0cdd7b456cb2
--- /dev/null
+++ b/arch/arm/kernel/devtree.c
@@ -0,0 +1,148 @@
1/*
2 * linux/arch/arm/kernel/devtree.c
3 *
4 * Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/init.h>
12#include <linux/module.h>
13#include <linux/errno.h>
14#include <linux/types.h>
15#include <linux/bootmem.h>
16#include <linux/memblock.h>
17#include <linux/of.h>
18#include <linux/of_fdt.h>
19#include <linux/of_irq.h>
20#include <linux/of_platform.h>
21
22#include <asm/setup.h>
23#include <asm/page.h>
24#include <asm/mach/arch.h>
25#include <asm/mach-types.h>
26
27void __init early_init_dt_add_memory_arch(u64 base, u64 size)
28{
29 arm_add_memory(base, size);
30}
31
32void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
33{
34 return alloc_bootmem_align(size, align);
35}
36
37void __init arm_dt_memblock_reserve(void)
38{
39 u64 *reserve_map, base, size;
40
41 if (!initial_boot_params)
42 return;
43
44 /* Reserve the dtb region */
45 memblock_reserve(virt_to_phys(initial_boot_params),
46 be32_to_cpu(initial_boot_params->totalsize));
47
48 /*
49 * Process the reserve map. This will probably overlap the initrd
50 * and dtb locations which are already reserved, but overlaping
51 * doesn't hurt anything
52 */
53 reserve_map = ((void*)initial_boot_params) +
54 be32_to_cpu(initial_boot_params->off_mem_rsvmap);
55 while (1) {
56 base = be64_to_cpup(reserve_map++);
57 size = be64_to_cpup(reserve_map++);
58 if (!size)
59 break;
60 memblock_reserve(base, size);
61 }
62}
63
64/**
65 * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
66 * @dt_phys: physical address of dt blob
67 *
68 * If a dtb was passed to the kernel in r2, then use it to choose the
69 * correct machine_desc and to setup the system.
70 */
71struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
72{
73 struct boot_param_header *devtree;
74 struct machine_desc *mdesc, *mdesc_best = NULL;
75 unsigned int score, mdesc_score = ~1;
76 unsigned long dt_root;
77 const char *model;
78
79 if (!dt_phys)
80 return NULL;
81
82 devtree = phys_to_virt(dt_phys);
83
84 /* check device tree validity */
85 if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
86 return NULL;
87
88 /* Search the mdescs for the 'best' compatible value match */
89 initial_boot_params = devtree;
90 dt_root = of_get_flat_dt_root();
91 for_each_machine_desc(mdesc) {
92 score = of_flat_dt_match(dt_root, mdesc->dt_compat);
93 if (score > 0 && score < mdesc_score) {
94 mdesc_best = mdesc;
95 mdesc_score = score;
96 }
97 }
98 if (!mdesc_best) {
99 const char *prop;
100 long size;
101
102 early_print("\nError: unrecognized/unsupported "
103 "device tree compatible list:\n[ ");
104
105 prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
106 while (size > 0) {
107 early_print("'%s' ", prop);
108 size -= strlen(prop) + 1;
109 prop += strlen(prop) + 1;
110 }
111 early_print("]\n\n");
112
113 dump_machine_table(); /* does not return */
114 }
115
116 model = of_get_flat_dt_prop(dt_root, "model", NULL);
117 if (!model)
118 model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
119 if (!model)
120 model = "<unknown>";
121 pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
122
123 /* Retrieve various information from the /chosen node */
124 of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
125 /* Initialize {size,address}-cells info */
126 of_scan_flat_dt(early_init_dt_scan_root, NULL);
127 /* Setup memory, calling early_init_dt_add_memory_arch */
128 of_scan_flat_dt(early_init_dt_scan_memory, NULL);
129
130 /* Change machine number to match the mdesc we're using */
131 __machine_arch_type = mdesc_best->nr;
132
133 return mdesc_best;
134}
135
136/**
137 * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
138 *
139 * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
140 * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
141 * supported.
142 */
143unsigned int irq_create_of_mapping(struct device_node *controller,
144 const u32 *intspec, unsigned int intsize)
145{
146 return intspec[0];
147}
148EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index eed2f795e1b3..d16500110ee9 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -443,40 +443,40 @@ static expansioncard_ops_t ecard_default_ops = {
443 * 443 *
444 * They are not meant to be called directly, but via enable/disable_irq. 444 * They are not meant to be called directly, but via enable/disable_irq.
445 */ 445 */
446static void ecard_irq_unmask(unsigned int irqnr) 446static void ecard_irq_unmask(struct irq_data *d)
447{ 447{
448 ecard_t *ec = slot_to_ecard(irqnr - 32); 448 ecard_t *ec = slot_to_ecard(d->irq - 32);
449 449
450 if (ec) { 450 if (ec) {
451 if (!ec->ops) 451 if (!ec->ops)
452 ec->ops = &ecard_default_ops; 452 ec->ops = &ecard_default_ops;
453 453
454 if (ec->claimed && ec->ops->irqenable) 454 if (ec->claimed && ec->ops->irqenable)
455 ec->ops->irqenable(ec, irqnr); 455 ec->ops->irqenable(ec, d->irq);
456 else 456 else
457 printk(KERN_ERR "ecard: rejecting request to " 457 printk(KERN_ERR "ecard: rejecting request to "
458 "enable IRQs for %d\n", irqnr); 458 "enable IRQs for %d\n", d->irq);
459 } 459 }
460} 460}
461 461
462static void ecard_irq_mask(unsigned int irqnr) 462static void ecard_irq_mask(struct irq_data *d)
463{ 463{
464 ecard_t *ec = slot_to_ecard(irqnr - 32); 464 ecard_t *ec = slot_to_ecard(d->irq - 32);
465 465
466 if (ec) { 466 if (ec) {
467 if (!ec->ops) 467 if (!ec->ops)
468 ec->ops = &ecard_default_ops; 468 ec->ops = &ecard_default_ops;
469 469
470 if (ec->ops && ec->ops->irqdisable) 470 if (ec->ops && ec->ops->irqdisable)
471 ec->ops->irqdisable(ec, irqnr); 471 ec->ops->irqdisable(ec, d->irq);
472 } 472 }
473} 473}
474 474
475static struct irq_chip ecard_chip = { 475static struct irq_chip ecard_chip = {
476 .name = "ECARD", 476 .name = "ECARD",
477 .ack = ecard_irq_mask, 477 .irq_ack = ecard_irq_mask,
478 .mask = ecard_irq_mask, 478 .irq_mask = ecard_irq_mask,
479 .unmask = ecard_irq_unmask, 479 .irq_unmask = ecard_irq_unmask,
480}; 480};
481 481
482void ecard_enablefiq(unsigned int fiqnr) 482void ecard_enablefiq(unsigned int fiqnr)
@@ -551,7 +551,7 @@ static void ecard_check_lockup(struct irq_desc *desc)
551 printk(KERN_ERR "\nInterrupt lockup detected - " 551 printk(KERN_ERR "\nInterrupt lockup detected - "
552 "disabling all expansion card interrupts\n"); 552 "disabling all expansion card interrupts\n");
553 553
554 desc->chip->mask(IRQ_EXPANSIONCARD); 554 desc->irq_data.chip->irq_mask(&desc->irq_data);
555 ecard_dump_irq_state(); 555 ecard_dump_irq_state();
556 } 556 }
557 } else 557 } else
@@ -574,7 +574,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
574 ecard_t *ec; 574 ecard_t *ec;
575 int called = 0; 575 int called = 0;
576 576
577 desc->chip->mask(irq); 577 desc->irq_data.chip->irq_mask(&desc->irq_data);
578 for (ec = cards; ec; ec = ec->next) { 578 for (ec = cards; ec; ec = ec->next) {
579 int pending; 579 int pending;
580 580
@@ -591,7 +591,7 @@ ecard_irq_handler(unsigned int irq, struct irq_desc *desc)
591 called ++; 591 called ++;
592 } 592 }
593 } 593 }
594 desc->chip->unmask(irq); 594 desc->irq_data.chip->irq_unmask(&desc->irq_data);
595 595
596 if (called == 0) 596 if (called == 0)
597 ecard_check_lockup(desc); 597 ecard_check_lockup(desc);
@@ -1043,8 +1043,8 @@ ecard_probe(int slot, card_type_t type)
1043 */ 1043 */
1044 if (slot < 8) { 1044 if (slot < 8) {
1045 ec->irq = 32 + slot; 1045 ec->irq = 32 + slot;
1046 set_irq_chip(ec->irq, &ecard_chip); 1046 irq_set_chip_and_handler(ec->irq, &ecard_chip,
1047 set_irq_handler(ec->irq, handle_level_irq); 1047 handle_level_irq);
1048 set_irq_flags(ec->irq, IRQF_VALID); 1048 set_irq_flags(ec->irq, IRQF_VALID);
1049 } 1049 }
1050 1050
@@ -1103,7 +1103,7 @@ static int __init ecard_init(void)
1103 1103
1104 irqhw = ecard_probeirqhw(); 1104 irqhw = ecard_probeirqhw();
1105 1105
1106 set_irq_chained_handler(IRQ_EXPANSIONCARD, 1106 irq_set_chained_handler(IRQ_EXPANSIONCARD,
1107 irqhw ? ecard_irqexp_handler : ecard_irq_handler); 1107 irqhw ? ecard_irqexp_handler : ecard_irq_handler);
1108 1108
1109 ecard_proc_init(); 1109 ecard_proc_init();
diff --git a/arch/arm/kernel/elf.c b/arch/arm/kernel/elf.c
index d4a0da1e48f4..9b05c6a0dcea 100644
--- a/arch/arm/kernel/elf.c
+++ b/arch/arm/kernel/elf.c
@@ -40,15 +40,22 @@ EXPORT_SYMBOL(elf_check_arch);
40void elf_set_personality(const struct elf32_hdr *x) 40void elf_set_personality(const struct elf32_hdr *x)
41{ 41{
42 unsigned int eflags = x->e_flags; 42 unsigned int eflags = x->e_flags;
43 unsigned int personality = PER_LINUX_32BIT; 43 unsigned int personality = current->personality & ~PER_MASK;
44
45 /*
46 * We only support Linux ELF executables, so always set the
47 * personality to LINUX.
48 */
49 personality |= PER_LINUX;
44 50
45 /* 51 /*
46 * APCS-26 is only valid for OABI executables 52 * APCS-26 is only valid for OABI executables
47 */ 53 */
48 if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) { 54 if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
49 if (eflags & EF_ARM_APCS_26) 55 (eflags & EF_ARM_APCS_26))
50 personality = PER_LINUX; 56 personality &= ~ADDR_LIMIT_32BIT;
51 } 57 else
58 personality |= ADDR_LIMIT_32BIT;
52 59
53 set_personality(personality); 60 set_personality(personality);
54 61
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb8e93a76407..90c62cd51ca9 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -16,7 +16,8 @@
16 */ 16 */
17 17
18#include <asm/memory.h> 18#include <asm/memory.h>
19#include <asm/glue.h> 19#include <asm/glue-df.h>
20#include <asm/glue-pf.h>
20#include <asm/vfpmacros.h> 21#include <asm/vfpmacros.h>
21#include <mach/entry-macro.S> 22#include <mach/entry-macro.S>
22#include <asm/thread_notify.h> 23#include <asm/thread_notify.h>
@@ -25,40 +26,22 @@
25#include <asm/tls.h> 26#include <asm/tls.h>
26 27
27#include "entry-header.S" 28#include "entry-header.S"
29#include <asm/entry-macro-multi.S>
28 30
29/* 31/*
30 * Interrupt handling. Preserves r7, r8, r9 32 * Interrupt handling. Preserves r7, r8, r9
31 */ 33 */
32 .macro irq_handler 34 .macro irq_handler
33 get_irqnr_preamble r5, lr 35#ifdef CONFIG_MULTI_IRQ_HANDLER
341: get_irqnr_and_base r0, r6, r5, lr 36 ldr r5, =handle_arch_irq
35 movne r1, sp 37 mov r0, sp
36 @ 38 ldr r5, [r5]
37 @ routine called with r0 = irq number, r1 = struct pt_regs * 39 adr lr, BSYM(9997f)
38 @ 40 teq r5, #0
39 adrne lr, BSYM(1b) 41 movne pc, r5
40 bne asm_do_IRQ
41
42#ifdef CONFIG_SMP
43 /*
44 * XXX
45 *
46 * this macro assumes that irqstat (r6) and base (r5) are
47 * preserved from get_irqnr_and_base above
48 */
49 test_for_ipi r0, r6, r5, lr
50 movne r0, sp
51 adrne lr, BSYM(1b)
52 bne do_IPI
53
54#ifdef CONFIG_LOCAL_TIMERS
55 test_for_ltirq r0, r6, r5, lr
56 movne r0, sp
57 adrne lr, BSYM(1b)
58 bne do_local_timer
59#endif
60#endif 42#endif
61 43 arch_irq_handler_default
449997:
62 .endm 45 .endm
63 46
64#ifdef CONFIG_KPROBES 47#ifdef CONFIG_KPROBES
@@ -196,6 +179,7 @@ __dabt_svc:
196 @ 179 @
197 @ set desired IRQ state, then call main handler 180 @ set desired IRQ state, then call main handler
198 @ 181 @
182 debug_entry r1
199 msr cpsr_c, r9 183 msr cpsr_c, r9
200 mov r2, sp 184 mov r2, sp
201 bl do_DataAbort 185 bl do_DataAbort
@@ -322,6 +306,7 @@ __pabt_svc:
322#else 306#else
323 bl CPU_PABORT_HANDLER 307 bl CPU_PABORT_HANDLER
324#endif 308#endif
309 debug_entry r1
325 msr cpsr_c, r9 @ Maybe enable interrupts 310 msr cpsr_c, r9 @ Maybe enable interrupts
326 mov r2, sp @ regs 311 mov r2, sp @ regs
327 bl do_PrefetchAbort @ call abort handler 312 bl do_PrefetchAbort @ call abort handler
@@ -437,6 +422,7 @@ __dabt_usr:
437 @ 422 @
438 @ IRQs on, then call the main handler 423 @ IRQs on, then call the main handler
439 @ 424 @
425 debug_entry r1
440 enable_irq 426 enable_irq
441 mov r2, sp 427 mov r2, sp
442 adr lr, BSYM(ret_from_exception) 428 adr lr, BSYM(ret_from_exception)
@@ -449,6 +435,10 @@ __irq_usr:
449 usr_entry 435 usr_entry
450 kuser_cmpxchg_check 436 kuser_cmpxchg_check
451 437
438#ifdef CONFIG_IRQSOFF_TRACER
439 bl trace_hardirqs_off
440#endif
441
452 get_thread_info tsk 442 get_thread_info tsk
453#ifdef CONFIG_PREEMPT 443#ifdef CONFIG_PREEMPT
454 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count 444 ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -467,7 +457,7 @@ __irq_usr:
467#endif 457#endif
468 458
469 mov why, #0 459 mov why, #0
470 b ret_to_user 460 b ret_to_user_from_irq
471 UNWIND(.fnend ) 461 UNWIND(.fnend )
472ENDPROC(__irq_usr) 462ENDPROC(__irq_usr)
473 463
@@ -701,6 +691,7 @@ __pabt_usr:
701#else 691#else
702 bl CPU_PABORT_HANDLER 692 bl CPU_PABORT_HANDLER
703#endif 693#endif
694 debug_entry r1
704 enable_irq @ Enable interrupts 695 enable_irq @ Enable interrupts
705 mov r2, sp @ regs 696 mov r2, sp @ regs
706 bl do_PrefetchAbort @ call abort handler 697 bl do_PrefetchAbort @ call abort handler
@@ -733,7 +724,7 @@ ENTRY(__switch_to)
733 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack 724 THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
734 THUMB( str sp, [ip], #4 ) 725 THUMB( str sp, [ip], #4 )
735 THUMB( str lr, [ip], #4 ) 726 THUMB( str lr, [ip], #4 )
736#ifdef CONFIG_MMU 727#ifdef CONFIG_CPU_USE_DOMAINS
737 ldr r6, [r2, #TI_CPU_DOMAIN] 728 ldr r6, [r2, #TI_CPU_DOMAIN]
738#endif 729#endif
739 set_tls r3, r4, r5 730 set_tls r3, r4, r5
@@ -742,7 +733,7 @@ ENTRY(__switch_to)
742 ldr r8, =__stack_chk_guard 733 ldr r8, =__stack_chk_guard
743 ldr r7, [r7, #TSK_STACK_CANARY] 734 ldr r7, [r7, #TSK_STACK_CANARY]
744#endif 735#endif
745#ifdef CONFIG_MMU 736#ifdef CONFIG_CPU_USE_DOMAINS
746 mcr p15, 0, r6, c3, c0, 0 @ Set domain register 737 mcr p15, 0, r6, c3, c0, 0 @ Set domain register
747#endif 738#endif
748 mov r5, r0 739 mov r5, r0
@@ -840,7 +831,7 @@ __kuser_helper_start:
840 */ 831 */
841 832
842__kuser_memory_barrier: @ 0xffff0fa0 833__kuser_memory_barrier: @ 0xffff0fa0
843 smp_dmb 834 smp_dmb arm
844 usr_ret lr 835 usr_ret lr
845 836
846 .align 5 837 .align 5
@@ -909,7 +900,7 @@ __kuser_cmpxchg: @ 0xffff0fc0
909 * A special ghost syscall is used for that (see traps.c). 900 * A special ghost syscall is used for that (see traps.c).
910 */ 901 */
911 stmfd sp!, {r7, lr} 902 stmfd sp!, {r7, lr}
912 ldr r7, =1f @ it's 20 bits 903 ldr r7, 1f @ it's 20 bits
913 swi __ARM_NR_cmpxchg 904 swi __ARM_NR_cmpxchg
914 ldmfd sp!, {r7, pc} 905 ldmfd sp!, {r7, pc}
9151: .word __ARM_NR_cmpxchg 9061: .word __ARM_NR_cmpxchg
@@ -957,7 +948,7 @@ kuser_cmpxchg_fixup:
957 948
958#else 949#else
959 950
960 smp_dmb 951 smp_dmb arm
9611: ldrex r3, [r2] 9521: ldrex r3, [r2]
962 subs r3, r3, r0 953 subs r3, r3, r0
963 strexeq r3, r1, [r2] 954 strexeq r3, r1, [r2]
@@ -965,11 +956,8 @@ kuser_cmpxchg_fixup:
965 beq 1b 956 beq 1b
966 rsbs r0, r3, #0 957 rsbs r0, r3, #0
967 /* beware -- each __kuser slot must be 8 instructions max */ 958 /* beware -- each __kuser slot must be 8 instructions max */
968#ifdef CONFIG_SMP 959 ALT_SMP(b __kuser_memory_barrier)
969 b __kuser_memory_barrier 960 ALT_UP(usr_ret lr)
970#else
971 usr_ret lr
972#endif
973 961
974#endif 962#endif
975 963
@@ -1246,3 +1234,9 @@ cr_alignment:
1246 .space 4 1234 .space 4
1247cr_no_alignment: 1235cr_no_alignment:
1248 .space 4 1236 .space 4
1237
1238#ifdef CONFIG_MULTI_IRQ_HANDLER
1239 .globl handle_arch_irq
1240handle_arch_irq:
1241 .space 4
1242#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 7885722bdf4e..b2a27b6b0046 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -29,6 +29,9 @@ ret_fast_syscall:
29 ldr r1, [tsk, #TI_FLAGS] 29 ldr r1, [tsk, #TI_FLAGS]
30 tst r1, #_TIF_WORK_MASK 30 tst r1, #_TIF_WORK_MASK
31 bne fast_work_pending 31 bne fast_work_pending
32#if defined(CONFIG_IRQSOFF_TRACER)
33 asm_trace_hardirqs_on
34#endif
32 35
33 /* perform architecture specific actions before user return */ 36 /* perform architecture specific actions before user return */
34 arch_ret_to_user r1, lr 37 arch_ret_to_user r1, lr
@@ -61,14 +64,19 @@ work_resched:
61ENTRY(ret_to_user) 64ENTRY(ret_to_user)
62ret_slow_syscall: 65ret_slow_syscall:
63 disable_irq @ disable interrupts 66 disable_irq @ disable interrupts
67ENTRY(ret_to_user_from_irq)
64 ldr r1, [tsk, #TI_FLAGS] 68 ldr r1, [tsk, #TI_FLAGS]
65 tst r1, #_TIF_WORK_MASK 69 tst r1, #_TIF_WORK_MASK
66 bne work_pending 70 bne work_pending
67no_work_pending: 71no_work_pending:
72#if defined(CONFIG_IRQSOFF_TRACER)
73 asm_trace_hardirqs_on
74#endif
68 /* perform architecture specific actions before user return */ 75 /* perform architecture specific actions before user return */
69 arch_ret_to_user r1, lr 76 arch_ret_to_user r1, lr
70 77
71 restore_user_regs fast = 0, offset = 0 78 restore_user_regs fast = 0, offset = 0
79ENDPROC(ret_to_user_from_irq)
72ENDPROC(ret_to_user) 80ENDPROC(ret_to_user)
73 81
74/* 82/*
@@ -129,76 +137,187 @@ ENDPROC(ret_from_fork)
129 * clobber the ip register. This is OK because the ARM calling convention 137 * clobber the ip register. This is OK because the ARM calling convention
130 * allows it to be clobbered in subroutines and doesn't use it to hold 138 * allows it to be clobbered in subroutines and doesn't use it to hold
131 * parameters.) 139 * parameters.)
140 *
141 * When using dynamic ftrace, we patch out the mcount call by a "mov r0, r0"
142 * for the mcount case, and a "pop {lr}" for the __gnu_mcount_nc case (see
143 * arch/arm/kernel/ftrace.c).
132 */ 144 */
133#ifdef CONFIG_DYNAMIC_FTRACE 145
134ENTRY(mcount) 146#ifndef CONFIG_OLD_MCOUNT
135 stmdb sp!, {r0-r3, lr} 147#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 4))
136 mov r0, lr 148#error Ftrace requires CONFIG_FRAME_POINTER=y with GCC older than 4.4.0.
149#endif
150#endif
151
152.macro __mcount suffix
153 mcount_enter
154 ldr r0, =ftrace_trace_function
155 ldr r2, [r0]
156 adr r0, .Lftrace_stub
157 cmp r0, r2
158 bne 1f
159
160#ifdef CONFIG_FUNCTION_GRAPH_TRACER
161 ldr r1, =ftrace_graph_return
162 ldr r2, [r1]
163 cmp r0, r2
164 bne ftrace_graph_caller\suffix
165
166 ldr r1, =ftrace_graph_entry
167 ldr r2, [r1]
168 ldr r0, =ftrace_graph_entry_stub
169 cmp r0, r2
170 bne ftrace_graph_caller\suffix
171#endif
172
173 mcount_exit
174
1751: mcount_get_lr r1 @ lr of instrumented func
176 mov r0, lr @ instrumented function
137 sub r0, r0, #MCOUNT_INSN_SIZE 177 sub r0, r0, #MCOUNT_INSN_SIZE
178 adr lr, BSYM(2f)
179 mov pc, r2
1802: mcount_exit
181.endm
138 182
139 .globl mcount_call 183.macro __ftrace_caller suffix
140mcount_call: 184 mcount_enter
141 bl ftrace_stub
142 ldr lr, [fp, #-4] @ restore lr
143 ldmia sp!, {r0-r3, pc}
144 185
145ENTRY(ftrace_caller) 186 mcount_get_lr r1 @ lr of instrumented func
146 stmdb sp!, {r0-r3, lr} 187 mov r0, lr @ instrumented function
147 ldr r1, [fp, #-4]
148 mov r0, lr
149 sub r0, r0, #MCOUNT_INSN_SIZE 188 sub r0, r0, #MCOUNT_INSN_SIZE
150 189
151 .globl ftrace_call 190 .globl ftrace_call\suffix
152ftrace_call: 191ftrace_call\suffix:
153 bl ftrace_stub 192 bl ftrace_stub
154 ldr lr, [fp, #-4] @ restore lr 193
194#ifdef CONFIG_FUNCTION_GRAPH_TRACER
195 .globl ftrace_graph_call\suffix
196ftrace_graph_call\suffix:
197 mov r0, r0
198#endif
199
200 mcount_exit
201.endm
202
203.macro __ftrace_graph_caller
204 sub r0, fp, #4 @ &lr of instrumented routine (&parent)
205#ifdef CONFIG_DYNAMIC_FTRACE
206 @ called from __ftrace_caller, saved in mcount_enter
207 ldr r1, [sp, #16] @ instrumented routine (func)
208#else
209 @ called from __mcount, untouched in lr
210 mov r1, lr @ instrumented routine (func)
211#endif
212 sub r1, r1, #MCOUNT_INSN_SIZE
213 mov r2, fp @ frame pointer
214 bl prepare_ftrace_return
215 mcount_exit
216.endm
217
218#ifdef CONFIG_OLD_MCOUNT
219/*
220 * mcount
221 */
222
223.macro mcount_enter
224 stmdb sp!, {r0-r3, lr}
225.endm
226
227.macro mcount_get_lr reg
228 ldr \reg, [fp, #-4]
229.endm
230
231.macro mcount_exit
232 ldr lr, [fp, #-4]
155 ldmia sp!, {r0-r3, pc} 233 ldmia sp!, {r0-r3, pc}
234.endm
156 235
236ENTRY(mcount)
237#ifdef CONFIG_DYNAMIC_FTRACE
238 stmdb sp!, {lr}
239 ldr lr, [fp, #-4]
240 ldmia sp!, {pc}
157#else 241#else
242 __mcount _old
243#endif
244ENDPROC(mcount)
158 245
159ENTRY(__gnu_mcount_nc) 246#ifdef CONFIG_DYNAMIC_FTRACE
247ENTRY(ftrace_caller_old)
248 __ftrace_caller _old
249ENDPROC(ftrace_caller_old)
250#endif
251
252#ifdef CONFIG_FUNCTION_GRAPH_TRACER
253ENTRY(ftrace_graph_caller_old)
254 __ftrace_graph_caller
255ENDPROC(ftrace_graph_caller_old)
256#endif
257
258.purgem mcount_enter
259.purgem mcount_get_lr
260.purgem mcount_exit
261#endif
262
263/*
264 * __gnu_mcount_nc
265 */
266
267.macro mcount_enter
160 stmdb sp!, {r0-r3, lr} 268 stmdb sp!, {r0-r3, lr}
161 ldr r0, =ftrace_trace_function 269.endm
162 ldr r2, [r0] 270
163 adr r0, ftrace_stub 271.macro mcount_get_lr reg
164 cmp r0, r2 272 ldr \reg, [sp, #20]
165 bne gnu_trace 273.endm
274
275.macro mcount_exit
166 ldmia sp!, {r0-r3, ip, lr} 276 ldmia sp!, {r0-r3, ip, lr}
167 mov pc, ip 277 mov pc, ip
278.endm
168 279
169gnu_trace: 280ENTRY(__gnu_mcount_nc)
170 ldr r1, [sp, #20] @ lr of instrumented routine 281#ifdef CONFIG_DYNAMIC_FTRACE
171 mov r0, lr 282 mov ip, lr
172 sub r0, r0, #MCOUNT_INSN_SIZE 283 ldmia sp!, {lr}
173 mov lr, pc
174 mov pc, r2
175 ldmia sp!, {r0-r3, ip, lr}
176 mov pc, ip 284 mov pc, ip
285#else
286 __mcount
287#endif
288ENDPROC(__gnu_mcount_nc)
177 289
178ENTRY(mcount) 290#ifdef CONFIG_DYNAMIC_FTRACE
179 stmdb sp!, {r0-r3, lr} 291ENTRY(ftrace_caller)
180 ldr r0, =ftrace_trace_function 292 __ftrace_caller
181 ldr r2, [r0] 293ENDPROC(ftrace_caller)
182 adr r0, ftrace_stub 294#endif
183 cmp r0, r2
184 bne trace
185 ldr lr, [fp, #-4] @ restore lr
186 ldmia sp!, {r0-r3, pc}
187 295
188trace: 296#ifdef CONFIG_FUNCTION_GRAPH_TRACER
189 ldr r1, [fp, #-4] @ lr of instrumented routine 297ENTRY(ftrace_graph_caller)
190 mov r0, lr 298 __ftrace_graph_caller
191 sub r0, r0, #MCOUNT_INSN_SIZE 299ENDPROC(ftrace_graph_caller)
192 mov lr, pc 300#endif
193 mov pc, r2
194 ldr lr, [fp, #-4] @ restore lr
195 ldmia sp!, {r0-r3, pc}
196 301
197#endif /* CONFIG_DYNAMIC_FTRACE */ 302.purgem mcount_enter
303.purgem mcount_get_lr
304.purgem mcount_exit
305
306#ifdef CONFIG_FUNCTION_GRAPH_TRACER
307 .globl return_to_handler
308return_to_handler:
309 stmdb sp!, {r0-r3}
310 mov r0, fp @ frame pointer
311 bl ftrace_return_to_handler
312 mov lr, r0 @ r0 has real ret addr
313 ldmia sp!, {r0-r3}
314 mov pc, lr
315#endif
198 316
199 .globl ftrace_stub 317ENTRY(ftrace_stub)
200ftrace_stub: 318.Lftrace_stub:
201 mov pc, lr 319 mov pc, lr
320ENDPROC(ftrace_stub)
202 321
203#endif /* CONFIG_FUNCTION_TRACER */ 322#endif /* CONFIG_FUNCTION_TRACER */
204 323
@@ -295,7 +414,6 @@ ENTRY(vector_swi)
295 414
296 get_thread_info tsk 415 get_thread_info tsk
297 adr tbl, sys_call_table @ load syscall table pointer 416 adr tbl, sys_call_table @ load syscall table pointer
298 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
299 417
300#if defined(CONFIG_OABI_COMPAT) 418#if defined(CONFIG_OABI_COMPAT)
301 /* 419 /*
@@ -312,8 +430,20 @@ ENTRY(vector_swi)
312 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number 430 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
313#endif 431#endif
314 432
433 ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
315 stmdb sp!, {r4, r5} @ push fifth and sixth args 434 stmdb sp!, {r4, r5} @ push fifth and sixth args
316 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 435
436#ifdef CONFIG_SECCOMP
437 tst r10, #_TIF_SECCOMP
438 beq 1f
439 mov r0, scno
440 bl __secure_computing
441 add r0, sp, #S_R0 + S_OFF @ pointer to regs
442 ldmia r0, {r0 - r3} @ have to reload r0 - r3
4431:
444#endif
445
446 tst r10, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
317 bne __sys_trace 447 bne __sys_trace
318 448
319 cmp scno, #NR_syscalls @ check upper syscall limit 449 cmp scno, #NR_syscalls @ check upper syscall limit
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index d93f976fb389..051166c2a932 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -76,13 +76,13 @@
76#ifndef CONFIG_THUMB2_KERNEL 76#ifndef CONFIG_THUMB2_KERNEL
77 .macro svc_exit, rpsr 77 .macro svc_exit, rpsr
78 msr spsr_cxsf, \rpsr 78 msr spsr_cxsf, \rpsr
79#if defined(CONFIG_CPU_32v6K) 79#if defined(CONFIG_CPU_V6)
80 clrex @ clear the exclusive monitor
81 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
82#elif defined (CONFIG_CPU_V6)
83 ldr r0, [sp] 80 ldr r0, [sp]
84 strex r1, r2, [sp] @ clear the exclusive monitor 81 strex r1, r2, [sp] @ clear the exclusive monitor
85 ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr 82 ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr
83#elif defined(CONFIG_CPU_32v6K)
84 clrex @ clear the exclusive monitor
85 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
86#else 86#else
87 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr 87 ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
88#endif 88#endif
@@ -92,10 +92,10 @@
92 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr 92 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
93 ldr lr, [sp, #\offset + S_PC]! @ get pc 93 ldr lr, [sp, #\offset + S_PC]! @ get pc
94 msr spsr_cxsf, r1 @ save in spsr_svc 94 msr spsr_cxsf, r1 @ save in spsr_svc
95#if defined(CONFIG_CPU_32v6K) 95#if defined(CONFIG_CPU_V6)
96 clrex @ clear the exclusive monitor
97#elif defined (CONFIG_CPU_V6)
98 strex r1, r2, [sp] @ clear the exclusive monitor 96 strex r1, r2, [sp] @ clear the exclusive monitor
97#elif defined(CONFIG_CPU_32v6K)
98 clrex @ clear the exclusive monitor
99#endif 99#endif
100 .if \fast 100 .if \fast
101 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr 101 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
@@ -165,6 +165,25 @@
165 .endm 165 .endm
166#endif /* !CONFIG_THUMB2_KERNEL */ 166#endif /* !CONFIG_THUMB2_KERNEL */
167 167
168 @
169 @ Debug exceptions are taken as prefetch or data aborts.
170 @ We must disable preemption during the handler so that
171 @ we can access the debug registers safely.
172 @
173 .macro debug_entry, fsr
174#if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT)
175 ldr r4, =0x40f @ mask out fsr.fs
176 and r5, r4, \fsr
177 cmp r5, #2 @ debug exception
178 bne 1f
179 get_thread_info r10
180 ldr r6, [r10, #TI_PREEMPT] @ get preempt count
181 add r11, r6, #1 @ increment it
182 str r11, [r10, #TI_PREEMPT]
1831:
184#endif
185 .endm
186
168/* 187/*
169 * These are the registers used in the syscall handler, and allow us to 188 * These are the registers used in the syscall handler, and allow us to
170 * have in theory up to 7 arguments to a function - r0 to r6. 189 * have in theory up to 7 arguments to a function - r0 to r6.
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 33c7077174db..1bec8b5f22f0 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -30,6 +30,21 @@
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Alexander Shishkin"); 31MODULE_AUTHOR("Alexander Shishkin");
32 32
33/*
34 * ETM tracer state
35 */
36struct tracectx {
37 unsigned int etb_bufsz;
38 void __iomem *etb_regs;
39 void __iomem *etm_regs;
40 unsigned long flags;
41 int ncmppairs;
42 int etm_portsz;
43 struct device *dev;
44 struct clk *emu_clk;
45 struct mutex mutex;
46};
47
33static struct tracectx tracer; 48static struct tracectx tracer;
34 49
35static inline bool trace_isrunning(struct tracectx *t) 50static inline bool trace_isrunning(struct tracectx *t)
@@ -314,6 +329,7 @@ static const struct file_operations etb_fops = {
314 .read = etb_read, 329 .read = etb_read,
315 .open = etb_open, 330 .open = etb_open,
316 .release = etb_release, 331 .release = etb_release,
332 .llseek = no_llseek,
317}; 333};
318 334
319static struct miscdevice etb_miscdev = { 335static struct miscdevice etb_miscdev = {
@@ -322,7 +338,7 @@ static struct miscdevice etb_miscdev = {
322 .fops = &etb_fops, 338 .fops = &etb_fops,
323}; 339};
324 340
325static int __init etb_probe(struct amba_device *dev, struct amba_id *id) 341static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
326{ 342{
327 struct tracectx *t = &tracer; 343 struct tracectx *t = &tracer;
328 int ret = 0; 344 int ret = 0;
@@ -514,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
514static struct kobj_attribute trace_mode_attr = 530static struct kobj_attribute trace_mode_attr =
515 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); 531 __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
516 532
517static int __init etm_probe(struct amba_device *dev, struct amba_id *id) 533static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
518{ 534{
519 struct tracectx *t = &tracer; 535 struct tracectx *t = &tracer;
520 int ret = 0; 536 int ret = 0;
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 6ff7919613d7..4c164ece5891 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -45,6 +45,7 @@
45#include <asm/fiq.h> 45#include <asm/fiq.h>
46#include <asm/irq.h> 46#include <asm/irq.h>
47#include <asm/system.h> 47#include <asm/system.h>
48#include <asm/traps.h>
48 49
49static unsigned long no_fiq_insn; 50static unsigned long no_fiq_insn;
50 51
@@ -67,63 +68,27 @@ static struct fiq_handler default_owner = {
67 68
68static struct fiq_handler *current_fiq = &default_owner; 69static struct fiq_handler *current_fiq = &default_owner;
69 70
70int show_fiq_list(struct seq_file *p, void *v) 71int show_fiq_list(struct seq_file *p, int prec)
71{ 72{
72 if (current_fiq != &default_owner) 73 if (current_fiq != &default_owner)
73 seq_printf(p, "FIQ: %s\n", current_fiq->name); 74 seq_printf(p, "%*s: %s\n", prec, "FIQ",
75 current_fiq->name);
74 76
75 return 0; 77 return 0;
76} 78}
77 79
78void set_fiq_handler(void *start, unsigned int length) 80void set_fiq_handler(void *start, unsigned int length)
79{ 81{
82#if defined(CONFIG_CPU_USE_DOMAINS)
80 memcpy((void *)0xffff001c, start, length); 83 memcpy((void *)0xffff001c, start, length);
84#else
85 memcpy(vectors_page + 0x1c, start, length);
86#endif
81 flush_icache_range(0xffff001c, 0xffff001c + length); 87 flush_icache_range(0xffff001c, 0xffff001c + length);
82 if (!vectors_high()) 88 if (!vectors_high())
83 flush_icache_range(0x1c, 0x1c + length); 89 flush_icache_range(0x1c, 0x1c + length);
84} 90}
85 91
86/*
87 * Taking an interrupt in FIQ mode is death, so both these functions
88 * disable irqs for the duration. Note - these functions are almost
89 * entirely coded in assembly.
90 */
91void __naked set_fiq_regs(struct pt_regs *regs)
92{
93 register unsigned long tmp;
94 asm volatile (
95 "mov ip, sp\n\
96 stmfd sp!, {fp, ip, lr, pc}\n\
97 sub fp, ip, #4\n\
98 mrs %0, cpsr\n\
99 msr cpsr_c, %2 @ select FIQ mode\n\
100 mov r0, r0\n\
101 ldmia %1, {r8 - r14}\n\
102 msr cpsr_c, %0 @ return to SVC mode\n\
103 mov r0, r0\n\
104 ldmfd sp, {fp, sp, pc}"
105 : "=&r" (tmp)
106 : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
107}
108
109void __naked get_fiq_regs(struct pt_regs *regs)
110{
111 register unsigned long tmp;
112 asm volatile (
113 "mov ip, sp\n\
114 stmfd sp!, {fp, ip, lr, pc}\n\
115 sub fp, ip, #4\n\
116 mrs %0, cpsr\n\
117 msr cpsr_c, %2 @ select FIQ mode\n\
118 mov r0, r0\n\
119 stmia %1, {r8 - r14}\n\
120 msr cpsr_c, %0 @ return to SVC mode\n\
121 mov r0, r0\n\
122 ldmfd sp, {fp, sp, pc}"
123 : "=&r" (tmp)
124 : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
125}
126
127int claim_fiq(struct fiq_handler *f) 92int claim_fiq(struct fiq_handler *f)
128{ 93{
129 int ret = 0; 94 int ret = 0;
@@ -168,8 +133,8 @@ void disable_fiq(int fiq)
168} 133}
169 134
170EXPORT_SYMBOL(set_fiq_handler); 135EXPORT_SYMBOL(set_fiq_handler);
171EXPORT_SYMBOL(set_fiq_regs); 136EXPORT_SYMBOL(__set_fiq_regs); /* defined in fiqasm.S */
172EXPORT_SYMBOL(get_fiq_regs); 137EXPORT_SYMBOL(__get_fiq_regs); /* defined in fiqasm.S */
173EXPORT_SYMBOL(claim_fiq); 138EXPORT_SYMBOL(claim_fiq);
174EXPORT_SYMBOL(release_fiq); 139EXPORT_SYMBOL(release_fiq);
175EXPORT_SYMBOL(enable_fiq); 140EXPORT_SYMBOL(enable_fiq);
diff --git a/arch/arm/kernel/fiqasm.S b/arch/arm/kernel/fiqasm.S
new file mode 100644
index 000000000000..207f9d652010
--- /dev/null
+++ b/arch/arm/kernel/fiqasm.S
@@ -0,0 +1,49 @@
1/*
2 * linux/arch/arm/kernel/fiqasm.S
3 *
4 * Derived from code originally in linux/arch/arm/kernel/fiq.c:
5 *
6 * Copyright (C) 1998 Russell King
7 * Copyright (C) 1998, 1999 Phil Blundell
8 * Copyright (C) 2011, Linaro Limited
9 *
10 * FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
11 *
12 * FIQ support re-written by Russell King to be more generic
13 *
14 * v7/Thumb-2 compatibility modifications by Linaro Limited, 2011.
15 */
16
17#include <linux/linkage.h>
18#include <asm/assembler.h>
19
20/*
21 * Taking an interrupt in FIQ mode is death, so both these functions
22 * disable irqs for the duration.
23 */
24
25ENTRY(__set_fiq_regs)
26 mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
27 mrs r1, cpsr
28 msr cpsr_c, r2 @ select FIQ mode
29 mov r0, r0 @ avoid hazard prior to ARMv4
30 ldmia r0!, {r8 - r12}
31 ldr sp, [r0], #4
32 ldr lr, [r0]
33 msr cpsr_c, r1 @ return to SVC mode
34 mov r0, r0 @ avoid hazard prior to ARMv4
35 mov pc, lr
36ENDPROC(__set_fiq_regs)
37
38ENTRY(__get_fiq_regs)
39 mov r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
40 mrs r1, cpsr
41 msr cpsr_c, r2 @ select FIQ mode
42 mov r0, r0 @ avoid hazard prior to ARMv4
43 stmia r0!, {r8 - r12}
44 str sp, [r0], #4
45 str lr, [r0]
46 msr cpsr_c, r1 @ return to SVC mode
47 mov r0, r0 @ avoid hazard prior to ARMv4
48 mov pc, lr
49ENDPROC(__get_fiq_regs)
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index 0298286ad4ad..c0062ad1e847 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -2,102 +2,287 @@
2 * Dynamic function tracing support. 2 * Dynamic function tracing support.
3 * 3 *
4 * Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com> 4 * Copyright (C) 2008 Abhishek Sagar <sagar.abhishek@gmail.com>
5 * Copyright (C) 2010 Rabin Vincent <rabin@rab.in>
5 * 6 *
6 * For licencing details, see COPYING. 7 * For licencing details, see COPYING.
7 * 8 *
8 * Defines low-level handling of mcount calls when the kernel 9 * Defines low-level handling of mcount calls when the kernel
9 * is compiled with the -pg flag. When using dynamic ftrace, the 10 * is compiled with the -pg flag. When using dynamic ftrace, the
10 * mcount call-sites get patched lazily with NOP till they are 11 * mcount call-sites get patched with NOP till they are enabled.
11 * enabled. All code mutation routines here take effect atomically. 12 * All code mutation routines here are called under stop_machine().
12 */ 13 */
13 14
14#include <linux/ftrace.h> 15#include <linux/ftrace.h>
16#include <linux/uaccess.h>
15 17
16#include <asm/cacheflush.h> 18#include <asm/cacheflush.h>
17#include <asm/ftrace.h> 19#include <asm/ftrace.h>
18 20
19#define PC_OFFSET 8 21#ifdef CONFIG_THUMB2_KERNEL
20#define BL_OPCODE 0xeb000000 22#define NOP 0xeb04f85d /* pop.w {lr} */
21#define BL_OFFSET_MASK 0x00ffffff 23#else
24#define NOP 0xe8bd4000 /* pop {lr} */
25#endif
22 26
23static unsigned long bl_insn; 27#ifdef CONFIG_DYNAMIC_FTRACE
24static const unsigned long NOP = 0xe1a00000; /* mov r0, r0 */ 28#ifdef CONFIG_OLD_MCOUNT
29#define OLD_MCOUNT_ADDR ((unsigned long) mcount)
30#define OLD_FTRACE_ADDR ((unsigned long) ftrace_caller_old)
25 31
26unsigned char *ftrace_nop_replace(void) 32#define OLD_NOP 0xe1a00000 /* mov r0, r0 */
33
34static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
35{
36 return rec->arch.old_mcount ? OLD_NOP : NOP;
37}
38
39static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
40{
41 if (!rec->arch.old_mcount)
42 return addr;
43
44 if (addr == MCOUNT_ADDR)
45 addr = OLD_MCOUNT_ADDR;
46 else if (addr == FTRACE_ADDR)
47 addr = OLD_FTRACE_ADDR;
48
49 return addr;
50}
51#else
52static unsigned long ftrace_nop_replace(struct dyn_ftrace *rec)
53{
54 return NOP;
55}
56
57static unsigned long adjust_address(struct dyn_ftrace *rec, unsigned long addr)
27{ 58{
28 return (char *)&NOP; 59 return addr;
29} 60}
61#endif
62
63#ifdef CONFIG_THUMB2_KERNEL
64static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
65 bool link)
66{
67 unsigned long s, j1, j2, i1, i2, imm10, imm11;
68 unsigned long first, second;
69 long offset;
70
71 offset = (long)addr - (long)(pc + 4);
72 if (offset < -16777216 || offset > 16777214) {
73 WARN_ON_ONCE(1);
74 return 0;
75 }
76
77 s = (offset >> 24) & 0x1;
78 i1 = (offset >> 23) & 0x1;
79 i2 = (offset >> 22) & 0x1;
80 imm10 = (offset >> 12) & 0x3ff;
81 imm11 = (offset >> 1) & 0x7ff;
82
83 j1 = (!i1) ^ s;
84 j2 = (!i2) ^ s;
85
86 first = 0xf000 | (s << 10) | imm10;
87 second = 0x9000 | (j1 << 13) | (j2 << 11) | imm11;
88 if (link)
89 second |= 1 << 14;
30 90
31/* construct a branch (BL) instruction to addr */ 91 return (second << 16) | first;
32unsigned char *ftrace_call_replace(unsigned long pc, unsigned long addr) 92}
93#else
94static unsigned long ftrace_gen_branch(unsigned long pc, unsigned long addr,
95 bool link)
33{ 96{
97 unsigned long opcode = 0xea000000;
34 long offset; 98 long offset;
35 99
36 offset = (long)addr - (long)(pc + PC_OFFSET); 100 if (link)
101 opcode |= 1 << 24;
102
103 offset = (long)addr - (long)(pc + 8);
37 if (unlikely(offset < -33554432 || offset > 33554428)) { 104 if (unlikely(offset < -33554432 || offset > 33554428)) {
38 /* Can't generate branches that far (from ARM ARM). Ftrace 105 /* Can't generate branches that far (from ARM ARM). Ftrace
39 * doesn't generate branches outside of kernel text. 106 * doesn't generate branches outside of kernel text.
40 */ 107 */
41 WARN_ON_ONCE(1); 108 WARN_ON_ONCE(1);
42 return NULL; 109 return 0;
43 } 110 }
44 offset = (offset >> 2) & BL_OFFSET_MASK; 111
45 bl_insn = BL_OPCODE | offset; 112 offset = (offset >> 2) & 0x00ffffff;
46 return (unsigned char *)&bl_insn; 113
114 return opcode | offset;
47} 115}
116#endif
48 117
49int ftrace_modify_code(unsigned long pc, unsigned char *old_code, 118static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
50 unsigned char *new_code)
51{ 119{
52 unsigned long err = 0, replaced = 0, old, new; 120 return ftrace_gen_branch(pc, addr, true);
53 121}
54 old = *(unsigned long *)old_code;
55 new = *(unsigned long *)new_code;
56 122
57 __asm__ __volatile__ ( 123static int ftrace_modify_code(unsigned long pc, unsigned long old,
58 "1: ldr %1, [%2] \n" 124 unsigned long new)
59 " cmp %1, %4 \n" 125{
60 "2: streq %3, [%2] \n" 126 unsigned long replaced;
61 " cmpne %1, %3 \n"
62 " movne %0, #2 \n"
63 "3:\n"
64 127
65 ".pushsection .fixup, \"ax\"\n" 128 if (probe_kernel_read(&replaced, (void *)pc, MCOUNT_INSN_SIZE))
66 "4: mov %0, #1 \n" 129 return -EFAULT;
67 " b 3b \n"
68 ".popsection\n"
69 130
70 ".pushsection __ex_table, \"a\"\n" 131 if (replaced != old)
71 " .long 1b, 4b \n" 132 return -EINVAL;
72 " .long 2b, 4b \n"
73 ".popsection\n"
74 133
75 : "=r"(err), "=r"(replaced) 134 if (probe_kernel_write((void *)pc, &new, MCOUNT_INSN_SIZE))
76 : "r"(pc), "r"(new), "r"(old), "0"(err), "1"(replaced) 135 return -EPERM;
77 : "memory");
78 136
79 if (!err && (replaced == old)) 137 flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
80 flush_icache_range(pc, pc + MCOUNT_INSN_SIZE);
81 138
82 return err; 139 return 0;
83} 140}
84 141
85int ftrace_update_ftrace_func(ftrace_func_t func) 142int ftrace_update_ftrace_func(ftrace_func_t func)
86{ 143{
87 int ret;
88 unsigned long pc, old; 144 unsigned long pc, old;
89 unsigned char *new; 145 unsigned long new;
146 int ret;
90 147
91 pc = (unsigned long)&ftrace_call; 148 pc = (unsigned long)&ftrace_call;
92 memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE); 149 memcpy(&old, &ftrace_call, MCOUNT_INSN_SIZE);
93 new = ftrace_call_replace(pc, (unsigned long)func); 150 new = ftrace_call_replace(pc, (unsigned long)func);
94 ret = ftrace_modify_code(pc, (unsigned char *)&old, new); 151
152 ret = ftrace_modify_code(pc, old, new);
153
154#ifdef CONFIG_OLD_MCOUNT
155 if (!ret) {
156 pc = (unsigned long)&ftrace_call_old;
157 memcpy(&old, &ftrace_call_old, MCOUNT_INSN_SIZE);
158 new = ftrace_call_replace(pc, (unsigned long)func);
159
160 ret = ftrace_modify_code(pc, old, new);
161 }
162#endif
163
164 return ret;
165}
166
167int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
168{
169 unsigned long new, old;
170 unsigned long ip = rec->ip;
171
172 old = ftrace_nop_replace(rec);
173 new = ftrace_call_replace(ip, adjust_address(rec, addr));
174
175 return ftrace_modify_code(rec->ip, old, new);
176}
177
178int ftrace_make_nop(struct module *mod,
179 struct dyn_ftrace *rec, unsigned long addr)
180{
181 unsigned long ip = rec->ip;
182 unsigned long old;
183 unsigned long new;
184 int ret;
185
186 old = ftrace_call_replace(ip, adjust_address(rec, addr));
187 new = ftrace_nop_replace(rec);
188 ret = ftrace_modify_code(ip, old, new);
189
190#ifdef CONFIG_OLD_MCOUNT
191 if (ret == -EINVAL && addr == MCOUNT_ADDR) {
192 rec->arch.old_mcount = true;
193
194 old = ftrace_call_replace(ip, adjust_address(rec, addr));
195 new = ftrace_nop_replace(rec);
196 ret = ftrace_modify_code(ip, old, new);
197 }
198#endif
199
95 return ret; 200 return ret;
96} 201}
97 202
98/* run from ftrace_init with irqs disabled */
99int __init ftrace_dyn_arch_init(void *data) 203int __init ftrace_dyn_arch_init(void *data)
100{ 204{
101 ftrace_mcount_set(data); 205 *(unsigned long *)data = 0;
206
102 return 0; 207 return 0;
103} 208}
209#endif /* CONFIG_DYNAMIC_FTRACE */
210
211#ifdef CONFIG_FUNCTION_GRAPH_TRACER
212void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
213 unsigned long frame_pointer)
214{
215 unsigned long return_hooker = (unsigned long) &return_to_handler;
216 struct ftrace_graph_ent trace;
217 unsigned long old;
218 int err;
219
220 if (unlikely(atomic_read(&current->tracing_graph_pause)))
221 return;
222
223 old = *parent;
224 *parent = return_hooker;
225
226 err = ftrace_push_return_trace(old, self_addr, &trace.depth,
227 frame_pointer);
228 if (err == -EBUSY) {
229 *parent = old;
230 return;
231 }
232
233 trace.func = self_addr;
234
235 /* Only trace if the calling function expects to */
236 if (!ftrace_graph_entry(&trace)) {
237 current->curr_ret_stack--;
238 *parent = old;
239 }
240}
241
242#ifdef CONFIG_DYNAMIC_FTRACE
243extern unsigned long ftrace_graph_call;
244extern unsigned long ftrace_graph_call_old;
245extern void ftrace_graph_caller_old(void);
246
247static int __ftrace_modify_caller(unsigned long *callsite,
248 void (*func) (void), bool enable)
249{
250 unsigned long caller_fn = (unsigned long) func;
251 unsigned long pc = (unsigned long) callsite;
252 unsigned long branch = ftrace_gen_branch(pc, caller_fn, false);
253 unsigned long nop = 0xe1a00000; /* mov r0, r0 */
254 unsigned long old = enable ? nop : branch;
255 unsigned long new = enable ? branch : nop;
256
257 return ftrace_modify_code(pc, old, new);
258}
259
260static int ftrace_modify_graph_caller(bool enable)
261{
262 int ret;
263
264 ret = __ftrace_modify_caller(&ftrace_graph_call,
265 ftrace_graph_caller,
266 enable);
267
268#ifdef CONFIG_OLD_MCOUNT
269 if (!ret)
270 ret = __ftrace_modify_caller(&ftrace_graph_call_old,
271 ftrace_graph_caller_old,
272 enable);
273#endif
274
275 return ret;
276}
277
278int ftrace_enable_ftrace_graph_caller(void)
279{
280 return ftrace_modify_graph_caller(true);
281}
282
283int ftrace_disable_ftrace_graph_caller(void)
284{
285 return ftrace_modify_graph_caller(false);
286}
287#endif /* CONFIG_DYNAMIC_FTRACE */
288#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/arch/arm/kernel/head-common.S b/arch/arm/kernel/head-common.S
index b9505aa267c0..854bd22380d3 100644
--- a/arch/arm/kernel/head-common.S
+++ b/arch/arm/kernel/head-common.S
@@ -15,19 +15,57 @@
15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2) 15#define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
16#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2) 16#define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
17 17
18 .align 2 18#ifdef CONFIG_CPU_BIG_ENDIAN
19 .type __switch_data, %object 19#define OF_DT_MAGIC 0xd00dfeed
20__switch_data: 20#else
21 .long __mmap_switched 21#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
22 .long __data_loc @ r4 22#endif
23 .long _data @ r5 23
24 .long __bss_start @ r6 24/*
25 .long _end @ r7 25 * Exception handling. Something went wrong and we can't proceed. We
26 .long processor_id @ r4 26 * ought to tell the user, but since we don't have any guarantee that
27 .long __machine_arch_type @ r5 27 * we're even running on the right architecture, we do virtually nothing.
28 .long __atags_pointer @ r6 28 *
29 .long cr_alignment @ r7 29 * If CONFIG_DEBUG_LL is set we try to print out something about the error
30 .long init_thread_union + THREAD_START_SP @ sp 30 * and hope for the best (useful if bootloader fails to pass a proper
31 * machine ID for example).
32 */
33 __HEAD
34
35/* Determine validity of the r2 atags pointer. The heuristic requires
36 * that the pointer be aligned, in the first 16k of physical RAM and
37 * that the ATAG_CORE marker is first and present. If CONFIG_OF_FLATTREE
38 * is selected, then it will also accept a dtb pointer. Future revisions
39 * of this function may be more lenient with the physical address and
40 * may also be able to move the ATAGS block if necessary.
41 *
42 * Returns:
43 * r2 either valid atags pointer, valid dtb pointer, or zero
44 * r5, r6 corrupted
45 */
46__vet_atags:
47 tst r2, #0x3 @ aligned?
48 bne 1f
49
50 ldr r5, [r2, #0]
51#ifdef CONFIG_OF_FLATTREE
52 ldr r6, =OF_DT_MAGIC @ is it a DTB?
53 cmp r5, r6
54 beq 2f
55#endif
56 cmp r5, #ATAG_CORE_SIZE @ is first tag ATAG_CORE?
57 cmpne r5, #ATAG_CORE_SIZE_EMPTY
58 bne 1f
59 ldr r5, [r2, #4]
60 ldr r6, =ATAG_CORE
61 cmp r5, r6
62 bne 1f
63
642: mov pc, lr @ atag/dtb pointer is ok
65
661: mov r2, #0
67 mov pc, lr
68ENDPROC(__vet_atags)
31 69
32/* 70/*
33 * The following fragment of code is executed with the MMU on in MMU mode, 71 * The following fragment of code is executed with the MMU on in MMU mode,
@@ -35,11 +73,12 @@ __switch_data:
35 * 73 *
36 * r0 = cp#15 control register 74 * r0 = cp#15 control register
37 * r1 = machine ID 75 * r1 = machine ID
38 * r2 = atags pointer 76 * r2 = atags/dtb pointer
39 * r9 = processor ID 77 * r9 = processor ID
40 */ 78 */
79 __INIT
41__mmap_switched: 80__mmap_switched:
42 adr r3, __switch_data + 4 81 adr r3, __mmap_switched_data
43 82
44 ldmia r3!, {r4, r5, r6, r7} 83 ldmia r3!, {r4, r5, r6, r7}
45 cmp r4, r5 @ Copy data segment if needed 84 cmp r4, r5 @ Copy data segment if needed
@@ -64,85 +103,30 @@ __mmap_switched:
64 b start_kernel 103 b start_kernel
65ENDPROC(__mmap_switched) 104ENDPROC(__mmap_switched)
66 105
67/* 106 .align 2
68 * Exception handling. Something went wrong and we can't proceed. We 107 .type __mmap_switched_data, %object
69 * ought to tell the user, but since we don't have any guarantee that 108__mmap_switched_data:
70 * we're even running on the right architecture, we do virtually nothing. 109 .long __data_loc @ r4
71 * 110 .long _sdata @ r5
72 * If CONFIG_DEBUG_LL is set we try to print out something about the error 111 .long __bss_start @ r6
73 * and hope for the best (useful if bootloader fails to pass a proper 112 .long _end @ r7
74 * machine ID for example). 113 .long processor_id @ r4
75 */ 114 .long __machine_arch_type @ r5
76__error_p: 115 .long __atags_pointer @ r6
77#ifdef CONFIG_DEBUG_LL 116 .long cr_alignment @ r7
78 adr r0, str_p1 117 .long init_thread_union + THREAD_START_SP @ sp
79 bl printascii 118 .size __mmap_switched_data, . - __mmap_switched_data
80 mov r0, r9
81 bl printhex8
82 adr r0, str_p2
83 bl printascii
84 b __error
85str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x"
86str_p2: .asciz ").\n"
87 .align
88#endif
89ENDPROC(__error_p)
90
91__error_a:
92#ifdef CONFIG_DEBUG_LL
93 mov r4, r1 @ preserve machine ID
94 adr r0, str_a1
95 bl printascii
96 mov r0, r4
97 bl printhex8
98 adr r0, str_a2
99 bl printascii
100 adr r3, 4f
101 ldmia r3, {r4, r5, r6} @ get machine desc list
102 sub r4, r3, r4 @ get offset between virt&phys
103 add r5, r5, r4 @ convert virt addresses to
104 add r6, r6, r4 @ physical address space
1051: ldr r0, [r5, #MACHINFO_TYPE] @ get machine type
106 bl printhex8
107 mov r0, #'\t'
108 bl printch
109 ldr r0, [r5, #MACHINFO_NAME] @ get machine name
110 add r0, r0, r4
111 bl printascii
112 mov r0, #'\n'
113 bl printch
114 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
115 cmp r5, r6
116 blo 1b
117 adr r0, str_a3
118 bl printascii
119 b __error
120ENDPROC(__error_a)
121
122str_a1: .asciz "\nError: unrecognized/unsupported machine ID (r1 = 0x"
123str_a2: .asciz ").\n\nAvailable machine support:\n\nID (hex)\tNAME\n"
124str_a3: .asciz "\nPlease check your kernel config and/or bootloader.\n"
125 .align
126#endif
127 119
128__error:
129#ifdef CONFIG_ARCH_RPC
130/* 120/*
131 * Turn the screen red on a error - RiscPC only. 121 * This provides a C-API version of __lookup_processor_type
132 */ 122 */
133 mov r0, #0x02000000 123ENTRY(lookup_processor_type)
134 mov r3, #0x11 124 stmfd sp!, {r4 - r6, r9, lr}
135 orr r3, r3, r3, lsl #8 125 mov r9, r0
136 orr r3, r3, r3, lsl #16 126 bl __lookup_processor_type
137 str r3, [r0], #4 127 mov r0, r5
138 str r3, [r0], #4 128 ldmfd sp!, {r4 - r6, r9, pc}
139 str r3, [r0], #4 129ENDPROC(lookup_processor_type)
140 str r3, [r0], #4
141#endif
1421: mov r0, r0
143 b 1b
144ENDPROC(__error)
145
146 130
147/* 131/*
148 * Read processor ID register (CP#15, CR0), and look up in the linker-built 132 * Read processor ID register (CP#15, CR0), and look up in the linker-built
@@ -157,11 +141,11 @@ ENDPROC(__error)
157 * r5 = proc_info pointer in physical address space 141 * r5 = proc_info pointer in physical address space
158 * r9 = cpuid (preserved) 142 * r9 = cpuid (preserved)
159 */ 143 */
144 __CPUINIT
160__lookup_processor_type: 145__lookup_processor_type:
161 adr r3, 3f 146 adr r3, __lookup_processor_type_data
162 ldmia r3, {r5 - r7} 147 ldmia r3, {r4 - r6}
163 add r3, r3, #8 148 sub r3, r3, r4 @ get offset between virt&phys
164 sub r3, r3, r7 @ get offset between virt&phys
165 add r5, r5, r3 @ convert virt addresses to 149 add r5, r5, r3 @ convert virt addresses to
166 add r6, r6, r3 @ physical address space 150 add r6, r6, r3 @ physical address space
1671: ldmia r5, {r3, r4} @ value, mask 1511: ldmia r5, {r3, r4} @ value, mask
@@ -176,92 +160,45 @@ __lookup_processor_type:
176ENDPROC(__lookup_processor_type) 160ENDPROC(__lookup_processor_type)
177 161
178/* 162/*
179 * This provides a C-API version of the above function. 163 * Look in <asm/procinfo.h> for information about the __proc_info structure.
180 */
181ENTRY(lookup_processor_type)
182 stmfd sp!, {r4 - r7, r9, lr}
183 mov r9, r0
184 bl __lookup_processor_type
185 mov r0, r5
186 ldmfd sp!, {r4 - r7, r9, pc}
187ENDPROC(lookup_processor_type)
188
189/*
190 * Look in <asm/procinfo.h> and arch/arm/kernel/arch.[ch] for
191 * more information about the __proc_info and __arch_info structures.
192 */ 164 */
193 .align 2 165 .align 2
1943: .long __proc_info_begin 166 .type __lookup_processor_type_data, %object
167__lookup_processor_type_data:
168 .long .
169 .long __proc_info_begin
195 .long __proc_info_end 170 .long __proc_info_end
1964: .long . 171 .size __lookup_processor_type_data, . - __lookup_processor_type_data
197 .long __arch_info_begin
198 .long __arch_info_end
199 172
200/* 173__error_p:
201 * Lookup machine architecture in the linker-build list of architectures. 174#ifdef CONFIG_DEBUG_LL
202 * Note that we can't use the absolute addresses for the __arch_info 175 adr r0, str_p1
203 * lists since we aren't running with the MMU on (and therefore, we are 176 bl printascii
204 * not in the correct address space). We have to calculate the offset. 177 mov r0, r9
205 * 178 bl printhex8
206 * r1 = machine architecture number 179 adr r0, str_p2
207 * Returns: 180 bl printascii
208 * r3, r4, r6 corrupted 181 b __error
209 * r5 = mach_info pointer in physical address space 182str_p1: .asciz "\nError: unrecognized/unsupported processor variant (0x"
210 */ 183str_p2: .asciz ").\n"
211__lookup_machine_type: 184 .align
212 adr r3, 4b 185#endif
213 ldmia r3, {r4, r5, r6} 186ENDPROC(__error_p)
214 sub r3, r3, r4 @ get offset between virt&phys
215 add r5, r5, r3 @ convert virt addresses to
216 add r6, r6, r3 @ physical address space
2171: ldr r3, [r5, #MACHINFO_TYPE] @ get machine type
218 teq r3, r1 @ matches loader number?
219 beq 2f @ found
220 add r5, r5, #SIZEOF_MACHINE_DESC @ next machine_desc
221 cmp r5, r6
222 blo 1b
223 mov r5, #0 @ unknown machine
2242: mov pc, lr
225ENDPROC(__lookup_machine_type)
226 187
188__error:
189#ifdef CONFIG_ARCH_RPC
227/* 190/*
228 * This provides a C-API version of the above function. 191 * Turn the screen red on a error - RiscPC only.
229 */
230ENTRY(lookup_machine_type)
231 stmfd sp!, {r4 - r6, lr}
232 mov r1, r0
233 bl __lookup_machine_type
234 mov r0, r5
235 ldmfd sp!, {r4 - r6, pc}
236ENDPROC(lookup_machine_type)
237
238/* Determine validity of the r2 atags pointer. The heuristic requires
239 * that the pointer be aligned, in the first 16k of physical RAM and
240 * that the ATAG_CORE marker is first and present. Future revisions
241 * of this function may be more lenient with the physical address and
242 * may also be able to move the ATAGS block if necessary.
243 *
244 * r8 = machinfo
245 *
246 * Returns:
247 * r2 either valid atags pointer, or zero
248 * r5, r6 corrupted
249 */ 192 */
250__vet_atags: 193 mov r0, #0x02000000
251 tst r2, #0x3 @ aligned? 194 mov r3, #0x11
252 bne 1f 195 orr r3, r3, r3, lsl #8
253 196 orr r3, r3, r3, lsl #16
254 ldr r5, [r2, #0] @ is first tag ATAG_CORE? 197 str r3, [r0], #4
255 cmp r5, #ATAG_CORE_SIZE 198 str r3, [r0], #4
256 cmpne r5, #ATAG_CORE_SIZE_EMPTY 199 str r3, [r0], #4
257 bne 1f 200 str r3, [r0], #4
258 ldr r5, [r2, #4] 201#endif
259 ldr r6, =ATAG_CORE 2021: mov r0, r0
260 cmp r5, r6 203 b 1b
261 bne 1f 204ENDPROC(__error)
262
263 mov pc, lr @ atag pointer is ok
264
2651: mov r2, #0
266 mov pc, lr
267ENDPROC(__vet_atags)
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S
index 573b803dc6bf..6b1e0ad9ec3b 100644
--- a/arch/arm/kernel/head-nommu.S
+++ b/arch/arm/kernel/head-nommu.S
@@ -44,12 +44,7 @@ ENTRY(stext)
44 bl __lookup_processor_type @ r5=procinfo r9=cpuid 44 bl __lookup_processor_type @ r5=procinfo r9=cpuid
45 movs r10, r5 @ invalid processor (r5=0)? 45 movs r10, r5 @ invalid processor (r5=0)?
46 beq __error_p @ yes, error 'p' 46 beq __error_p @ yes, error 'p'
47 bl __lookup_machine_type @ r5=machinfo
48 movs r8, r5 @ invalid machine (r5=0)?
49 beq __error_a @ yes, error 'a'
50 47
51 ldr r13, __switch_data @ address to jump to after
52 @ the initialization is done
53 adr lr, BSYM(__after_proc_init) @ return (PIC) address 48 adr lr, BSYM(__after_proc_init) @ return (PIC) address
54 ARM( add pc, r10, #PROCINFO_INITFUNC ) 49 ARM( add pc, r10, #PROCINFO_INITFUNC )
55 THUMB( add r12, r10, #PROCINFO_INITFUNC ) 50 THUMB( add r12, r10, #PROCINFO_INITFUNC )
@@ -87,8 +82,7 @@ __after_proc_init:
87 mcr p15, 0, r0, c1, c0, 0 @ write control reg 82 mcr p15, 0, r0, c1, c0, 0 @ write control reg
88#endif /* CONFIG_CPU_CP15 */ 83#endif /* CONFIG_CPU_CP15 */
89 84
90 mov r3, r13 85 b __mmap_switched @ clear the BSS and jump
91 mov pc, r3 @ clear the BSS and jump
92 @ to start_kernel 86 @ to start_kernel
93ENDPROC(__after_proc_init) 87ENDPROC(__after_proc_init)
94 .ltorg 88 .ltorg
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index eb62bf947212..278c1b0ebb2e 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -22,14 +22,10 @@
22#include <asm/thread_info.h> 22#include <asm/thread_info.h>
23#include <asm/system.h> 23#include <asm/system.h>
24 24
25#if (PHYS_OFFSET & 0x001fffff) 25#ifdef CONFIG_DEBUG_LL
26#error "PHYS_OFFSET must be at an even 2MiB boundary!" 26#include <mach/debug-macro.S>
27#endif 27#endif
28 28
29#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
30#define KERNEL_RAM_PADDR (PHYS_OFFSET + TEXT_OFFSET)
31
32
33/* 29/*
34 * swapper_pg_dir is the virtual address of the initial page table. 30 * swapper_pg_dir is the virtual address of the initial page table.
35 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must 31 * We place the page tables 16K below KERNEL_RAM_VADDR. Therefore, we must
@@ -37,6 +33,7 @@
37 * the least significant 16 bits to be 0x8000, but we could probably 33 * the least significant 16 bits to be 0x8000, but we could probably
38 * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000. 34 * relax this restriction to KERNEL_RAM_VADDR >= PAGE_OFFSET + 0x4000.
39 */ 35 */
36#define KERNEL_RAM_VADDR (PAGE_OFFSET + TEXT_OFFSET)
40#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000 37#if (KERNEL_RAM_VADDR & 0xffff) != 0x8000
41#error KERNEL_RAM_VADDR must start at 0xXXXX8000 38#error KERNEL_RAM_VADDR must start at 0xXXXX8000
42#endif 39#endif
@@ -44,8 +41,8 @@
44 .globl swapper_pg_dir 41 .globl swapper_pg_dir
45 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000 42 .equ swapper_pg_dir, KERNEL_RAM_VADDR - 0x4000
46 43
47 .macro pgtbl, rd 44 .macro pgtbl, rd, phys
48 ldr \rd, =(KERNEL_RAM_PADDR - 0x4000) 45 add \rd, \phys, #TEXT_OFFSET - 0x4000
49 .endm 46 .endm
50 47
51#ifdef CONFIG_XIP_KERNEL 48#ifdef CONFIG_XIP_KERNEL
@@ -62,7 +59,7 @@
62 * 59 *
63 * This is normally called from the decompressor code. The requirements 60 * This is normally called from the decompressor code. The requirements
64 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0, 61 * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
65 * r1 = machine nr, r2 = atags pointer. 62 * r1 = machine nr, r2 = atags or dtb pointer.
66 * 63 *
67 * This code is mostly position independent, so if you link the kernel at 64 * This code is mostly position independent, so if you link the kernel at
68 * 0xc0008000, you call this at __pa(0xc0008000). 65 * 0xc0008000, you call this at __pa(0xc0008000).
@@ -81,29 +78,210 @@ ENTRY(stext)
81 mrc p15, 0, r9, c0, c0 @ get processor id 78 mrc p15, 0, r9, c0, c0 @ get processor id
82 bl __lookup_processor_type @ r5=procinfo r9=cpuid 79 bl __lookup_processor_type @ r5=procinfo r9=cpuid
83 movs r10, r5 @ invalid processor (r5=0)? 80 movs r10, r5 @ invalid processor (r5=0)?
81 THUMB( it eq ) @ force fixup-able long branch encoding
84 beq __error_p @ yes, error 'p' 82 beq __error_p @ yes, error 'p'
85 bl __lookup_machine_type @ r5=machinfo 83
86 movs r8, r5 @ invalid machine (r5=0)? 84#ifndef CONFIG_XIP_KERNEL
87 beq __error_a @ yes, error 'a' 85 adr r3, 2f
86 ldmia r3, {r4, r8}
87 sub r4, r3, r4 @ (PHYS_OFFSET - PAGE_OFFSET)
88 add r8, r8, r4 @ PHYS_OFFSET
89#else
90 ldr r8, =PLAT_PHYS_OFFSET
91#endif
92
93 /*
94 * r1 = machine no, r2 = atags or dtb,
95 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
96 */
88 bl __vet_atags 97 bl __vet_atags
98#ifdef CONFIG_SMP_ON_UP
99 bl __fixup_smp
100#endif
101#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
102 bl __fixup_pv_table
103#endif
89 bl __create_page_tables 104 bl __create_page_tables
90 105
91 /* 106 /*
92 * The following calls CPU specific code in a position independent 107 * The following calls CPU specific code in a position independent
93 * manner. See arch/arm/mm/proc-*.S for details. r10 = base of 108 * manner. See arch/arm/mm/proc-*.S for details. r10 = base of
94 * xxx_proc_info structure selected by __lookup_machine_type 109 * xxx_proc_info structure selected by __lookup_processor_type
95 * above. On return, the CPU will be ready for the MMU to be 110 * above. On return, the CPU will be ready for the MMU to be
96 * turned on, and r0 will hold the CPU control register value. 111 * turned on, and r0 will hold the CPU control register value.
97 */ 112 */
98 ldr r13, __switch_data @ address to jump to after 113 ldr r13, =__mmap_switched @ address to jump to after
99 @ mmu has been enabled 114 @ mmu has been enabled
100 adr lr, BSYM(__enable_mmu) @ return (PIC) address 115 adr lr, BSYM(1f) @ return (PIC) address
116 mov r8, r4 @ set TTBR1 to swapper_pg_dir
101 ARM( add pc, r10, #PROCINFO_INITFUNC ) 117 ARM( add pc, r10, #PROCINFO_INITFUNC )
102 THUMB( add r12, r10, #PROCINFO_INITFUNC ) 118 THUMB( add r12, r10, #PROCINFO_INITFUNC )
103 THUMB( mov pc, r12 ) 119 THUMB( mov pc, r12 )
1201: b __enable_mmu
104ENDPROC(stext) 121ENDPROC(stext)
122 .ltorg
123#ifndef CONFIG_XIP_KERNEL
1242: .long .
125 .long PAGE_OFFSET
126#endif
127
128/*
129 * Setup the initial page tables. We only setup the barest
130 * amount which are required to get the kernel running, which
131 * generally means mapping in the kernel code.
132 *
133 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
134 *
135 * Returns:
136 * r0, r3, r5-r7 corrupted
137 * r4 = physical page table address
138 */
139__create_page_tables:
140 pgtbl r4, r8 @ page table address
141
142 /*
143 * Clear the 16K level 1 swapper page table
144 */
145 mov r0, r4
146 mov r3, #0
147 add r6, r0, #0x4000
1481: str r3, [r0], #4
149 str r3, [r0], #4
150 str r3, [r0], #4
151 str r3, [r0], #4
152 teq r0, r6
153 bne 1b
154
155 ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags
156
157 /*
158 * Create identity mapping to cater for __enable_mmu.
159 * This identity mapping will be removed by paging_init().
160 */
161 adr r0, __enable_mmu_loc
162 ldmia r0, {r3, r5, r6}
163 sub r0, r0, r3 @ virt->phys offset
164 add r5, r5, r0 @ phys __enable_mmu
165 add r6, r6, r0 @ phys __enable_mmu_end
166 mov r5, r5, lsr #20
167 mov r6, r6, lsr #20
168
1691: orr r3, r7, r5, lsl #20 @ flags + kernel base
170 str r3, [r4, r5, lsl #2] @ identity mapping
171 teq r5, r6
172 addne r5, r5, #1 @ next section
173 bne 1b
174
175 /*
176 * Now setup the pagetables for our kernel direct
177 * mapped region.
178 */
179 mov r3, pc
180 mov r3, r3, lsr #20
181 orr r3, r7, r3, lsl #20
182 add r0, r4, #(KERNEL_START & 0xff000000) >> 18
183 str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
184 ldr r6, =(KERNEL_END - 1)
185 add r0, r0, #4
186 add r6, r4, r6, lsr #18
1871: cmp r0, r6
188 add r3, r3, #1 << 20
189 strls r3, [r0], #4
190 bls 1b
191
192#ifdef CONFIG_XIP_KERNEL
193 /*
194 * Map some ram to cover our .data and .bss areas.
195 */
196 add r3, r8, #TEXT_OFFSET
197 orr r3, r3, r7
198 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
199 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
200 ldr r6, =(_end - 1)
201 add r0, r0, #4
202 add r6, r4, r6, lsr #18
2031: cmp r0, r6
204 add r3, r3, #1 << 20
205 strls r3, [r0], #4
206 bls 1b
207#endif
208
209 /*
210 * Then map boot params address in r2 or
211 * the first 1MB of ram if boot params address is not specified.
212 */
213 mov r0, r2, lsr #20
214 movs r0, r0, lsl #20
215 moveq r0, r8
216 sub r3, r0, r8
217 add r3, r3, #PAGE_OFFSET
218 add r3, r4, r3, lsr #18
219 orr r6, r7, r0
220 str r6, [r3]
221
222#ifdef CONFIG_DEBUG_LL
223#ifndef CONFIG_DEBUG_ICEDCC
224 /*
225 * Map in IO space for serial debugging.
226 * This allows debug messages to be output
227 * via a serial console before paging_init.
228 */
229 addruart r7, r3
230
231 mov r3, r3, lsr #20
232 mov r3, r3, lsl #2
233
234 add r0, r4, r3
235 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long)
236 cmp r3, #0x0800 @ limit to 512MB
237 movhi r3, #0x0800
238 add r6, r0, r3
239 mov r3, r7, lsr #20
240 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
241 orr r3, r7, r3, lsl #20
2421: str r3, [r0], #4
243 add r3, r3, #1 << 20
244 teq r0, r6
245 bne 1b
246
247#else /* CONFIG_DEBUG_ICEDCC */
248 /* we don't need any serial debugging mappings for ICEDCC */
249 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags
250#endif /* !CONFIG_DEBUG_ICEDCC */
251
252#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS)
253 /*
254 * If we're using the NetWinder or CATS, we also need to map
255 * in the 16550-type serial port for the debug messages
256 */
257 add r0, r4, #0xff000000 >> 18
258 orr r3, r7, #0x7c000000
259 str r3, [r0]
260#endif
261#ifdef CONFIG_ARCH_RPC
262 /*
263 * Map in screen at 0x02000000 & SCREEN2_BASE
264 * Similar reasons here - for debug. This is
265 * only for Acorn RiscPC architectures.
266 */
267 add r0, r4, #0x02000000 >> 18
268 orr r3, r7, #0x02000000
269 str r3, [r0]
270 add r0, r4, #0xd8000000 >> 18
271 str r3, [r0]
272#endif
273#endif
274 mov pc, lr
275ENDPROC(__create_page_tables)
276 .ltorg
277 .align
278__enable_mmu_loc:
279 .long .
280 .long __enable_mmu
281 .long __enable_mmu_end
105 282
106#if defined(CONFIG_SMP) 283#if defined(CONFIG_SMP)
284 __CPUINIT
107ENTRY(secondary_startup) 285ENTRY(secondary_startup)
108 /* 286 /*
109 * Common entry point for secondary CPUs. 287 * Common entry point for secondary CPUs.
@@ -117,15 +295,18 @@ ENTRY(secondary_startup)
117 bl __lookup_processor_type 295 bl __lookup_processor_type
118 movs r10, r5 @ invalid processor? 296 movs r10, r5 @ invalid processor?
119 moveq r0, #'p' @ yes, error 'p' 297 moveq r0, #'p' @ yes, error 'p'
120 beq __error 298 THUMB( it eq ) @ force fixup-able long branch encoding
299 beq __error_p
121 300
122 /* 301 /*
123 * Use the page tables supplied from __cpu_up. 302 * Use the page tables supplied from __cpu_up.
124 */ 303 */
125 adr r4, __secondary_data 304 adr r4, __secondary_data
126 ldmia r4, {r5, r7, r12} @ address to jump to after 305 ldmia r4, {r5, r7, r12} @ address to jump to after
127 sub r4, r4, r5 @ mmu has been enabled 306 sub lr, r4, r5 @ mmu has been enabled
128 ldr r4, [r7, r4] @ get secondary_data.pgdir 307 ldr r4, [r7, lr] @ get secondary_data.pgdir
308 add r7, r7, #4
309 ldr r8, [r7, lr] @ get secondary_data.swapper_pg_dir
129 adr lr, BSYM(__enable_mmu) @ return address 310 adr lr, BSYM(__enable_mmu) @ return address
130 mov r13, r12 @ __secondary_switched address 311 mov r13, r12 @ __secondary_switched address
131 ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor 312 ARM( add pc, r10, #PROCINFO_INITFUNC ) @ initialise processor
@@ -143,6 +324,8 @@ ENTRY(__secondary_switched)
143 b secondary_start_kernel 324 b secondary_start_kernel
144ENDPROC(__secondary_switched) 325ENDPROC(__secondary_switched)
145 326
327 .align
328
146 .type __secondary_data, %object 329 .type __secondary_data, %object
147__secondary_data: 330__secondary_data:
148 .long . 331 .long .
@@ -156,6 +339,13 @@ __secondary_data:
156 * Setup common bits before finally enabling the MMU. Essentially 339 * Setup common bits before finally enabling the MMU. Essentially
157 * this is just loading the page table pointer and domain access 340 * this is just loading the page table pointer and domain access
158 * registers. 341 * registers.
342 *
343 * r0 = cp#15 control register
344 * r1 = machine ID
345 * r2 = atags or dtb pointer
346 * r4 = page table pointer
347 * r9 = processor ID
348 * r13 = *virtual* address to jump to upon completion
159 */ 349 */
160__enable_mmu: 350__enable_mmu:
161#ifdef CONFIG_ALIGNMENT_TRAP 351#ifdef CONFIG_ALIGNMENT_TRAP
@@ -188,6 +378,9 @@ ENDPROC(__enable_mmu)
188 * mailing list archives BEFORE sending another post to the list. 378 * mailing list archives BEFORE sending another post to the list.
189 * 379 *
190 * r0 = cp#15 control register 380 * r0 = cp#15 control register
381 * r1 = machine ID
382 * r2 = atags or dtb pointer
383 * r9 = processor ID
191 * r13 = *virtual* address to jump to upon completion 384 * r13 = *virtual* address to jump to upon completion
192 * 385 *
193 * other registers depend on the function called upon completion 386 * other registers depend on the function called upon completion
@@ -200,137 +393,200 @@ __turn_mmu_on:
200 mov r3, r3 393 mov r3, r3
201 mov r3, r13 394 mov r3, r13
202 mov pc, r3 395 mov pc, r3
396__enable_mmu_end:
203ENDPROC(__turn_mmu_on) 397ENDPROC(__turn_mmu_on)
204 398
205 399
206/* 400#ifdef CONFIG_SMP_ON_UP
207 * Setup the initial page tables. We only setup the barest 401 __INIT
208 * amount which are required to get the kernel running, which 402__fixup_smp:
209 * generally means mapping in the kernel code. 403 and r3, r9, #0x000f0000 @ architecture version
210 * 404 teq r3, #0x000f0000 @ CPU ID supported?
211 * r8 = machinfo 405 bne __fixup_smp_on_up @ no, assume UP
212 * r9 = cpuid
213 * r10 = procinfo
214 *
215 * Returns:
216 * r0, r3, r6, r7 corrupted
217 * r4 = physical page table address
218 */
219__create_page_tables:
220 pgtbl r4 @ page table address
221 406
222 /* 407 bic r3, r9, #0x00ff0000
223 * Clear the 16K level 1 swapper page table 408 bic r3, r3, #0x0000000f @ mask 0xff00fff0
224 */ 409 mov r4, #0x41000000
225 mov r0, r4 410 orr r4, r4, #0x0000b000
226 mov r3, #0 411 orr r4, r4, #0x00000020 @ val 0x4100b020
227 add r6, r0, #0x4000 412 teq r3, r4 @ ARM 11MPCore?
2281: str r3, [r0], #4 413 moveq pc, lr @ yes, assume SMP
229 str r3, [r0], #4
230 str r3, [r0], #4
231 str r3, [r0], #4
232 teq r0, r6
233 bne 1b
234 414
235 ldr r7, [r10, #PROCINFO_MM_MMUFLAGS] @ mm_mmuflags 415 mrc p15, 0, r0, c0, c0, 5 @ read MPIDR
416 and r0, r0, #0xc0000000 @ multiprocessing extensions and
417 teq r0, #0x80000000 @ not part of a uniprocessor system?
418 moveq pc, lr @ yes, assume SMP
236 419
237 /* 420__fixup_smp_on_up:
238 * Create identity mapping for first MB of kernel to 421 adr r0, 1f
239 * cater for the MMU enable. This identity mapping 422 ldmia r0, {r3 - r5}
240 * will be removed by paging_init(). We use our current program 423 sub r3, r0, r3
241 * counter to determine corresponding section base address. 424 add r4, r4, r3
242 */ 425 add r5, r5, r3
243 mov r6, pc 426 b __do_fixup_smp_on_up
244 mov r6, r6, lsr #20 @ start of kernel section 427ENDPROC(__fixup_smp)
245 orr r3, r7, r6, lsl #20 @ flags + kernel base
246 str r3, [r4, r6, lsl #2] @ identity mapping
247 428
248 /* 429 .align
249 * Now setup the pagetables for our kernel direct 4301: .word .
250 * mapped region. 431 .word __smpalt_begin
251 */ 432 .word __smpalt_end
252 add r0, r4, #(KERNEL_START & 0xff000000) >> 18
253 str r3, [r0, #(KERNEL_START & 0x00f00000) >> 18]!
254 ldr r6, =(KERNEL_END - 1)
255 add r0, r0, #4
256 add r6, r4, r6, lsr #18
2571: cmp r0, r6
258 add r3, r3, #1 << 20
259 strls r3, [r0], #4
260 bls 1b
261 433
262#ifdef CONFIG_XIP_KERNEL 434 .pushsection .data
263 /* 435 .globl smp_on_up
264 * Map some ram to cover our .data and .bss areas. 436smp_on_up:
265 */ 437 ALT_SMP(.long 1)
266 orr r3, r7, #(KERNEL_RAM_PADDR & 0xff000000) 438 ALT_UP(.long 0)
267 .if (KERNEL_RAM_PADDR & 0x00f00000) 439 .popsection
268 orr r3, r3, #(KERNEL_RAM_PADDR & 0x00f00000)
269 .endif
270 add r0, r4, #(KERNEL_RAM_VADDR & 0xff000000) >> 18
271 str r3, [r0, #(KERNEL_RAM_VADDR & 0x00f00000) >> 18]!
272 ldr r6, =(_end - 1)
273 add r0, r0, #4
274 add r6, r4, r6, lsr #18
2751: cmp r0, r6
276 add r3, r3, #1 << 20
277 strls r3, [r0], #4
278 bls 1b
279#endif 440#endif
280 441
281 /* 442 .text
282 * Then map first 1MB of ram in case it contains our boot params. 443__do_fixup_smp_on_up:
283 */ 444 cmp r4, r5
284 add r0, r4, #PAGE_OFFSET >> 18 445 movhs pc, lr
285 orr r6, r7, #(PHYS_OFFSET & 0xff000000) 446 ldmia r4!, {r0, r6}
286 .if (PHYS_OFFSET & 0x00f00000) 447 ARM( str r6, [r0, r3] )
287 orr r6, r6, #(PHYS_OFFSET & 0x00f00000) 448 THUMB( add r0, r0, r3 )
288 .endif 449#ifdef __ARMEB__
289 str r6, [r0] 450 THUMB( mov r6, r6, ror #16 ) @ Convert word order for big-endian.
451#endif
452 THUMB( strh r6, [r0], #2 ) @ For Thumb-2, store as two halfwords
453 THUMB( mov r6, r6, lsr #16 ) @ to be robust against misaligned r3.
454 THUMB( strh r6, [r0] )
455 b __do_fixup_smp_on_up
456ENDPROC(__do_fixup_smp_on_up)
290 457
291#ifdef CONFIG_DEBUG_LL 458ENTRY(fixup_smp)
292 ldr r7, [r10, #PROCINFO_IO_MMUFLAGS] @ io_mmuflags 459 stmfd sp!, {r4 - r6, lr}
293 /* 460 mov r4, r0
294 * Map in IO space for serial debugging. 461 add r5, r0, r1
295 * This allows debug messages to be output 462 mov r3, #0
296 * via a serial console before paging_init. 463 bl __do_fixup_smp_on_up
297 */ 464 ldmfd sp!, {r4 - r6, pc}
298 ldr r3, [r8, #MACHINFO_PGOFFIO] 465ENDPROC(fixup_smp)
299 add r0, r4, r3 466
300 rsb r3, r3, #0x4000 @ PTRS_PER_PGD*sizeof(long) 467#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
301 cmp r3, #0x0800 @ limit to 512MB 468
302 movhi r3, #0x0800 469/* __fixup_pv_table - patch the stub instructions with the delta between
303 add r6, r0, r3 470 * PHYS_OFFSET and PAGE_OFFSET, which is assumed to be 16MiB aligned and
304 ldr r3, [r8, #MACHINFO_PHYSIO] 471 * can be expressed by an immediate shifter operand. The stub instruction
305 orr r3, r3, r7 472 * has a form of '(add|sub) rd, rn, #imm'.
3061: str r3, [r0], #4 473 */
307 add r3, r3, #1 << 20 474 __HEAD
308 teq r0, r6 475__fixup_pv_table:
309 bne 1b 476 adr r0, 1f
310#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) 477 ldmia r0, {r3-r5, r7}
311 /* 478 sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
312 * If we're using the NetWinder or CATS, we also need to map 479 add r4, r4, r3 @ adjust table start address
313 * in the 16550-type serial port for the debug messages 480 add r5, r5, r3 @ adjust table end address
314 */ 481 add r7, r7, r3 @ adjust __pv_phys_offset address
315 add r0, r4, #0xff000000 >> 18 482 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset
316 orr r3, r7, #0x7c000000 483#ifndef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
317 str r3, [r0] 484 mov r6, r3, lsr #24 @ constant for add/sub instructions
485 teq r3, r6, lsl #24 @ must be 16MiB aligned
486#else
487 mov r6, r3, lsr #16 @ constant for add/sub instructions
488 teq r3, r6, lsl #16 @ must be 64kiB aligned
318#endif 489#endif
319#ifdef CONFIG_ARCH_RPC 490THUMB( it ne @ cross section branch )
320 /* 491 bne __error
321 * Map in screen at 0x02000000 & SCREEN2_BASE 492 str r6, [r7, #4] @ save to __pv_offset
322 * Similar reasons here - for debug. This is 493 b __fixup_a_pv_table
323 * only for Acorn RiscPC architectures. 494ENDPROC(__fixup_pv_table)
324 */ 495
325 add r0, r4, #0x02000000 >> 18 496 .align
326 orr r3, r7, #0x02000000 4971: .long .
327 str r3, [r0] 498 .long __pv_table_begin
328 add r0, r4, #0xd8000000 >> 18 499 .long __pv_table_end
329 str r3, [r0] 5002: .long __pv_phys_offset
501
502 .text
503__fixup_a_pv_table:
504#ifdef CONFIG_THUMB2_KERNEL
505#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
506 lsls r0, r6, #24
507 lsr r6, #8
508 beq 1f
509 clz r7, r0
510 lsr r0, #24
511 lsl r0, r7
512 bic r0, 0x0080
513 lsrs r7, #1
514 orrcs r0, #0x0080
515 orr r0, r0, r7, lsl #12
330#endif 516#endif
5171: lsls r6, #24
518 beq 4f
519 clz r7, r6
520 lsr r6, #24
521 lsl r6, r7
522 bic r6, #0x0080
523 lsrs r7, #1
524 orrcs r6, #0x0080
525 orr r6, r6, r7, lsl #12
526 orr r6, #0x4000
527 b 4f
5282: @ at this point the C flag is always clear
529 add r7, r3
530#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
531 ldrh ip, [r7]
532 tst ip, 0x0400 @ the i bit tells us LS or MS byte
533 beq 3f
534 cmp r0, #0 @ set C flag, and ...
535 biceq ip, 0x0400 @ immediate zero value has a special encoding
536 streqh ip, [r7] @ that requires the i bit cleared
537#endif
5383: ldrh ip, [r7, #2]
539 and ip, 0x8f00
540 orrcc ip, r6 @ mask in offset bits 31-24
541 orrcs ip, r0 @ mask in offset bits 23-16
542 strh ip, [r7, #2]
5434: cmp r4, r5
544 ldrcc r7, [r4], #4 @ use branch for delay slot
545 bcc 2b
546 bx lr
547#else
548#ifdef CONFIG_ARM_PATCH_PHYS_VIRT_16BIT
549 and r0, r6, #255 @ offset bits 23-16
550 mov r6, r6, lsr #8 @ offset bits 31-24
551#else
552 mov r0, #0 @ just in case...
331#endif 553#endif
554 b 3f
5552: ldr ip, [r7, r3]
556 bic ip, ip, #0x000000ff
557 tst ip, #0x400 @ rotate shift tells us LS or MS byte
558 orrne ip, ip, r6 @ mask in offset bits 31-24
559 orreq ip, ip, r0 @ mask in offset bits 23-16
560 str ip, [r7, r3]
5613: cmp r4, r5
562 ldrcc r7, [r4], #4 @ use branch for delay slot
563 bcc 2b
332 mov pc, lr 564 mov pc, lr
333ENDPROC(__create_page_tables) 565#endif
334 .ltorg 566ENDPROC(__fixup_a_pv_table)
567
568ENTRY(fixup_pv_table)
569 stmfd sp!, {r4 - r7, lr}
570 ldr r2, 2f @ get address of __pv_phys_offset
571 mov r3, #0 @ no offset
572 mov r4, r0 @ r0 = table start
573 add r5, r0, r1 @ r1 = table size
574 ldr r6, [r2, #4] @ get __pv_offset
575 bl __fixup_a_pv_table
576 ldmfd sp!, {r4 - r7, pc}
577ENDPROC(fixup_pv_table)
578
579 .align
5802: .long __pv_phys_offset
581
582 .data
583 .globl __pv_phys_offset
584 .type __pv_phys_offset, %object
585__pv_phys_offset:
586 .long 0
587 .size __pv_phys_offset, . - __pv_phys_offset
588__pv_offset:
589 .long 0
590#endif
335 591
336#include "head-common.S" 592#include "head-common.S"
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..87acc25d7a3e
--- /dev/null
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -0,0 +1,978 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 *
6 * This program is distributed in the hope that it will be useful,
7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 * GNU General Public License for more details.
10 *
11 * You should have received a copy of the GNU General Public License
12 * along with this program; if not, write to the Free Software
13 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14 *
15 * Copyright (C) 2009, 2010 ARM Limited
16 *
17 * Author: Will Deacon <will.deacon@arm.com>
18 */
19
20/*
21 * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
22 * using the CPU's debug registers.
23 */
24#define pr_fmt(fmt) "hw-breakpoint: " fmt
25
26#include <linux/errno.h>
27#include <linux/hardirq.h>
28#include <linux/perf_event.h>
29#include <linux/hw_breakpoint.h>
30#include <linux/smp.h>
31
32#include <asm/cacheflush.h>
33#include <asm/cputype.h>
34#include <asm/current.h>
35#include <asm/hw_breakpoint.h>
36#include <asm/kdebug.h>
37#include <asm/system.h>
38#include <asm/traps.h>
39
40/* Breakpoint currently in use for each BRP. */
41static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
42
43/* Watchpoint currently in use for each WRP. */
44static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
45
46/* Number of BRP/WRP registers on this CPU. */
47static int core_num_brps;
48static int core_num_reserved_brps;
49static int core_num_wrps;
50
51/* Debug architecture version. */
52static u8 debug_arch;
53
54/* Maximum supported watchpoint length. */
55static u8 max_watchpoint_len;
56
57#define READ_WB_REG_CASE(OP2, M, VAL) \
58 case ((OP2 << 4) + M): \
59 ARM_DBG_READ(c ## M, OP2, VAL); \
60 break
61
62#define WRITE_WB_REG_CASE(OP2, M, VAL) \
63 case ((OP2 << 4) + M): \
64 ARM_DBG_WRITE(c ## M, OP2, VAL);\
65 break
66
67#define GEN_READ_WB_REG_CASES(OP2, VAL) \
68 READ_WB_REG_CASE(OP2, 0, VAL); \
69 READ_WB_REG_CASE(OP2, 1, VAL); \
70 READ_WB_REG_CASE(OP2, 2, VAL); \
71 READ_WB_REG_CASE(OP2, 3, VAL); \
72 READ_WB_REG_CASE(OP2, 4, VAL); \
73 READ_WB_REG_CASE(OP2, 5, VAL); \
74 READ_WB_REG_CASE(OP2, 6, VAL); \
75 READ_WB_REG_CASE(OP2, 7, VAL); \
76 READ_WB_REG_CASE(OP2, 8, VAL); \
77 READ_WB_REG_CASE(OP2, 9, VAL); \
78 READ_WB_REG_CASE(OP2, 10, VAL); \
79 READ_WB_REG_CASE(OP2, 11, VAL); \
80 READ_WB_REG_CASE(OP2, 12, VAL); \
81 READ_WB_REG_CASE(OP2, 13, VAL); \
82 READ_WB_REG_CASE(OP2, 14, VAL); \
83 READ_WB_REG_CASE(OP2, 15, VAL)
84
85#define GEN_WRITE_WB_REG_CASES(OP2, VAL) \
86 WRITE_WB_REG_CASE(OP2, 0, VAL); \
87 WRITE_WB_REG_CASE(OP2, 1, VAL); \
88 WRITE_WB_REG_CASE(OP2, 2, VAL); \
89 WRITE_WB_REG_CASE(OP2, 3, VAL); \
90 WRITE_WB_REG_CASE(OP2, 4, VAL); \
91 WRITE_WB_REG_CASE(OP2, 5, VAL); \
92 WRITE_WB_REG_CASE(OP2, 6, VAL); \
93 WRITE_WB_REG_CASE(OP2, 7, VAL); \
94 WRITE_WB_REG_CASE(OP2, 8, VAL); \
95 WRITE_WB_REG_CASE(OP2, 9, VAL); \
96 WRITE_WB_REG_CASE(OP2, 10, VAL); \
97 WRITE_WB_REG_CASE(OP2, 11, VAL); \
98 WRITE_WB_REG_CASE(OP2, 12, VAL); \
99 WRITE_WB_REG_CASE(OP2, 13, VAL); \
100 WRITE_WB_REG_CASE(OP2, 14, VAL); \
101 WRITE_WB_REG_CASE(OP2, 15, VAL)
102
103static u32 read_wb_reg(int n)
104{
105 u32 val = 0;
106
107 switch (n) {
108 GEN_READ_WB_REG_CASES(ARM_OP2_BVR, val);
109 GEN_READ_WB_REG_CASES(ARM_OP2_BCR, val);
110 GEN_READ_WB_REG_CASES(ARM_OP2_WVR, val);
111 GEN_READ_WB_REG_CASES(ARM_OP2_WCR, val);
112 default:
113 pr_warning("attempt to read from unknown breakpoint "
114 "register %d\n", n);
115 }
116
117 return val;
118}
119
120static void write_wb_reg(int n, u32 val)
121{
122 switch (n) {
123 GEN_WRITE_WB_REG_CASES(ARM_OP2_BVR, val);
124 GEN_WRITE_WB_REG_CASES(ARM_OP2_BCR, val);
125 GEN_WRITE_WB_REG_CASES(ARM_OP2_WVR, val);
126 GEN_WRITE_WB_REG_CASES(ARM_OP2_WCR, val);
127 default:
128 pr_warning("attempt to write to unknown breakpoint "
129 "register %d\n", n);
130 }
131 isb();
132}
133
134/* Determine debug architecture. */
135static u8 get_debug_arch(void)
136{
137 u32 didr;
138
139 /* Do we implement the extended CPUID interface? */
140 if (WARN_ONCE((((read_cpuid_id() >> 16) & 0xf) != 0xf),
141 "CPUID feature registers not supported. "
142 "Assuming v6 debug is present.\n"))
143 return ARM_DEBUG_ARCH_V6;
144
145 ARM_DBG_READ(c0, 0, didr);
146 return (didr >> 16) & 0xf;
147}
148
149u8 arch_get_debug_arch(void)
150{
151 return debug_arch;
152}
153
154static int debug_arch_supported(void)
155{
156 u8 arch = get_debug_arch();
157 return arch >= ARM_DEBUG_ARCH_V6 && arch <= ARM_DEBUG_ARCH_V7_ECP14;
158}
159
160/* Determine number of BRP register available. */
161static int get_num_brp_resources(void)
162{
163 u32 didr;
164 ARM_DBG_READ(c0, 0, didr);
165 return ((didr >> 24) & 0xf) + 1;
166}
167
168/* Does this core support mismatch breakpoints? */
169static int core_has_mismatch_brps(void)
170{
171 return (get_debug_arch() >= ARM_DEBUG_ARCH_V7_ECP14 &&
172 get_num_brp_resources() > 1);
173}
174
175/* Determine number of usable WRPs available. */
176static int get_num_wrps(void)
177{
178 /*
179 * FIXME: When a watchpoint fires, the only way to work out which
180 * watchpoint it was is by disassembling the faulting instruction
181 * and working out the address of the memory access.
182 *
183 * Furthermore, we can only do this if the watchpoint was precise
184 * since imprecise watchpoints prevent us from calculating register
185 * based addresses.
186 *
187 * Providing we have more than 1 breakpoint register, we only report
188 * a single watchpoint register for the time being. This way, we always
189 * know which watchpoint fired. In the future we can either add a
190 * disassembler and address generation emulator, or we can insert a
191 * check to see if the DFAR is set on watchpoint exception entry
192 * [the ARM ARM states that the DFAR is UNKNOWN, but experience shows
193 * that it is set on some implementations].
194 */
195
196#if 0
197 int wrps;
198 u32 didr;
199 ARM_DBG_READ(c0, 0, didr);
200 wrps = ((didr >> 28) & 0xf) + 1;
201#endif
202 int wrps = 1;
203
204 if (core_has_mismatch_brps() && wrps >= get_num_brp_resources())
205 wrps = get_num_brp_resources() - 1;
206
207 return wrps;
208}
209
210/* We reserve one breakpoint for each watchpoint. */
211static int get_num_reserved_brps(void)
212{
213 if (core_has_mismatch_brps())
214 return get_num_wrps();
215 return 0;
216}
217
218/* Determine number of usable BRPs available. */
219static int get_num_brps(void)
220{
221 int brps = get_num_brp_resources();
222 if (core_has_mismatch_brps())
223 brps -= get_num_reserved_brps();
224 return brps;
225}
226
227/*
228 * In order to access the breakpoint/watchpoint control registers,
229 * we must be running in debug monitor mode. Unfortunately, we can
230 * be put into halting debug mode at any time by an external debugger
231 * but there is nothing we can do to prevent that.
232 */
233static int enable_monitor_mode(void)
234{
235 u32 dscr;
236 int ret = 0;
237
238 ARM_DBG_READ(c1, 0, dscr);
239
240 /* Ensure that halting mode is disabled. */
241 if (WARN_ONCE(dscr & ARM_DSCR_HDBGEN,
242 "halting debug mode enabled. Unable to access hardware resources.\n")) {
243 ret = -EPERM;
244 goto out;
245 }
246
247 /* If monitor mode is already enabled, just return. */
248 if (dscr & ARM_DSCR_MDBGEN)
249 goto out;
250
251 /* Write to the corresponding DSCR. */
252 switch (get_debug_arch()) {
253 case ARM_DEBUG_ARCH_V6:
254 case ARM_DEBUG_ARCH_V6_1:
255 ARM_DBG_WRITE(c1, 0, (dscr | ARM_DSCR_MDBGEN));
256 break;
257 case ARM_DEBUG_ARCH_V7_ECP14:
258 ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
259 break;
260 default:
261 ret = -ENODEV;
262 goto out;
263 }
264
265 /* Check that the write made it through. */
266 ARM_DBG_READ(c1, 0, dscr);
267 if (!(dscr & ARM_DSCR_MDBGEN))
268 ret = -EPERM;
269
270out:
271 return ret;
272}
273
274int hw_breakpoint_slots(int type)
275{
276 if (!debug_arch_supported())
277 return 0;
278
279 /*
280 * We can be called early, so don't rely on
281 * our static variables being initialised.
282 */
283 switch (type) {
284 case TYPE_INST:
285 return get_num_brps();
286 case TYPE_DATA:
287 return get_num_wrps();
288 default:
289 pr_warning("unknown slot type: %d\n", type);
290 return 0;
291 }
292}
293
294/*
295 * Check if 8-bit byte-address select is available.
296 * This clobbers WRP 0.
297 */
298static u8 get_max_wp_len(void)
299{
300 u32 ctrl_reg;
301 struct arch_hw_breakpoint_ctrl ctrl;
302 u8 size = 4;
303
304 if (debug_arch < ARM_DEBUG_ARCH_V7_ECP14)
305 goto out;
306
307 memset(&ctrl, 0, sizeof(ctrl));
308 ctrl.len = ARM_BREAKPOINT_LEN_8;
309 ctrl_reg = encode_ctrl_reg(ctrl);
310
311 write_wb_reg(ARM_BASE_WVR, 0);
312 write_wb_reg(ARM_BASE_WCR, ctrl_reg);
313 if ((read_wb_reg(ARM_BASE_WCR) & ctrl_reg) == ctrl_reg)
314 size = 8;
315
316out:
317 return size;
318}
319
320u8 arch_get_max_wp_len(void)
321{
322 return max_watchpoint_len;
323}
324
325/*
326 * Install a perf counter breakpoint.
327 */
328int arch_install_hw_breakpoint(struct perf_event *bp)
329{
330 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
331 struct perf_event **slot, **slots;
332 int i, max_slots, ctrl_base, val_base, ret = 0;
333 u32 addr, ctrl;
334
335 /* Ensure that we are in monitor mode and halting mode is disabled. */
336 ret = enable_monitor_mode();
337 if (ret)
338 goto out;
339
340 addr = info->address;
341 ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
342
343 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
344 /* Breakpoint */
345 ctrl_base = ARM_BASE_BCR;
346 val_base = ARM_BASE_BVR;
347 slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
348 max_slots = core_num_brps;
349 if (info->step_ctrl.enabled) {
350 /* Override the breakpoint data with the step data. */
351 addr = info->trigger & ~0x3;
352 ctrl = encode_ctrl_reg(info->step_ctrl);
353 }
354 } else {
355 /* Watchpoint */
356 if (info->step_ctrl.enabled) {
357 /* Install into the reserved breakpoint region. */
358 ctrl_base = ARM_BASE_BCR + core_num_brps;
359 val_base = ARM_BASE_BVR + core_num_brps;
360 /* Override the watchpoint data with the step data. */
361 addr = info->trigger & ~0x3;
362 ctrl = encode_ctrl_reg(info->step_ctrl);
363 } else {
364 ctrl_base = ARM_BASE_WCR;
365 val_base = ARM_BASE_WVR;
366 }
367 slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
368 max_slots = core_num_wrps;
369 }
370
371 for (i = 0; i < max_slots; ++i) {
372 slot = &slots[i];
373
374 if (!*slot) {
375 *slot = bp;
376 break;
377 }
378 }
379
380 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
381 ret = -EBUSY;
382 goto out;
383 }
384
385 /* Setup the address register. */
386 write_wb_reg(val_base + i, addr);
387
388 /* Setup the control register. */
389 write_wb_reg(ctrl_base + i, ctrl);
390
391out:
392 return ret;
393}
394
395void arch_uninstall_hw_breakpoint(struct perf_event *bp)
396{
397 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
398 struct perf_event **slot, **slots;
399 int i, max_slots, base;
400
401 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
402 /* Breakpoint */
403 base = ARM_BASE_BCR;
404 slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
405 max_slots = core_num_brps;
406 } else {
407 /* Watchpoint */
408 if (info->step_ctrl.enabled)
409 base = ARM_BASE_BCR + core_num_brps;
410 else
411 base = ARM_BASE_WCR;
412 slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
413 max_slots = core_num_wrps;
414 }
415
416 /* Remove the breakpoint. */
417 for (i = 0; i < max_slots; ++i) {
418 slot = &slots[i];
419
420 if (*slot == bp) {
421 *slot = NULL;
422 break;
423 }
424 }
425
426 if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
427 return;
428
429 /* Reset the control register. */
430 write_wb_reg(base + i, 0);
431}
432
433static int get_hbp_len(u8 hbp_len)
434{
435 unsigned int len_in_bytes = 0;
436
437 switch (hbp_len) {
438 case ARM_BREAKPOINT_LEN_1:
439 len_in_bytes = 1;
440 break;
441 case ARM_BREAKPOINT_LEN_2:
442 len_in_bytes = 2;
443 break;
444 case ARM_BREAKPOINT_LEN_4:
445 len_in_bytes = 4;
446 break;
447 case ARM_BREAKPOINT_LEN_8:
448 len_in_bytes = 8;
449 break;
450 }
451
452 return len_in_bytes;
453}
454
455/*
456 * Check whether bp virtual address is in kernel space.
457 */
458int arch_check_bp_in_kernelspace(struct perf_event *bp)
459{
460 unsigned int len;
461 unsigned long va;
462 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
463
464 va = info->address;
465 len = get_hbp_len(info->ctrl.len);
466
467 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
468}
469
470/*
471 * Extract generic type and length encodings from an arch_hw_breakpoint_ctrl.
472 * Hopefully this will disappear when ptrace can bypass the conversion
473 * to generic breakpoint descriptions.
474 */
475int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
476 int *gen_len, int *gen_type)
477{
478 /* Type */
479 switch (ctrl.type) {
480 case ARM_BREAKPOINT_EXECUTE:
481 *gen_type = HW_BREAKPOINT_X;
482 break;
483 case ARM_BREAKPOINT_LOAD:
484 *gen_type = HW_BREAKPOINT_R;
485 break;
486 case ARM_BREAKPOINT_STORE:
487 *gen_type = HW_BREAKPOINT_W;
488 break;
489 case ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE:
490 *gen_type = HW_BREAKPOINT_RW;
491 break;
492 default:
493 return -EINVAL;
494 }
495
496 /* Len */
497 switch (ctrl.len) {
498 case ARM_BREAKPOINT_LEN_1:
499 *gen_len = HW_BREAKPOINT_LEN_1;
500 break;
501 case ARM_BREAKPOINT_LEN_2:
502 *gen_len = HW_BREAKPOINT_LEN_2;
503 break;
504 case ARM_BREAKPOINT_LEN_4:
505 *gen_len = HW_BREAKPOINT_LEN_4;
506 break;
507 case ARM_BREAKPOINT_LEN_8:
508 *gen_len = HW_BREAKPOINT_LEN_8;
509 break;
510 default:
511 return -EINVAL;
512 }
513
514 return 0;
515}
516
517/*
518 * Construct an arch_hw_breakpoint from a perf_event.
519 */
520static int arch_build_bp_info(struct perf_event *bp)
521{
522 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
523
524 /* Type */
525 switch (bp->attr.bp_type) {
526 case HW_BREAKPOINT_X:
527 info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
528 break;
529 case HW_BREAKPOINT_R:
530 info->ctrl.type = ARM_BREAKPOINT_LOAD;
531 break;
532 case HW_BREAKPOINT_W:
533 info->ctrl.type = ARM_BREAKPOINT_STORE;
534 break;
535 case HW_BREAKPOINT_RW:
536 info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 /* Len */
543 switch (bp->attr.bp_len) {
544 case HW_BREAKPOINT_LEN_1:
545 info->ctrl.len = ARM_BREAKPOINT_LEN_1;
546 break;
547 case HW_BREAKPOINT_LEN_2:
548 info->ctrl.len = ARM_BREAKPOINT_LEN_2;
549 break;
550 case HW_BREAKPOINT_LEN_4:
551 info->ctrl.len = ARM_BREAKPOINT_LEN_4;
552 break;
553 case HW_BREAKPOINT_LEN_8:
554 info->ctrl.len = ARM_BREAKPOINT_LEN_8;
555 if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE)
556 && max_watchpoint_len >= 8)
557 break;
558 default:
559 return -EINVAL;
560 }
561
562 /*
563 * Breakpoints must be of length 2 (thumb) or 4 (ARM) bytes.
564 * Watchpoints can be of length 1, 2, 4 or 8 bytes if supported
565 * by the hardware and must be aligned to the appropriate number of
566 * bytes.
567 */
568 if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
569 info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
570 info->ctrl.len != ARM_BREAKPOINT_LEN_4)
571 return -EINVAL;
572
573 /* Address */
574 info->address = bp->attr.bp_addr;
575
576 /* Privilege */
577 info->ctrl.privilege = ARM_BREAKPOINT_USER;
578 if (arch_check_bp_in_kernelspace(bp))
579 info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
580
581 /* Enabled? */
582 info->ctrl.enabled = !bp->attr.disabled;
583
584 /* Mismatch */
585 info->ctrl.mismatch = 0;
586
587 return 0;
588}
589
590/*
591 * Validate the arch-specific HW Breakpoint register settings.
592 */
593int arch_validate_hwbkpt_settings(struct perf_event *bp)
594{
595 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
596 int ret = 0;
597 u32 offset, alignment_mask = 0x3;
598
599 /* Build the arch_hw_breakpoint. */
600 ret = arch_build_bp_info(bp);
601 if (ret)
602 goto out;
603
604 /* Check address alignment. */
605 if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
606 alignment_mask = 0x7;
607 offset = info->address & alignment_mask;
608 switch (offset) {
609 case 0:
610 /* Aligned */
611 break;
612 case 1:
613 /* Allow single byte watchpoint. */
614 if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
615 break;
616 case 2:
617 /* Allow halfword watchpoints and breakpoints. */
618 if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
619 break;
620 default:
621 ret = -EINVAL;
622 goto out;
623 }
624
625 info->address &= ~alignment_mask;
626 info->ctrl.len <<= offset;
627
628 /*
629 * Currently we rely on an overflow handler to take
630 * care of single-stepping the breakpoint when it fires.
631 * In the case of userspace breakpoints on a core with V7 debug,
632 * we can use the mismatch feature as a poor-man's hardware
633 * single-step, but this only works for per-task breakpoints.
634 */
635 if (WARN_ONCE(!bp->overflow_handler &&
636 (arch_check_bp_in_kernelspace(bp) || !core_has_mismatch_brps()
637 || !bp->hw.bp_target),
638 "overflow handler required but none found\n")) {
639 ret = -EINVAL;
640 }
641out:
642 return ret;
643}
644
645/*
646 * Enable/disable single-stepping over the breakpoint bp at address addr.
647 */
648static void enable_single_step(struct perf_event *bp, u32 addr)
649{
650 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
651
652 arch_uninstall_hw_breakpoint(bp);
653 info->step_ctrl.mismatch = 1;
654 info->step_ctrl.len = ARM_BREAKPOINT_LEN_4;
655 info->step_ctrl.type = ARM_BREAKPOINT_EXECUTE;
656 info->step_ctrl.privilege = info->ctrl.privilege;
657 info->step_ctrl.enabled = 1;
658 info->trigger = addr;
659 arch_install_hw_breakpoint(bp);
660}
661
662static void disable_single_step(struct perf_event *bp)
663{
664 arch_uninstall_hw_breakpoint(bp);
665 counter_arch_bp(bp)->step_ctrl.enabled = 0;
666 arch_install_hw_breakpoint(bp);
667}
668
669static void watchpoint_handler(unsigned long unknown, struct pt_regs *regs)
670{
671 int i;
672 struct perf_event *wp, **slots;
673 struct arch_hw_breakpoint *info;
674
675 slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
676
677 /* Without a disassembler, we can only handle 1 watchpoint. */
678 BUG_ON(core_num_wrps > 1);
679
680 for (i = 0; i < core_num_wrps; ++i) {
681 rcu_read_lock();
682
683 wp = slots[i];
684
685 if (wp == NULL) {
686 rcu_read_unlock();
687 continue;
688 }
689
690 /*
691 * The DFAR is an unknown value. Since we only allow a
692 * single watchpoint, we can set the trigger to the lowest
693 * possible faulting address.
694 */
695 info = counter_arch_bp(wp);
696 info->trigger = wp->attr.bp_addr;
697 pr_debug("watchpoint fired: address = 0x%x\n", info->trigger);
698 perf_bp_event(wp, regs);
699
700 /*
701 * If no overflow handler is present, insert a temporary
702 * mismatch breakpoint so we can single-step over the
703 * watchpoint trigger.
704 */
705 if (!wp->overflow_handler)
706 enable_single_step(wp, instruction_pointer(regs));
707
708 rcu_read_unlock();
709 }
710}
711
712static void watchpoint_single_step_handler(unsigned long pc)
713{
714 int i;
715 struct perf_event *wp, **slots;
716 struct arch_hw_breakpoint *info;
717
718 slots = (struct perf_event **)__get_cpu_var(wp_on_reg);
719
720 for (i = 0; i < core_num_reserved_brps; ++i) {
721 rcu_read_lock();
722
723 wp = slots[i];
724
725 if (wp == NULL)
726 goto unlock;
727
728 info = counter_arch_bp(wp);
729 if (!info->step_ctrl.enabled)
730 goto unlock;
731
732 /*
733 * Restore the original watchpoint if we've completed the
734 * single-step.
735 */
736 if (info->trigger != pc)
737 disable_single_step(wp);
738
739unlock:
740 rcu_read_unlock();
741 }
742}
743
744static void breakpoint_handler(unsigned long unknown, struct pt_regs *regs)
745{
746 int i;
747 u32 ctrl_reg, val, addr;
748 struct perf_event *bp, **slots;
749 struct arch_hw_breakpoint *info;
750 struct arch_hw_breakpoint_ctrl ctrl;
751
752 slots = (struct perf_event **)__get_cpu_var(bp_on_reg);
753
754 /* The exception entry code places the amended lr in the PC. */
755 addr = regs->ARM_pc;
756
757 /* Check the currently installed breakpoints first. */
758 for (i = 0; i < core_num_brps; ++i) {
759 rcu_read_lock();
760
761 bp = slots[i];
762
763 if (bp == NULL)
764 goto unlock;
765
766 info = counter_arch_bp(bp);
767
768 /* Check if the breakpoint value matches. */
769 val = read_wb_reg(ARM_BASE_BVR + i);
770 if (val != (addr & ~0x3))
771 goto mismatch;
772
773 /* Possible match, check the byte address select to confirm. */
774 ctrl_reg = read_wb_reg(ARM_BASE_BCR + i);
775 decode_ctrl_reg(ctrl_reg, &ctrl);
776 if ((1 << (addr & 0x3)) & ctrl.len) {
777 info->trigger = addr;
778 pr_debug("breakpoint fired: address = 0x%x\n", addr);
779 perf_bp_event(bp, regs);
780 if (!bp->overflow_handler)
781 enable_single_step(bp, addr);
782 goto unlock;
783 }
784
785mismatch:
786 /* If we're stepping a breakpoint, it can now be restored. */
787 if (info->step_ctrl.enabled)
788 disable_single_step(bp);
789unlock:
790 rcu_read_unlock();
791 }
792
793 /* Handle any pending watchpoint single-step breakpoints. */
794 watchpoint_single_step_handler(addr);
795}
796
797/*
798 * Called from either the Data Abort Handler [watchpoint] or the
799 * Prefetch Abort Handler [breakpoint] with preemption disabled.
800 */
801static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
802 struct pt_regs *regs)
803{
804 int ret = 0;
805 u32 dscr;
806
807 /* We must be called with preemption disabled. */
808 WARN_ON(preemptible());
809
810 /* We only handle watchpoints and hardware breakpoints. */
811 ARM_DBG_READ(c1, 0, dscr);
812
813 /* Perform perf callbacks. */
814 switch (ARM_DSCR_MOE(dscr)) {
815 case ARM_ENTRY_BREAKPOINT:
816 breakpoint_handler(addr, regs);
817 break;
818 case ARM_ENTRY_ASYNC_WATCHPOINT:
819 WARN(1, "Asynchronous watchpoint exception taken. Debugging results may be unreliable\n");
820 case ARM_ENTRY_SYNC_WATCHPOINT:
821 watchpoint_handler(addr, regs);
822 break;
823 default:
824 ret = 1; /* Unhandled fault. */
825 }
826
827 /*
828 * Re-enable preemption after it was disabled in the
829 * low-level exception handling code.
830 */
831 preempt_enable();
832
833 return ret;
834}
835
836/*
837 * One-time initialisation.
838 */
839static void reset_ctrl_regs(void *info)
840{
841 int i, cpu = smp_processor_id();
842 u32 dbg_power;
843 cpumask_t *cpumask = info;
844
845 /*
846 * v7 debug contains save and restore registers so that debug state
847 * can be maintained across low-power modes without leaving the debug
848 * logic powered up. It is IMPLEMENTATION DEFINED whether we can access
849 * the debug registers out of reset, so we must unlock the OS Lock
850 * Access Register to avoid taking undefined instruction exceptions
851 * later on.
852 */
853 if (debug_arch >= ARM_DEBUG_ARCH_V7_ECP14) {
854 /*
855 * Ensure sticky power-down is clear (i.e. debug logic is
856 * powered up).
857 */
858 asm volatile("mrc p14, 0, %0, c1, c5, 4" : "=r" (dbg_power));
859 if ((dbg_power & 0x1) == 0) {
860 pr_warning("CPU %d debug is powered down!\n", cpu);
861 cpumask_or(cpumask, cpumask, cpumask_of(cpu));
862 return;
863 }
864
865 /*
866 * Unconditionally clear the lock by writing a value
867 * other than 0xC5ACCE55 to the access register.
868 */
869 asm volatile("mcr p14, 0, %0, c1, c0, 4" : : "r" (0));
870 isb();
871
872 /*
873 * Clear any configured vector-catch events before
874 * enabling monitor mode.
875 */
876 asm volatile("mcr p14, 0, %0, c0, c7, 0" : : "r" (0));
877 isb();
878 }
879
880 if (enable_monitor_mode())
881 return;
882
883 /* We must also reset any reserved registers. */
884 for (i = 0; i < core_num_brps + core_num_reserved_brps; ++i) {
885 write_wb_reg(ARM_BASE_BCR + i, 0UL);
886 write_wb_reg(ARM_BASE_BVR + i, 0UL);
887 }
888
889 for (i = 0; i < core_num_wrps; ++i) {
890 write_wb_reg(ARM_BASE_WCR + i, 0UL);
891 write_wb_reg(ARM_BASE_WVR + i, 0UL);
892 }
893}
894
895static int __cpuinit dbg_reset_notify(struct notifier_block *self,
896 unsigned long action, void *cpu)
897{
898 if (action == CPU_ONLINE)
899 smp_call_function_single((int)cpu, reset_ctrl_regs, NULL, 1);
900 return NOTIFY_OK;
901}
902
903static struct notifier_block __cpuinitdata dbg_reset_nb = {
904 .notifier_call = dbg_reset_notify,
905};
906
907static int __init arch_hw_breakpoint_init(void)
908{
909 u32 dscr;
910 cpumask_t cpumask = { CPU_BITS_NONE };
911
912 debug_arch = get_debug_arch();
913
914 if (!debug_arch_supported()) {
915 pr_info("debug architecture 0x%x unsupported.\n", debug_arch);
916 return 0;
917 }
918
919 /* Determine how many BRPs/WRPs are available. */
920 core_num_brps = get_num_brps();
921 core_num_reserved_brps = get_num_reserved_brps();
922 core_num_wrps = get_num_wrps();
923
924 pr_info("found %d breakpoint and %d watchpoint registers.\n",
925 core_num_brps + core_num_reserved_brps, core_num_wrps);
926
927 if (core_num_reserved_brps)
928 pr_info("%d breakpoint(s) reserved for watchpoint "
929 "single-step.\n", core_num_reserved_brps);
930
931 /*
932 * Reset the breakpoint resources. We assume that a halting
933 * debugger will leave the world in a nice state for us.
934 */
935 on_each_cpu(reset_ctrl_regs, &cpumask, 1);
936 if (!cpumask_empty(&cpumask)) {
937 core_num_brps = 0;
938 core_num_reserved_brps = 0;
939 core_num_wrps = 0;
940 return 0;
941 }
942
943 ARM_DBG_READ(c1, 0, dscr);
944 if (dscr & ARM_DSCR_HDBGEN) {
945 max_watchpoint_len = 4;
946 pr_warning("halting debug mode enabled. Assuming maximum watchpoint size of %u bytes.\n",
947 max_watchpoint_len);
948 } else {
949 /* Work out the maximum supported watchpoint length. */
950 max_watchpoint_len = get_max_wp_len();
951 pr_info("maximum watchpoint size is %u bytes.\n",
952 max_watchpoint_len);
953 }
954
955 /* Register debug fault handler. */
956 hook_fault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
957 "watchpoint debug exception");
958 hook_ifault_code(2, hw_breakpoint_pending, SIGTRAP, TRAP_HWBKPT,
959 "breakpoint debug exception");
960
961 /* Register hotplug notifier. */
962 register_cpu_notifier(&dbg_reset_nb);
963 return 0;
964}
965arch_initcall(arch_hw_breakpoint_init);
966
967void hw_breakpoint_pmu_read(struct perf_event *bp)
968{
969}
970
971/*
972 * Dummy function to register with die_notifier.
973 */
974int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
975 unsigned long val, void *data)
976{
977 return NOTIFY_DONE;
978}
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index c0d5c3b3a760..83bbad03fcc6 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -35,8 +35,10 @@
35#include <linux/list.h> 35#include <linux/list.h>
36#include <linux/kallsyms.h> 36#include <linux/kallsyms.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/ftrace.h>
38 39
39#include <asm/system.h> 40#include <asm/system.h>
41#include <asm/mach/arch.h>
40#include <asm/mach/irq.h> 42#include <asm/mach/irq.h>
41#include <asm/mach/time.h> 43#include <asm/mach/time.h>
42 44
@@ -47,56 +49,20 @@
47#define irq_finish(irq) do { } while (0) 49#define irq_finish(irq) do { } while (0)
48#endif 50#endif
49 51
50unsigned int arch_nr_irqs;
51void (*init_arch_irq)(void) __initdata = NULL;
52unsigned long irq_err_count; 52unsigned long irq_err_count;
53 53
54int show_interrupts(struct seq_file *p, void *v) 54int arch_show_interrupts(struct seq_file *p, int prec)
55{ 55{
56 int i = *(loff_t *) v, cpu;
57 struct irq_desc *desc;
58 struct irqaction * action;
59 unsigned long flags;
60
61 if (i == 0) {
62 char cpuname[12];
63
64 seq_printf(p, " ");
65 for_each_present_cpu(cpu) {
66 sprintf(cpuname, "CPU%d", cpu);
67 seq_printf(p, " %10s", cpuname);
68 }
69 seq_putc(p, '\n');
70 }
71
72 if (i < nr_irqs) {
73 desc = irq_to_desc(i);
74 raw_spin_lock_irqsave(&desc->lock, flags);
75 action = desc->action;
76 if (!action)
77 goto unlock;
78
79 seq_printf(p, "%3d: ", i);
80 for_each_present_cpu(cpu)
81 seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
82 seq_printf(p, " %10s", desc->chip->name ? : "-");
83 seq_printf(p, " %s", action->name);
84 for (action = action->next; action; action = action->next)
85 seq_printf(p, ", %s", action->name);
86
87 seq_putc(p, '\n');
88unlock:
89 raw_spin_unlock_irqrestore(&desc->lock, flags);
90 } else if (i == nr_irqs) {
91#ifdef CONFIG_FIQ 56#ifdef CONFIG_FIQ
92 show_fiq_list(p, v); 57 show_fiq_list(p, prec);
93#endif 58#endif
94#ifdef CONFIG_SMP 59#ifdef CONFIG_SMP
95 show_ipi_list(p); 60 show_ipi_list(p, prec);
96 show_local_irqs(p);
97#endif 61#endif
98 seq_printf(p, "Err: %10lu\n", irq_err_count); 62#ifdef CONFIG_LOCAL_TIMERS
99 } 63 show_local_irqs(p, prec);
64#endif
65 seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
100 return 0; 66 return 0;
101} 67}
102 68
@@ -105,7 +71,8 @@ unlock:
105 * come via this function. Instead, they should provide their 71 * come via this function. Instead, they should provide their
106 * own 'handler' 72 * own 'handler'
107 */ 73 */
108asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs) 74asmlinkage void __exception_irq_entry
75asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
109{ 76{
110 struct pt_regs *old_regs = set_irq_regs(regs); 77 struct pt_regs *old_regs = set_irq_regs(regs);
111 78
@@ -132,56 +99,53 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
132 99
133void set_irq_flags(unsigned int irq, unsigned int iflags) 100void set_irq_flags(unsigned int irq, unsigned int iflags)
134{ 101{
135 struct irq_desc *desc; 102 unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
136 unsigned long flags;
137 103
138 if (irq >= nr_irqs) { 104 if (irq >= nr_irqs) {
139 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq); 105 printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
140 return; 106 return;
141 } 107 }
142 108
143 desc = irq_to_desc(irq);
144 raw_spin_lock_irqsave(&desc->lock, flags);
145 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
146 if (iflags & IRQF_VALID) 109 if (iflags & IRQF_VALID)
147 desc->status &= ~IRQ_NOREQUEST; 110 clr |= IRQ_NOREQUEST;
148 if (iflags & IRQF_PROBE) 111 if (iflags & IRQF_PROBE)
149 desc->status &= ~IRQ_NOPROBE; 112 clr |= IRQ_NOPROBE;
150 if (!(iflags & IRQF_NOAUTOEN)) 113 if (!(iflags & IRQF_NOAUTOEN))
151 desc->status &= ~IRQ_NOAUTOEN; 114 clr |= IRQ_NOAUTOEN;
152 raw_spin_unlock_irqrestore(&desc->lock, flags); 115 /* Order is clear bits in "clr" then set bits in "set" */
116 irq_modify_status(irq, clr, set & ~clr);
153} 117}
154 118
155void __init init_IRQ(void) 119void __init init_IRQ(void)
156{ 120{
157 struct irq_desc *desc; 121 machine_desc->init_irq();
158 int irq;
159
160 for (irq = 0; irq < nr_irqs; irq++) {
161 desc = irq_to_desc_alloc_node(irq, 0);
162 desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
163 }
164
165 init_arch_irq();
166} 122}
167 123
168#ifdef CONFIG_SPARSE_IRQ 124#ifdef CONFIG_SPARSE_IRQ
169int __init arch_probe_nr_irqs(void) 125int __init arch_probe_nr_irqs(void)
170{ 126{
171 nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS; 127 nr_irqs = machine_desc->nr_irqs ? machine_desc->nr_irqs : NR_IRQS;
172 return 0; 128 return nr_irqs;
173} 129}
174#endif 130#endif
175 131
176#ifdef CONFIG_HOTPLUG_CPU 132#ifdef CONFIG_HOTPLUG_CPU
177 133
178static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu) 134static bool migrate_one_irq(struct irq_data *d)
179{ 135{
180 pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", irq, desc->node, cpu); 136 unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask);
137 bool ret = false;
138
139 if (cpu >= nr_cpu_ids) {
140 cpu = cpumask_any(cpu_online_mask);
141 ret = true;
142 }
181 143
182 raw_spin_lock_irq(&desc->lock); 144 pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu);
183 desc->chip->set_affinity(irq, cpumask_of(cpu)); 145
184 raw_spin_unlock_irq(&desc->lock); 146 d->chip->irq_set_affinity(d, cpumask_of(cpu), true);
147
148 return ret;
185} 149}
186 150
187/* 151/*
@@ -193,23 +157,30 @@ void migrate_irqs(void)
193{ 157{
194 unsigned int i, cpu = smp_processor_id(); 158 unsigned int i, cpu = smp_processor_id();
195 struct irq_desc *desc; 159 struct irq_desc *desc;
160 unsigned long flags;
161
162 local_irq_save(flags);
196 163
197 for_each_irq_desc(i, desc) { 164 for_each_irq_desc(i, desc) {
198 if (desc->node == cpu) { 165 struct irq_data *d = &desc->irq_data;
199 unsigned int newcpu = cpumask_any_and(desc->affinity, 166 bool affinity_broken = false;
200 cpu_online_mask); 167
201 if (newcpu >= nr_cpu_ids) { 168 raw_spin_lock(&desc->lock);
202 if (printk_ratelimit()) 169 do {
203 printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n", 170 if (desc->action == NULL)
204 i, cpu); 171 break;
205 172
206 cpumask_setall(desc->affinity); 173 if (d->node != cpu)
207 newcpu = cpumask_any_and(desc->affinity, 174 break;
208 cpu_online_mask); 175
209 } 176 affinity_broken = migrate_one_irq(d);
210 177 } while (0);
211 route_irq(desc, i, newcpu); 178 raw_spin_unlock(&desc->lock);
212 } 179
180 if (affinity_broken && printk_ratelimit())
181 pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu);
213 } 182 }
183
184 local_irq_restore(flags);
214} 185}
215#endif /* CONFIG_HOTPLUG_CPU */ 186#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S
index b63b528f22a6..7fa3bb0d2397 100644
--- a/arch/arm/kernel/iwmmxt.S
+++ b/arch/arm/kernel/iwmmxt.S
@@ -19,6 +19,14 @@
19#include <asm/thread_info.h> 19#include <asm/thread_info.h>
20#include <asm/asm-offsets.h> 20#include <asm/asm-offsets.h>
21 21
22#if defined(CONFIG_CPU_PJ4)
23#define PJ4(code...) code
24#define XSC(code...)
25#else
26#define PJ4(code...)
27#define XSC(code...) code
28#endif
29
22#define MMX_WR0 (0x00) 30#define MMX_WR0 (0x00)
23#define MMX_WR1 (0x08) 31#define MMX_WR1 (0x08)
24#define MMX_WR2 (0x10) 32#define MMX_WR2 (0x10)
@@ -58,11 +66,17 @@
58 66
59ENTRY(iwmmxt_task_enable) 67ENTRY(iwmmxt_task_enable)
60 68
61 mrc p15, 0, r2, c15, c1, 0 69 XSC(mrc p15, 0, r2, c15, c1, 0)
62 tst r2, #0x3 @ CP0 and CP1 accessible? 70 PJ4(mrc p15, 0, r2, c1, c0, 2)
71 @ CP0 and CP1 accessible?
72 XSC(tst r2, #0x3)
73 PJ4(tst r2, #0xf)
63 movne pc, lr @ if so no business here 74 movne pc, lr @ if so no business here
64 orr r2, r2, #0x3 @ enable access to CP0 and CP1 75 @ enable access to CP0 and CP1
65 mcr p15, 0, r2, c15, c1, 0 76 XSC(orr r2, r2, #0x3)
77 XSC(mcr p15, 0, r2, c15, c1, 0)
78 PJ4(orr r2, r2, #0xf)
79 PJ4(mcr p15, 0, r2, c1, c0, 2)
66 80
67 ldr r3, =concan_owner 81 ldr r3, =concan_owner
68 add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area 82 add r0, r10, #TI_IWMMXT_STATE @ get task Concan save area
@@ -179,17 +193,26 @@ ENTRY(iwmmxt_task_disable)
179 teqne r1, r2 @ or specified one? 193 teqne r1, r2 @ or specified one?
180 bne 1f @ no: quit 194 bne 1f @ no: quit
181 195
182 mrc p15, 0, r4, c15, c1, 0 196 @ enable access to CP0 and CP1
183 orr r4, r4, #0x3 @ enable access to CP0 and CP1 197 XSC(mrc p15, 0, r4, c15, c1, 0)
184 mcr p15, 0, r4, c15, c1, 0 198 XSC(orr r4, r4, #0xf)
199 XSC(mcr p15, 0, r4, c15, c1, 0)
200 PJ4(mrc p15, 0, r4, c1, c0, 2)
201 PJ4(orr r4, r4, #0x3)
202 PJ4(mcr p15, 0, r4, c1, c0, 2)
203
185 mov r0, #0 @ nothing to load 204 mov r0, #0 @ nothing to load
186 str r0, [r3] @ no more current owner 205 str r0, [r3] @ no more current owner
187 mrc p15, 0, r2, c2, c0, 0 206 mrc p15, 0, r2, c2, c0, 0
188 mov r2, r2 @ cpwait 207 mov r2, r2 @ cpwait
189 bl concan_save 208 bl concan_save
190 209
191 bic r4, r4, #0x3 @ disable access to CP0 and CP1 210 @ disable access to CP0 and CP1
192 mcr p15, 0, r4, c15, c1, 0 211 XSC(bic r4, r4, #0x3)
212 XSC(mcr p15, 0, r4, c15, c1, 0)
213 PJ4(bic r4, r4, #0xf)
214 PJ4(mcr p15, 0, r4, c1, c0, 2)
215
193 mrc p15, 0, r2, c2, c0, 0 216 mrc p15, 0, r2, c2, c0, 0
194 mov r2, r2 @ cpwait 217 mov r2, r2 @ cpwait
195 218
@@ -277,8 +300,11 @@ ENTRY(iwmmxt_task_restore)
277 */ 300 */
278ENTRY(iwmmxt_task_switch) 301ENTRY(iwmmxt_task_switch)
279 302
280 mrc p15, 0, r1, c15, c1, 0 303 XSC(mrc p15, 0, r1, c15, c1, 0)
281 tst r1, #0x3 @ CP0 and CP1 accessible? 304 PJ4(mrc p15, 0, r1, c1, c0, 2)
305 @ CP0 and CP1 accessible?
306 XSC(tst r1, #0x3)
307 PJ4(tst r1, #0xf)
282 bne 1f @ yes: block them for next task 308 bne 1f @ yes: block them for next task
283 309
284 ldr r2, =concan_owner 310 ldr r2, =concan_owner
@@ -287,8 +313,11 @@ ENTRY(iwmmxt_task_switch)
287 teq r2, r3 @ next task owns it? 313 teq r2, r3 @ next task owns it?
288 movne pc, lr @ no: leave Concan disabled 314 movne pc, lr @ no: leave Concan disabled
289 315
2901: eor r1, r1, #3 @ flip Concan access 3161: @ flip Conan access
291 mcr p15, 0, r1, c15, c1, 0 317 XSC(eor r1, r1, #0x3)
318 XSC(mcr p15, 0, r1, c15, c1, 0)
319 PJ4(eor r1, r1, #0xf)
320 PJ4(mcr p15, 0, r1, c1, c0, 2)
292 321
293 mrc p15, 0, r1, c2, c0, 0 322 mrc p15, 0, r1, c2, c0, 0
294 sub pc, lr, r1, lsr #32 @ cpwait and return 323 sub pc, lr, r1, lsr #32 @ cpwait and return
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index d6e8b4d2e60d..778c2f7024ff 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -79,7 +79,7 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task)
79 return; 79 return;
80 80
81 /* Initialize to zero */ 81 /* Initialize to zero */
82 for (regno = 0; regno < DBG_MAX_REG_NUM; regno++) 82 for (regno = 0; regno < GDB_MAX_REGS; regno++)
83 gdb_regs[regno] = 0; 83 gdb_regs[regno] = 0;
84 84
85 /* Otherwise, we have only some registers from switch_to() */ 85 /* Otherwise, we have only some registers from switch_to() */
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 2c1f0050c9c4..15eeff6aea0e 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -34,9 +34,6 @@
34 * 34 *
35 * *) If the PC is written to by the instruction, the 35 * *) If the PC is written to by the instruction, the
36 * instruction must be fully simulated in software. 36 * instruction must be fully simulated in software.
37 * If it is a conditional instruction, the handler
38 * will use insn[0] to copy its condition code to
39 * set r0 to 1 and insn[1] to "mov pc, lr" to return.
40 * 37 *
41 * *) Otherwise, a modified form of the instruction is 38 * *) Otherwise, a modified form of the instruction is
42 * directly executed. Its handler calls the 39 * directly executed. Its handler calls the
@@ -68,13 +65,17 @@
68 65
69#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) 66#define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25)
70 67
68#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos))
69
70/*
71 * Test if load/store instructions writeback the address register.
72 * if P (bit 24) == 0 or W (bit 21) == 1
73 */
74#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000)
75
71#define PSR_fs (PSR_f|PSR_s) 76#define PSR_fs (PSR_f|PSR_s)
72 77
73#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ 78#define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */
74#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */
75
76#define truecc_insn(insn) (((insn) & 0xf0000000) | \
77 (SET_R0_TRUE_INSTRUCTION & 0x0fffffff))
78 79
79typedef long (insn_0arg_fn_t)(void); 80typedef long (insn_0arg_fn_t)(void);
80typedef long (insn_1arg_fn_t)(long); 81typedef long (insn_1arg_fn_t)(long);
@@ -419,14 +420,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr,
419 420
420static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) 421static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs)
421{ 422{
422 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
423 kprobe_opcode_t insn = p->opcode; 423 kprobe_opcode_t insn = p->opcode;
424 long iaddr = (long)p->addr; 424 long iaddr = (long)p->addr;
425 int disp = branch_displacement(insn); 425 int disp = branch_displacement(insn);
426 426
427 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
428 return;
429
430 if (insn & (1 << 24)) 427 if (insn & (1 << 24))
431 regs->ARM_lr = iaddr + 4; 428 regs->ARM_lr = iaddr + 4;
432 429
@@ -446,14 +443,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs)
446 443
447static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) 444static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
448{ 445{
449 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
450 kprobe_opcode_t insn = p->opcode; 446 kprobe_opcode_t insn = p->opcode;
451 int rm = insn & 0xf; 447 int rm = insn & 0xf;
452 long rmv = regs->uregs[rm]; 448 long rmv = regs->uregs[rm];
453 449
454 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
455 return;
456
457 if (insn & (1 << 5)) 450 if (insn & (1 << 5))
458 regs->ARM_lr = (long)p->addr + 4; 451 regs->ARM_lr = (long)p->addr + 4;
459 452
@@ -463,9 +456,16 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs)
463 regs->ARM_cpsr |= PSR_T_BIT; 456 regs->ARM_cpsr |= PSR_T_BIT;
464} 457}
465 458
459static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs)
460{
461 kprobe_opcode_t insn = p->opcode;
462 int rd = (insn >> 12) & 0xf;
463 unsigned long mask = 0xf8ff03df; /* Mask out execution state */
464 regs->uregs[rd] = regs->ARM_cpsr & mask;
465}
466
466static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) 467static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
467{ 468{
468 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
469 kprobe_opcode_t insn = p->opcode; 469 kprobe_opcode_t insn = p->opcode;
470 int rn = (insn >> 16) & 0xf; 470 int rn = (insn >> 16) & 0xf;
471 int lbit = insn & (1 << 20); 471 int lbit = insn & (1 << 20);
@@ -476,9 +476,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
476 int reg_bit_vector; 476 int reg_bit_vector;
477 int reg_count; 477 int reg_count;
478 478
479 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
480 return;
481
482 reg_count = 0; 479 reg_count = 0;
483 reg_bit_vector = insn & 0xffff; 480 reg_bit_vector = insn & 0xffff;
484 while (reg_bit_vector) { 481 while (reg_bit_vector) {
@@ -510,11 +507,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
510 507
511static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) 508static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
512{ 509{
513 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
514
515 if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn))
516 return;
517
518 regs->ARM_pc = (long)p->addr + str_pc_offset; 510 regs->ARM_pc = (long)p->addr + str_pc_offset;
519 simulate_ldm1stm1(p, regs); 511 simulate_ldm1stm1(p, regs);
520 regs->ARM_pc = (long)p->addr + 4; 512 regs->ARM_pc = (long)p->addr + 4;
@@ -525,24 +517,16 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs)
525 regs->uregs[12] = regs->uregs[13]; 517 regs->uregs[12] = regs->uregs[13];
526} 518}
527 519
528static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs)
529{
530 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
531 kprobe_opcode_t insn = p->opcode;
532 int rn = (insn >> 16) & 0xf;
533 long rnv = regs->uregs[rn];
534
535 /* Save Rn in case of writeback. */
536 regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn);
537}
538
539static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) 520static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
540{ 521{
541 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; 522 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
542 kprobe_opcode_t insn = p->opcode; 523 kprobe_opcode_t insn = p->opcode;
524 long ppc = (long)p->addr + 8;
543 int rd = (insn >> 12) & 0xf; 525 int rd = (insn >> 12) & 0xf;
544 int rn = (insn >> 16) & 0xf; 526 int rn = (insn >> 16) & 0xf;
545 int rm = insn & 0xf; /* rm may be invalid, don't care. */ 527 int rm = insn & 0xf; /* rm may be invalid, don't care. */
528 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
529 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
546 530
547 /* Not following the C calling convention here, so need asm(). */ 531 /* Not following the C calling convention here, so need asm(). */
548 __asm__ __volatile__ ( 532 __asm__ __volatile__ (
@@ -554,29 +538,36 @@ static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs)
554 "str r0, %[rn] \n\t" /* in case of writeback */ 538 "str r0, %[rn] \n\t" /* in case of writeback */
555 "str r2, %[rd0] \n\t" 539 "str r2, %[rd0] \n\t"
556 "str r3, %[rd1] \n\t" 540 "str r3, %[rd1] \n\t"
557 : [rn] "+m" (regs->uregs[rn]), 541 : [rn] "+m" (rnv),
558 [rd0] "=m" (regs->uregs[rd]), 542 [rd0] "=m" (regs->uregs[rd]),
559 [rd1] "=m" (regs->uregs[rd+1]) 543 [rd1] "=m" (regs->uregs[rd+1])
560 : [rm] "m" (regs->uregs[rm]), 544 : [rm] "m" (rmv),
561 [cpsr] "r" (regs->ARM_cpsr), 545 [cpsr] "r" (regs->ARM_cpsr),
562 [i_fn] "r" (i_fn) 546 [i_fn] "r" (i_fn)
563 : "r0", "r1", "r2", "r3", "lr", "cc" 547 : "r0", "r1", "r2", "r3", "lr", "cc"
564 ); 548 );
549 if (is_writeback(insn))
550 regs->uregs[rn] = rnv;
565} 551}
566 552
567static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) 553static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs)
568{ 554{
569 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; 555 insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0];
570 kprobe_opcode_t insn = p->opcode; 556 kprobe_opcode_t insn = p->opcode;
557 long ppc = (long)p->addr + 8;
571 int rd = (insn >> 12) & 0xf; 558 int rd = (insn >> 12) & 0xf;
572 int rn = (insn >> 16) & 0xf; 559 int rn = (insn >> 16) & 0xf;
573 int rm = insn & 0xf; 560 int rm = insn & 0xf;
574 long rnv = regs->uregs[rn]; 561 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
575 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ 562 /* rm/rmv may be invalid, don't care. */
563 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
564 long rnv_wb;
576 565
577 regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], 566 rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd],
578 regs->uregs[rd+1], 567 regs->uregs[rd+1],
579 regs->ARM_cpsr, i_fn); 568 regs->ARM_cpsr, i_fn);
569 if (is_writeback(insn))
570 regs->uregs[rn] = rnv_wb;
580} 571}
581 572
582static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) 573static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
@@ -594,7 +585,8 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
594 long cpsr = regs->ARM_cpsr; 585 long cpsr = regs->ARM_cpsr;
595 586
596 fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn); 587 fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
597 regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */ 588 if (rn != 15)
589 regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */
598 rdv = fnr.r1; 590 rdv = fnr.r1;
599 591
600 if (rd == 15) { 592 if (rd == 15) {
@@ -622,35 +614,11 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
622 long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd]; 614 long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
623 long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn]; 615 long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn];
624 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ 616 long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
617 long rnv_wb;
625 618
626 /* Save Rn in case of writeback. */ 619 rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
627 regs->uregs[rn] = 620 if (rn != 15)
628 insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn); 621 regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */
629}
630
631static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
632{
633 insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0];
634 kprobe_opcode_t insn = p->opcode;
635 union reg_pair fnr;
636 int rd = (insn >> 12) & 0xf;
637 int rn = (insn >> 16) & 0xf;
638
639 fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn);
640 regs->uregs[rn] = fnr.r0;
641 regs->uregs[rd] = fnr.r1;
642}
643
644static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs)
645{
646 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
647 kprobe_opcode_t insn = p->opcode;
648 int rd = (insn >> 12) & 0xf;
649 int rn = (insn >> 16) & 0xf;
650 long rnv = regs->uregs[rn];
651 long rdv = regs->uregs[rd];
652
653 insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn);
654} 622}
655 623
656static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) 624static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs)
@@ -686,32 +654,32 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs)
686 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); 654 insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
687} 655}
688 656
689static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) 657static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs)
690{ 658{
691 insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0];
692 kprobe_opcode_t insn = p->opcode;
693 int rd = (insn >> 12) & 0xf;
694
695 regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn);
696} 659}
697 660
698static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) 661static void __kprobes
662emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs)
699{ 663{
700 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 664 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
701 kprobe_opcode_t insn = p->opcode; 665 kprobe_opcode_t insn = p->opcode;
702 int ird = (insn >> 12) & 0xf; 666 int rd = (insn >> 12) & 0xf;
667 long rdv = regs->uregs[rd];
703 668
704 insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); 669 regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn);
705} 670}
706 671
707static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) 672static void __kprobes
673emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs)
708{ 674{
709 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; 675 insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0];
710 kprobe_opcode_t insn = p->opcode; 676 kprobe_opcode_t insn = p->opcode;
711 int rn = (insn >> 16) & 0xf; 677 int rd = (insn >> 12) & 0xf;
678 int rn = insn & 0xf;
679 long rdv = regs->uregs[rd];
712 long rnv = regs->uregs[rn]; 680 long rnv = regs->uregs[rn];
713 681
714 insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); 682 regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn);
715} 683}
716 684
717static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) 685static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs)
@@ -817,6 +785,17 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs)
817} 785}
818 786
819static void __kprobes 787static void __kprobes
788emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs)
789{
790 insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0];
791 kprobe_opcode_t insn = p->opcode;
792 int rn = (insn >> 16) & 0xf;
793 long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn];
794
795 insnslot_1arg_rwflags(rnv, &regs->ARM_cpsr, i_fn);
796}
797
798static void __kprobes
820emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) 799emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs)
821{ 800{
822 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; 801 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
@@ -852,14 +831,34 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs)
852 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn); 831 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
853} 832}
854 833
834static void __kprobes
835emulate_alu_tests(struct kprobe *p, struct pt_regs *regs)
836{
837 insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0];
838 kprobe_opcode_t insn = p->opcode;
839 long ppc = (long)p->addr + 8;
840 int rn = (insn >> 16) & 0xf;
841 int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */
842 int rm = insn & 0xf;
843 long rnv = (rn == 15) ? ppc : regs->uregs[rn];
844 long rmv = (rm == 15) ? ppc : regs->uregs[rm];
845 long rsv = regs->uregs[rs];
846
847 insnslot_3arg_rwflags(rnv, rmv, rsv, &regs->ARM_cpsr, i_fn);
848}
849
855static enum kprobe_insn __kprobes 850static enum kprobe_insn __kprobes
856prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) 851prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
857{ 852{
858 int ibit = (insn & (1 << 26)) ? 25 : 22; 853 int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25))
854 : (~insn & (1 << 22));
855
856 if (is_writeback(insn) && is_r15(insn, 16))
857 return INSN_REJECTED; /* Writeback to PC */
859 858
860 insn &= 0xfff00fff; 859 insn &= 0xfff00fff;
861 insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 860 insn |= 0x00001000; /* Rn = r0, Rd = r1 */
862 if (insn & (1 << ibit)) { 861 if (not_imm) {
863 insn &= ~0xf; 862 insn &= ~0xf;
864 insn |= 2; /* Rm = r2 */ 863 insn |= 2; /* Rm = r2 */
865 } 864 }
@@ -869,20 +868,40 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi)
869} 868}
870 869
871static enum kprobe_insn __kprobes 870static enum kprobe_insn __kprobes
872prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) 871prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi)
873{ 872{
874 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 873 if (is_r15(insn, 12))
874 return INSN_REJECTED; /* Rd is PC */
875
876 insn &= 0xffff0fff; /* Rd = r0 */
875 asi->insn[0] = insn; 877 asi->insn[0] = insn;
876 asi->insn_handler = emulate_rd12rm0; 878 asi->insn_handler = emulate_rd12_modify;
877 return INSN_GOOD; 879 return INSN_GOOD;
878} 880}
879 881
880static enum kprobe_insn __kprobes 882static enum kprobe_insn __kprobes
881prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) 883prep_emulate_rd12rn0_modify(kprobe_opcode_t insn,
884 struct arch_specific_insn *asi)
882{ 885{
883 insn &= 0xffff0fff; /* Rd = r0 */ 886 if (is_r15(insn, 12))
887 return INSN_REJECTED; /* Rd is PC */
888
889 insn &= 0xffff0ff0; /* Rd = r0 */
890 insn |= 0x00000001; /* Rn = r1 */
891 asi->insn[0] = insn;
892 asi->insn_handler = emulate_rd12rn0_modify;
893 return INSN_GOOD;
894}
895
896static enum kprobe_insn __kprobes
897prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi)
898{
899 if (is_r15(insn, 12))
900 return INSN_REJECTED; /* Rd is PC */
901
902 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
884 asi->insn[0] = insn; 903 asi->insn[0] = insn;
885 asi->insn_handler = emulate_rd12; 904 asi->insn_handler = emulate_rd12rm0;
886 return INSN_GOOD; 905 return INSN_GOOD;
887} 906}
888 907
@@ -890,6 +909,9 @@ static enum kprobe_insn __kprobes
890prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, 909prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn,
891 struct arch_specific_insn *asi) 910 struct arch_specific_insn *asi)
892{ 911{
912 if (is_r15(insn, 12))
913 return INSN_REJECTED; /* Rd is PC */
914
893 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 915 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
894 insn |= 0x00000001; /* Rm = r1 */ 916 insn |= 0x00000001; /* Rm = r1 */
895 asi->insn[0] = insn; 917 asi->insn[0] = insn;
@@ -901,6 +923,9 @@ static enum kprobe_insn __kprobes
901prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, 923prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn,
902 struct arch_specific_insn *asi) 924 struct arch_specific_insn *asi)
903{ 925{
926 if (is_r15(insn, 16))
927 return INSN_REJECTED; /* Rd is PC */
928
904 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ 929 insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */
905 insn |= 0x00000001; /* Rm = r1 */ 930 insn |= 0x00000001; /* Rm = r1 */
906 asi->insn[0] = insn; 931 asi->insn[0] = insn;
@@ -912,6 +937,9 @@ static enum kprobe_insn __kprobes
912prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, 937prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn,
913 struct arch_specific_insn *asi) 938 struct arch_specific_insn *asi)
914{ 939{
940 if (is_r15(insn, 16))
941 return INSN_REJECTED; /* Rd is PC */
942
915 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ 943 insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */
916 insn |= 0x00000102; /* Rs = r1, Rm = r2 */ 944 insn |= 0x00000102; /* Rs = r1, Rm = r2 */
917 asi->insn[0] = insn; 945 asi->insn[0] = insn;
@@ -923,6 +951,9 @@ static enum kprobe_insn __kprobes
923prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, 951prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
924 struct arch_specific_insn *asi) 952 struct arch_specific_insn *asi)
925{ 953{
954 if (is_r15(insn, 16) || is_r15(insn, 12))
955 return INSN_REJECTED; /* RdHi or RdLo is PC */
956
926 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ 957 insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */
927 insn |= 0x00001203; /* Rs = r2, Rm = r3 */ 958 insn |= 0x00001203; /* Rs = r2, Rm = r3 */
928 asi->insn[0] = insn; 959 asi->insn[0] = insn;
@@ -943,20 +974,13 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn,
943static enum kprobe_insn __kprobes 974static enum kprobe_insn __kprobes
944space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) 975space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
945{ 976{
946 /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ 977 /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */
947 /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ 978 /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */
948 /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ 979 /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */
949 if ((insn & 0xfff30020) == 0xf1020000 || 980 /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */
950 (insn & 0xfe500f00) == 0xf8100a00 || 981 if ((insn & 0xfe300000) == 0xf4100000) {
951 (insn & 0xfe5f0f00) == 0xf84d0500) 982 asi->insn_handler = emulate_nop;
952 return INSN_REJECTED; 983 return INSN_GOOD_NO_SLOT;
953
954 /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */
955 if ((insn & 0xfd700000) == 0xf4500000) {
956 insn &= 0xfff0ffff; /* Rn = r0 */
957 asi->insn[0] = insn;
958 asi->insn_handler = emulate_rn16;
959 return INSN_GOOD;
960 } 984 }
961 985
962 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ 986 /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */
@@ -965,41 +989,22 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi)
965 return INSN_GOOD_NO_SLOT; 989 return INSN_GOOD_NO_SLOT;
966 } 990 }
967 991
968 /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ 992 /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */
969 /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 993 /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */
970 if ((insn & 0xffff00f0) == 0xf1010000 || 994
971 (insn & 0xff000010) == 0xfe000000) { 995 /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */
972 asi->insn[0] = insn; 996 /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
973 asi->insn_handler = emulate_none;
974 return INSN_GOOD;
975 }
976 997
998 /* Coprocessor instructions... */
977 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 999 /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
978 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ 1000 /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */
979 if ((insn & 0xffe00000) == 0xfc400000) { 1001 /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
980 insn &= 0xfff00fff; /* Rn = r0 */ 1002 /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
981 insn |= 0x00001000; /* Rd = r1 */ 1003 /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
982 asi->insn[0] = insn; 1004 /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
983 asi->insn_handler = 1005 /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
984 (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr;
985 return INSN_GOOD;
986 }
987 1006
988 /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1007 return INSN_REJECTED;
989 /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
990 if ((insn & 0xfe000000) == 0xfc000000) {
991 insn &= 0xfff0ffff; /* Rn = r0 */
992 asi->insn[0] = insn;
993 asi->insn_handler = emulate_ldcstc;
994 return INSN_GOOD;
995 }
996
997 /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
998 /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
999 insn &= 0xffff0fff; /* Rd = r0 */
1000 asi->insn[0] = insn;
1001 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1002 return INSN_GOOD;
1003} 1008}
1004 1009
1005static enum kprobe_insn __kprobes 1010static enum kprobe_insn __kprobes
@@ -1008,19 +1013,18 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1008 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1013 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */
1009 if ((insn & 0x0f900010) == 0x01000000) { 1014 if ((insn & 0x0f900010) == 0x01000000) {
1010 1015
1011 /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ 1016 /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */
1012 /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ 1017 if ((insn & 0x0ff000f0) == 0x01000000) {
1013 if ((insn & 0x0ff000f0) == 0x01200020 || 1018 if (is_r15(insn, 12))
1014 (insn & 0x0fb000f0) == 0x01200000) 1019 return INSN_REJECTED; /* Rd is PC */
1015 return INSN_REJECTED; 1020 asi->insn_handler = simulate_mrs;
1016 1021 return INSN_GOOD_NO_SLOT;
1017 /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ 1022 }
1018 if ((insn & 0x0fb00010) == 0x01000000)
1019 return prep_emulate_rd12(insn, asi);
1020 1023
1021 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ 1024 /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */
1022 if ((insn & 0x0ff00090) == 0x01400080) 1025 if ((insn & 0x0ff00090) == 0x01400080)
1023 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1026 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1027 asi);
1024 1028
1025 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ 1029 /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */
1026 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ 1030 /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */
@@ -1029,24 +1033,29 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1029 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1033 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1030 1034
1031 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ 1035 /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */
1032 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ 1036 /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */
1033 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1037 if ((insn & 0x0ff00090) == 0x01000080 ||
1038 (insn & 0x0ff000b0) == 0x01200080)
1039 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1034 1040
1041 /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */
1042 /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */
1043 /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */
1044
1045 /* Other instruction encodings aren't yet defined */
1046 return INSN_REJECTED;
1035 } 1047 }
1036 1048
1037 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ 1049 /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */
1038 else if ((insn & 0x0f900090) == 0x01000010) { 1050 else if ((insn & 0x0f900090) == 0x01000010) {
1039 1051
1040 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1041 if ((insn & 0xfff000f0) == 0xe1200070)
1042 return INSN_REJECTED;
1043
1044 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ 1052 /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */
1045 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ 1053 /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */
1046 if ((insn & 0x0ff000d0) == 0x01200010) { 1054 if ((insn & 0x0ff000d0) == 0x01200010) {
1047 asi->insn[0] = truecc_insn(insn); 1055 if ((insn & 0x0ff000ff) == 0x0120003f)
1056 return INSN_REJECTED; /* BLX pc */
1048 asi->insn_handler = simulate_blx2bx; 1057 asi->insn_handler = simulate_blx2bx;
1049 return INSN_GOOD; 1058 return INSN_GOOD_NO_SLOT;
1050 } 1059 }
1051 1060
1052 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ 1061 /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */
@@ -1057,17 +1066,27 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1057 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ 1066 /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */
1058 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ 1067 /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */
1059 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ 1068 /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */
1060 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1069 if ((insn & 0x0f9000f0) == 0x01000050)
1070 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1071
1072 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */
1073 /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */
1074
1075 /* Other instruction encodings aren't yet defined */
1076 return INSN_REJECTED;
1061 } 1077 }
1062 1078
1063 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ 1079 /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */
1064 else if ((insn & 0x0f000090) == 0x00000090) { 1080 else if ((insn & 0x0f0000f0) == 0x00000090) {
1065 1081
1066 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ 1082 /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */
1067 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ 1083 /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */
1068 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ 1084 /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */
1069 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ 1085 /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */
1070 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ 1086 /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */
1087 /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */
1088 /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */
1089 /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */
1071 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ 1090 /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */
1072 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ 1091 /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */
1073 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ 1092 /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */
@@ -1076,13 +1095,15 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1076 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ 1095 /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */
1077 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ 1096 /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */
1078 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ 1097 /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */
1079 if ((insn & 0x0fe000f0) == 0x00000090) { 1098 if ((insn & 0x00d00000) == 0x00500000)
1080 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1099 return INSN_REJECTED;
1081 } else if ((insn & 0x0fe000f0) == 0x00200090) { 1100 else if ((insn & 0x00e00000) == 0x00000000)
1082 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1101 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1083 } else { 1102 else if ((insn & 0x00a00000) == 0x00200000)
1084 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1103 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1085 } 1104 else
1105 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn,
1106 asi);
1086 } 1107 }
1087 1108
1088 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ 1109 /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */
@@ -1090,23 +1111,45 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1090 1111
1091 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ 1112 /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */
1092 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ 1113 /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */
1093 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ 1114 /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */
1094 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ 1115 /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */
1116 /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */
1095 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ 1117 /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */
1096 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ 1118 /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */
1119 /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */
1120 /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */
1121 /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */
1122 /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */
1123 /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */
1124 /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */
1125
1126 /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */
1127 /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */
1097 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ 1128 /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */
1098 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ 1129 /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */
1099 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ 1130 /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */
1100 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ 1131 /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */
1101 if ((insn & 0x0fb000f0) == 0x01000090) { 1132 if ((insn & 0x0f0000f0) == 0x01000090) {
1102 /* SWP/SWPB */ 1133 if ((insn & 0x0fb000f0) == 0x01000090) {
1103 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1134 /* SWP/SWPB */
1135 return prep_emulate_rd12rn16rm0_wflags(insn,
1136 asi);
1137 } else {
1138 /* STREX/LDREX variants and unallocaed space */
1139 return INSN_REJECTED;
1140 }
1141
1104 } else if ((insn & 0x0e1000d0) == 0x00000d0) { 1142 } else if ((insn & 0x0e1000d0) == 0x00000d0) {
1105 /* STRD/LDRD */ 1143 /* STRD/LDRD */
1144 if ((insn & 0x0000e000) == 0x0000e000)
1145 return INSN_REJECTED; /* Rd is LR or PC */
1146 if (is_writeback(insn) && is_r15(insn, 16))
1147 return INSN_REJECTED; /* Writeback to PC */
1148
1106 insn &= 0xfff00fff; 1149 insn &= 0xfff00fff;
1107 insn |= 0x00002000; /* Rn = r0, Rd = r2 */ 1150 insn |= 0x00002000; /* Rn = r0, Rd = r2 */
1108 if (insn & (1 << 22)) { 1151 if (!(insn & (1 << 22))) {
1109 /* I bit */ 1152 /* Register index */
1110 insn &= ~0xf; 1153 insn &= ~0xf;
1111 insn |= 1; /* Rm = r1 */ 1154 insn |= 1; /* Rm = r1 */
1112 } 1155 }
@@ -1116,6 +1159,9 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1116 return INSN_GOOD; 1159 return INSN_GOOD;
1117 } 1160 }
1118 1161
1162 /* LDRH/STRH/LDRSB/LDRSH */
1163 if (is_r15(insn, 12))
1164 return INSN_REJECTED; /* Rd is PC */
1119 return prep_emulate_ldr_str(insn, asi); 1165 return prep_emulate_ldr_str(insn, asi);
1120 } 1166 }
1121 1167
@@ -1123,7 +1169,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1123 1169
1124 /* 1170 /*
1125 * ALU op with S bit and Rd == 15 : 1171 * ALU op with S bit and Rd == 15 :
1126 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx 1172 * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx
1127 */ 1173 */
1128 if ((insn & 0x0e10f000) == 0x0010f000) 1174 if ((insn & 0x0e10f000) == 0x0010f000)
1129 return INSN_REJECTED; 1175 return INSN_REJECTED;
@@ -1152,22 +1198,61 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1152 insn |= 0x00000200; /* Rs = r2 */ 1198 insn |= 0x00000200; /* Rs = r2 */
1153 } 1199 }
1154 asi->insn[0] = insn; 1200 asi->insn[0] = insn;
1155 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1201
1202 if ((insn & 0x0f900000) == 0x01100000) {
1203 /*
1204 * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx
1205 * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx
1206 * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx
1207 * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx
1208 */
1209 asi->insn_handler = emulate_alu_tests;
1210 } else {
1211 /* ALU ops which write to Rd */
1212 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1156 emulate_alu_rwflags : emulate_alu_rflags; 1213 emulate_alu_rwflags : emulate_alu_rflags;
1214 }
1157 return INSN_GOOD; 1215 return INSN_GOOD;
1158} 1216}
1159 1217
1160static enum kprobe_insn __kprobes 1218static enum kprobe_insn __kprobes
1161space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1219space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1162{ 1220{
1221 /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
1222 /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
1223 if ((insn & 0x0fb00000) == 0x03000000)
1224 return prep_emulate_rd12_modify(insn, asi);
1225
1226 /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
1227 if ((insn & 0x0fff0000) == 0x03200000) {
1228 unsigned op2 = insn & 0x000000ff;
1229 if (op2 == 0x01 || op2 == 0x04) {
1230 /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
1231 /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
1232 asi->insn[0] = insn;
1233 asi->insn_handler = emulate_none;
1234 return INSN_GOOD;
1235 } else if (op2 <= 0x03) {
1236 /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
1237 /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
1238 /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
1239 /*
1240 * We make WFE and WFI true NOPs to avoid stalls due
1241 * to missing events whilst processing the probe.
1242 */
1243 asi->insn_handler = emulate_nop;
1244 return INSN_GOOD_NO_SLOT;
1245 }
1246 /* For DBG and unallocated hints it's safest to reject them */
1247 return INSN_REJECTED;
1248 }
1249
1163 /* 1250 /*
1164 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx 1251 * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx
1165 * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx
1166 * ALU op with S bit and Rd == 15 : 1252 * ALU op with S bit and Rd == 15 :
1167 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx 1253 * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx
1168 */ 1254 */
1169 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ 1255 if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */
1170 (insn & 0x0ff00000) == 0x03400000 || /* Undef */
1171 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ 1256 (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */
1172 return INSN_REJECTED; 1257 return INSN_REJECTED;
1173 1258
@@ -1178,10 +1263,22 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1178 * *S (bit 20) updates condition codes 1263 * *S (bit 20) updates condition codes
1179 * ADC/SBC/RSC reads the C flag 1264 * ADC/SBC/RSC reads the C flag
1180 */ 1265 */
1181 insn &= 0xffff0fff; /* Rd = r0 */ 1266 insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */
1182 asi->insn[0] = insn; 1267 asi->insn[0] = insn;
1183 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ 1268
1269 if ((insn & 0x0f900000) == 0x03100000) {
1270 /*
1271 * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx
1272 * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx
1273 * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx
1274 * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx
1275 */
1276 asi->insn_handler = emulate_alu_tests_imm;
1277 } else {
1278 /* ALU ops which write to Rd */
1279 asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */
1184 emulate_alu_imm_rwflags : emulate_alu_imm_rflags; 1280 emulate_alu_imm_rwflags : emulate_alu_imm_rflags;
1281 }
1185 return INSN_GOOD; 1282 return INSN_GOOD;
1186} 1283}
1187 1284
@@ -1190,6 +1287,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1190{ 1287{
1191 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ 1288 /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */
1192 if ((insn & 0x0ff000f0) == 0x068000b0) { 1289 if ((insn & 0x0ff000f0) == 0x068000b0) {
1290 if (is_r15(insn, 12))
1291 return INSN_REJECTED; /* Rd is PC */
1193 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ 1292 insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */
1194 insn |= 0x00000001; /* Rm = r1 */ 1293 insn |= 0x00000001; /* Rm = r1 */
1195 asi->insn[0] = insn; 1294 asi->insn[0] = insn;
@@ -1203,6 +1302,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1203 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ 1302 /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */
1204 if ((insn & 0x0fa00030) == 0x06a00010 || 1303 if ((insn & 0x0fa00030) == 0x06a00010 ||
1205 (insn & 0x0fb000f0) == 0x06a00030) { 1304 (insn & 0x0fb000f0) == 0x06a00030) {
1305 if (is_r15(insn, 12))
1306 return INSN_REJECTED; /* Rd is PC */
1206 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ 1307 insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */
1207 asi->insn[0] = insn; 1308 asi->insn[0] = insn;
1208 asi->insn_handler = emulate_sat; 1309 asi->insn_handler = emulate_sat;
@@ -1211,57 +1312,101 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1211 1312
1212 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ 1313 /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */
1213 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ 1314 /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */
1315 /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */
1214 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ 1316 /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */
1215 if ((insn & 0x0ff00070) == 0x06b00030 || 1317 if ((insn & 0x0ff00070) == 0x06b00030 ||
1216 (insn & 0x0ff000f0) == 0x06f000b0) 1318 (insn & 0x0ff00070) == 0x06f00030)
1217 return prep_emulate_rd12rm0(insn, asi); 1319 return prep_emulate_rd12rm0(insn, asi);
1218 1320
1321 /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */
1219 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ 1322 /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */
1220 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ 1323 /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */
1221 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ 1324 /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */
1222 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ 1325 /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */
1223 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ 1326 /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */
1327 /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */
1328 /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */
1224 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ 1329 /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */
1225 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ 1330 /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */
1226 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ 1331 /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */
1227 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ 1332 /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */
1228 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ 1333 /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */
1229 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ 1334 /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */
1335 /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */
1336 /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */
1230 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ 1337 /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */
1231 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ 1338 /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */
1232 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ 1339 /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */
1233 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ 1340 /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */
1234 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ 1341 /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */
1235 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ 1342 /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */
1343 /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */
1344 /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */
1236 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ 1345 /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */
1346 /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */
1237 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ 1347 /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */
1238 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ 1348 /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */
1239 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ 1349 /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */
1240 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ 1350 /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */
1241 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ 1351 /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */
1352 /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */
1353 /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */
1242 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ 1354 /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */
1243 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ 1355 /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */
1244 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ 1356 /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */
1245 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ 1357 /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */
1246 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ 1358 /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */
1247 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ 1359 /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */
1360 /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */
1361 /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */
1248 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ 1362 /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */
1249 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ 1363 /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */
1250 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ 1364 /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */
1251 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ 1365 /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */
1252 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ 1366 /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */
1253 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ 1367 /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */
1368 /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */
1369 /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */
1254 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ 1370 /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */
1371 if ((insn & 0x0f800010) == 0x06000010) {
1372 if ((insn & 0x00300000) == 0x00000000 ||
1373 (insn & 0x000000e0) == 0x000000a0 ||
1374 (insn & 0x000000e0) == 0x000000c0)
1375 return INSN_REJECTED; /* Unallocated space */
1376 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1377 }
1378
1255 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ 1379 /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */
1256 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ 1380 /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */
1381 if ((insn & 0x0ff00030) == 0x06800010)
1382 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1383
1257 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ 1384 /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */
1258 /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1385 /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */
1386 /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */
1259 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ 1387 /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */
1388 /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */
1260 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ 1389 /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */
1390 /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */
1261 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ 1391 /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */
1392 /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */
1393 /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */
1262 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ 1394 /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */
1395 /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */
1263 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ 1396 /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */
1264 return prep_emulate_rd12rn16rm0_wflags(insn, asi); 1397 /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */
1398 if ((insn & 0x0f8000f0) == 0x06800070) {
1399 if ((insn & 0x00300000) == 0x00100000)
1400 return INSN_REJECTED; /* Unallocated space */
1401
1402 if ((insn & 0x000f0000) == 0x000f0000)
1403 return prep_emulate_rd12rm0(insn, asi);
1404 else
1405 return prep_emulate_rd12rn16rm0_wflags(insn, asi);
1406 }
1407
1408 /* Other instruction encodings aren't yet defined */
1409 return INSN_REJECTED;
1265} 1410}
1266 1411
1267static enum kprobe_insn __kprobes 1412static enum kprobe_insn __kprobes
@@ -1271,29 +1416,49 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1271 if ((insn & 0x0ff000f0) == 0x03f000f0) 1416 if ((insn & 0x0ff000f0) == 0x03f000f0)
1272 return INSN_REJECTED; 1417 return INSN_REJECTED;
1273 1418
1274 /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */
1275 /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */
1276 if ((insn & 0x0ff000f0) == 0x07800010)
1277 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1278
1279 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ 1419 /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */
1280 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ 1420 /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */
1281 if ((insn & 0x0ff00090) == 0x07400010) 1421 if ((insn & 0x0ff00090) == 0x07400010)
1282 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); 1422 return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi);
1283 1423
1284 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ 1424 /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */
1425 /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */
1285 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ 1426 /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */
1427 /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */
1286 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ 1428 /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */
1287 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ 1429 /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */
1430 /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */
1431 /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */
1288 if ((insn & 0x0ff00090) == 0x07000010 || 1432 if ((insn & 0x0ff00090) == 0x07000010 ||
1289 (insn & 0x0ff000d0) == 0x07500010 || 1433 (insn & 0x0ff000d0) == 0x07500010 ||
1290 (insn & 0x0ff000d0) == 0x075000d0) 1434 (insn & 0x0ff000f0) == 0x07800010) {
1435
1436 if ((insn & 0x0000f000) == 0x0000f000)
1437 return prep_emulate_rd16rs8rm0_wflags(insn, asi);
1438 else
1439 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1440 }
1441
1442 /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */
1443 if ((insn & 0x0ff000d0) == 0x075000d0)
1291 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); 1444 return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi);
1292 1445
1293 /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ 1446 /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */
1294 /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ 1447 /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */
1295 /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ 1448 if ((insn & 0x0fa00070) == 0x07a00050)
1296 return prep_emulate_rd16rs8rm0_wflags(insn, asi); 1449 return prep_emulate_rd12rm0(insn, asi);
1450
1451 /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */
1452 /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */
1453 if ((insn & 0x0fe00070) == 0x07c00010) {
1454
1455 if ((insn & 0x0000000f) == 0x0000000f)
1456 return prep_emulate_rd12_modify(insn, asi);
1457 else
1458 return prep_emulate_rd12rn0_modify(insn, asi);
1459 }
1460
1461 return INSN_REJECTED;
1297} 1462}
1298 1463
1299static enum kprobe_insn __kprobes 1464static enum kprobe_insn __kprobes
@@ -1307,6 +1472,10 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1307 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ 1472 /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */
1308 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ 1473 /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */
1309 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ 1474 /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */
1475
1476 if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12))
1477 return INSN_REJECTED; /* LDRB into PC */
1478
1310 return prep_emulate_ldr_str(insn, asi); 1479 return prep_emulate_ldr_str(insn, asi);
1311} 1480}
1312 1481
@@ -1321,10 +1490,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1321 1490
1322 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ 1491 /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */
1323 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ 1492 /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */
1324 asi->insn[0] = truecc_insn(insn);
1325 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ 1493 asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */
1326 simulate_stm1_pc : simulate_ldm1stm1; 1494 simulate_stm1_pc : simulate_ldm1stm1;
1327 return INSN_GOOD; 1495 return INSN_GOOD_NO_SLOT;
1328} 1496}
1329 1497
1330static enum kprobe_insn __kprobes 1498static enum kprobe_insn __kprobes
@@ -1332,58 +1500,117 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1332{ 1500{
1333 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ 1501 /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */
1334 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ 1502 /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */
1335 asi->insn[0] = truecc_insn(insn);
1336 asi->insn_handler = simulate_bbl; 1503 asi->insn_handler = simulate_bbl;
1337 return INSN_GOOD; 1504 return INSN_GOOD_NO_SLOT;
1338} 1505}
1339 1506
1340static enum kprobe_insn __kprobes 1507static enum kprobe_insn __kprobes
1341space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1508space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1342{ 1509{
1510 /* Coprocessor instructions... */
1343 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1511 /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1344 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ 1512 /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */
1345 insn &= 0xfff00fff; 1513 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */
1346 insn |= 0x00001000; /* Rn = r0, Rd = r1 */ 1514 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1347 asi->insn[0] = insn; 1515 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */
1348 asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; 1516 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */
1349 return INSN_GOOD; 1517 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */
1518
1519 /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */
1520
1521 return INSN_REJECTED;
1350} 1522}
1351 1523
1352static enum kprobe_insn __kprobes 1524static unsigned long __kprobes __check_eq(unsigned long cpsr)
1353space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1354{ 1525{
1355 /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ 1526 return cpsr & PSR_Z_BIT;
1356 /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */
1357 insn &= 0xfff0ffff; /* Rn = r0 */
1358 asi->insn[0] = insn;
1359 asi->insn_handler = emulate_ldcstc;
1360 return INSN_GOOD;
1361} 1527}
1362 1528
1363static enum kprobe_insn __kprobes 1529static unsigned long __kprobes __check_ne(unsigned long cpsr)
1364space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1365{ 1530{
1366 /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ 1531 return (~cpsr) & PSR_Z_BIT;
1367 /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ 1532}
1368 if ((insn & 0xfff000f0) == 0xe1200070 ||
1369 (insn & 0x0f000000) == 0x0f000000)
1370 return INSN_REJECTED;
1371 1533
1372 /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ 1534static unsigned long __kprobes __check_cs(unsigned long cpsr)
1373 if ((insn & 0x0f000010) == 0x0e000000) { 1535{
1374 asi->insn[0] = insn; 1536 return cpsr & PSR_C_BIT;
1375 asi->insn_handler = emulate_none; 1537}
1376 return INSN_GOOD;
1377 }
1378 1538
1379 /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ 1539static unsigned long __kprobes __check_cc(unsigned long cpsr)
1380 /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ 1540{
1381 insn &= 0xffff0fff; /* Rd = r0 */ 1541 return (~cpsr) & PSR_C_BIT;
1382 asi->insn[0] = insn;
1383 asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12;
1384 return INSN_GOOD;
1385} 1542}
1386 1543
1544static unsigned long __kprobes __check_mi(unsigned long cpsr)
1545{
1546 return cpsr & PSR_N_BIT;
1547}
1548
1549static unsigned long __kprobes __check_pl(unsigned long cpsr)
1550{
1551 return (~cpsr) & PSR_N_BIT;
1552}
1553
1554static unsigned long __kprobes __check_vs(unsigned long cpsr)
1555{
1556 return cpsr & PSR_V_BIT;
1557}
1558
1559static unsigned long __kprobes __check_vc(unsigned long cpsr)
1560{
1561 return (~cpsr) & PSR_V_BIT;
1562}
1563
1564static unsigned long __kprobes __check_hi(unsigned long cpsr)
1565{
1566 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1567 return cpsr & PSR_C_BIT;
1568}
1569
1570static unsigned long __kprobes __check_ls(unsigned long cpsr)
1571{
1572 cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
1573 return (~cpsr) & PSR_C_BIT;
1574}
1575
1576static unsigned long __kprobes __check_ge(unsigned long cpsr)
1577{
1578 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1579 return (~cpsr) & PSR_N_BIT;
1580}
1581
1582static unsigned long __kprobes __check_lt(unsigned long cpsr)
1583{
1584 cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1585 return cpsr & PSR_N_BIT;
1586}
1587
1588static unsigned long __kprobes __check_gt(unsigned long cpsr)
1589{
1590 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1591 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1592 return (~temp) & PSR_N_BIT;
1593}
1594
1595static unsigned long __kprobes __check_le(unsigned long cpsr)
1596{
1597 unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
1598 temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */
1599 return temp & PSR_N_BIT;
1600}
1601
1602static unsigned long __kprobes __check_al(unsigned long cpsr)
1603{
1604 return true;
1605}
1606
1607static kprobe_check_cc * const condition_checks[16] = {
1608 &__check_eq, &__check_ne, &__check_cs, &__check_cc,
1609 &__check_mi, &__check_pl, &__check_vs, &__check_vc,
1610 &__check_hi, &__check_ls, &__check_ge, &__check_lt,
1611 &__check_gt, &__check_le, &__check_al, &__check_al
1612};
1613
1387/* Return: 1614/* Return:
1388 * INSN_REJECTED If instruction is one not allowed to kprobe, 1615 * INSN_REJECTED If instruction is one not allowed to kprobe,
1389 * INSN_GOOD If instruction is supported and uses instruction slot, 1616 * INSN_GOOD If instruction is supported and uses instruction slot,
@@ -1399,133 +1626,45 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1399enum kprobe_insn __kprobes 1626enum kprobe_insn __kprobes
1400arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) 1627arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi)
1401{ 1628{
1629 asi->insn_check_cc = condition_checks[insn>>28];
1402 asi->insn[1] = KPROBE_RETURN_INSTRUCTION; 1630 asi->insn[1] = KPROBE_RETURN_INSTRUCTION;
1403 1631
1404 if ((insn & 0xf0000000) == 0xf0000000) { 1632 if ((insn & 0xf0000000) == 0xf0000000)
1405 1633
1406 return space_1111(insn, asi); 1634 return space_1111(insn, asi);
1407 1635
1408 } else if ((insn & 0x0e000000) == 0x00000000) { 1636 else if ((insn & 0x0e000000) == 0x00000000)
1409 1637
1410 return space_cccc_000x(insn, asi); 1638 return space_cccc_000x(insn, asi);
1411 1639
1412 } else if ((insn & 0x0e000000) == 0x02000000) { 1640 else if ((insn & 0x0e000000) == 0x02000000)
1413 1641
1414 return space_cccc_001x(insn, asi); 1642 return space_cccc_001x(insn, asi);
1415 1643
1416 } else if ((insn & 0x0f000010) == 0x06000010) { 1644 else if ((insn & 0x0f000010) == 0x06000010)
1417 1645
1418 return space_cccc_0110__1(insn, asi); 1646 return space_cccc_0110__1(insn, asi);
1419 1647
1420 } else if ((insn & 0x0f000010) == 0x07000010) { 1648 else if ((insn & 0x0f000010) == 0x07000010)
1421 1649
1422 return space_cccc_0111__1(insn, asi); 1650 return space_cccc_0111__1(insn, asi);
1423 1651
1424 } else if ((insn & 0x0c000000) == 0x04000000) { 1652 else if ((insn & 0x0c000000) == 0x04000000)
1425 1653
1426 return space_cccc_01xx(insn, asi); 1654 return space_cccc_01xx(insn, asi);
1427 1655
1428 } else if ((insn & 0x0e000000) == 0x08000000) { 1656 else if ((insn & 0x0e000000) == 0x08000000)
1429 1657
1430 return space_cccc_100x(insn, asi); 1658 return space_cccc_100x(insn, asi);
1431 1659
1432 } else if ((insn & 0x0e000000) == 0x0a000000) { 1660 else if ((insn & 0x0e000000) == 0x0a000000)
1433 1661
1434 return space_cccc_101x(insn, asi); 1662 return space_cccc_101x(insn, asi);
1435 1663
1436 } else if ((insn & 0x0fe00000) == 0x0c400000) { 1664 return space_cccc_11xx(insn, asi);
1437
1438 return space_cccc_1100_010x(insn, asi);
1439
1440 } else if ((insn & 0x0e000000) == 0x0c400000) {
1441
1442 return space_cccc_110x(insn, asi);
1443
1444 }
1445
1446 return space_cccc_111x(insn, asi);
1447} 1665}
1448 1666
1449void __init arm_kprobe_decode_init(void) 1667void __init arm_kprobe_decode_init(void)
1450{ 1668{
1451 find_str_pc_offset(); 1669 find_str_pc_offset();
1452} 1670}
1453
1454
1455/*
1456 * All ARM instructions listed below.
1457 *
1458 * Instructions and their general purpose registers are given.
1459 * If a particular register may not use R15, it is prefixed with a "!".
1460 * If marked with a "*" means the value returned by reading R15
1461 * is implementation defined.
1462 *
1463 * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ
1464 * TST: Rd, Rn, Rm, !Rs
1465 * BX: Rm
1466 * BLX(2): !Rm
1467 * BX: Rm (R15 legal, but discouraged)
1468 * BXJ: !Rm,
1469 * CLZ: !Rd, !Rm
1470 * CPY: Rd, Rm
1471 * LDC/2,STC/2 immediate offset & unindex: Rn
1472 * LDC/2,STC/2 immediate pre/post-indexed: !Rn
1473 * LDM(1/3): !Rn, register_list
1474 * LDM(2): !Rn, !register_list
1475 * LDR,STR,PLD immediate offset: Rd, Rn
1476 * LDR,STR,PLD register offset: Rd, Rn, !Rm
1477 * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm
1478 * LDR,STR immediate pre/post-indexed: Rd, !Rn
1479 * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm
1480 * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm
1481 * LDRB,STRB immediate offset: !Rd, Rn
1482 * LDRB,STRB register offset: !Rd, Rn, !Rm
1483 * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm
1484 * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn
1485 * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm
1486 * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm
1487 * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn
1488 * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm
1489 * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm
1490 * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn
1491 * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm
1492 * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn
1493 * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm
1494 * LDREX: !Rd, !Rn
1495 * MCR/2: !Rd
1496 * MCRR/2,MRRC/2: !Rd, !Rn
1497 * MLA: !Rd, !Rn, !Rm, !Rs
1498 * MOV: Rd
1499 * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register)
1500 * MRS,MSR: !Rd
1501 * MUL: !Rd, !Rm, !Rs
1502 * PKH{BT,TB}: !Rd, !Rn, !Rm
1503 * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn
1504 * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn
1505 * REV/16/SH: !Rd, !Rm
1506 * RFE: !Rn
1507 * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm
1508 * SEL: !Rd, !Rn, !Rm
1509 * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs
1510 * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs
1511 * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs
1512 * SSAT/16: !Rd, !Rm
1513 * STM(1/2): !Rn, register_list* (R15 in reg list not recommended)
1514 * STRT immediate pre/post-indexed: Rd*, !Rn
1515 * STRT register pre/post-indexed: Rd*, !Rn, !Rm
1516 * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm
1517 * STREX: !Rd, !Rn, !Rm
1518 * SWP/B: !Rd, !Rn, !Rm
1519 * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm
1520 * {S,U}XT{B,B16,H}: !Rd, !Rm
1521 * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs
1522 * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs
1523 *
1524 * May transfer control by writing R15 (possible mode changes or alternate
1525 * mode accesses marked by "*"):
1526 * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY,
1527 * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI*
1528 *
1529 * Instructions that do not take general registers, nor transfer control:
1530 * CDP/2, SETEND, SRS*
1531 */
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/kernel/kprobes.c
index 2ba7deb3072e..1656c87501c0 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/kernel/kprobes.c
@@ -134,7 +134,8 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs,
134 struct kprobe_ctlblk *kcb) 134 struct kprobe_ctlblk *kcb)
135{ 135{
136 regs->ARM_pc += 4; 136 regs->ARM_pc += 4;
137 p->ainsn.insn_handler(p, regs); 137 if (p->ainsn.insn_check_cc(regs->ARM_cpsr))
138 p->ainsn.insn_handler(p, regs);
138} 139}
139 140
140/* 141/*
diff --git a/arch/arm/kernel/leds.c b/arch/arm/kernel/leds.c
index 31a316c1777b..0f107dcb0347 100644
--- a/arch/arm/kernel/leds.c
+++ b/arch/arm/kernel/leds.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/sysdev.h> 12#include <linux/sysdev.h>
13#include <linux/syscore_ops.h>
13 14
14#include <asm/leds.h> 15#include <asm/leds.h>
15 16
@@ -69,36 +70,37 @@ static ssize_t leds_store(struct sys_device *dev,
69 70
70static SYSDEV_ATTR(event, 0200, NULL, leds_store); 71static SYSDEV_ATTR(event, 0200, NULL, leds_store);
71 72
72static int leds_suspend(struct sys_device *dev, pm_message_t state) 73static struct sysdev_class leds_sysclass = {
74 .name = "leds",
75};
76
77static struct sys_device leds_device = {
78 .id = 0,
79 .cls = &leds_sysclass,
80};
81
82static int leds_suspend(void)
73{ 83{
74 leds_event(led_stop); 84 leds_event(led_stop);
75 return 0; 85 return 0;
76} 86}
77 87
78static int leds_resume(struct sys_device *dev) 88static void leds_resume(void)
79{ 89{
80 leds_event(led_start); 90 leds_event(led_start);
81 return 0;
82} 91}
83 92
84static int leds_shutdown(struct sys_device *dev) 93static void leds_shutdown(void)
85{ 94{
86 leds_event(led_halted); 95 leds_event(led_halted);
87 return 0;
88} 96}
89 97
90static struct sysdev_class leds_sysclass = { 98static struct syscore_ops leds_syscore_ops = {
91 .name = "leds",
92 .shutdown = leds_shutdown, 99 .shutdown = leds_shutdown,
93 .suspend = leds_suspend, 100 .suspend = leds_suspend,
94 .resume = leds_resume, 101 .resume = leds_resume,
95}; 102};
96 103
97static struct sys_device leds_device = {
98 .id = 0,
99 .cls = &leds_sysclass,
100};
101
102static int __init leds_init(void) 104static int __init leds_init(void)
103{ 105{
104 int ret; 106 int ret;
@@ -107,6 +109,8 @@ static int __init leds_init(void)
107 ret = sysdev_register(&leds_device); 109 ret = sysdev_register(&leds_device);
108 if (ret == 0) 110 if (ret == 0)
109 ret = sysdev_create_file(&leds_device, &attr_event); 111 ret = sysdev_create_file(&leds_device, &attr_event);
112 if (ret == 0)
113 register_syscore_ops(&leds_syscore_ops);
110 return ret; 114 return ret;
111} 115}
112 116
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 1fc74cbd1a19..e59bbd496c39 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -23,6 +23,8 @@ extern unsigned long kexec_indirection_page;
23extern unsigned long kexec_mach_type; 23extern unsigned long kexec_mach_type;
24extern unsigned long kexec_boot_atags; 24extern unsigned long kexec_boot_atags;
25 25
26static atomic_t waiting_for_crash_ipi;
27
26/* 28/*
27 * Provide a dummy crash_notes definition while crash dump arrives to arm. 29 * Provide a dummy crash_notes definition while crash dump arrives to arm.
28 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. 30 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -37,14 +39,47 @@ void machine_kexec_cleanup(struct kimage *image)
37{ 39{
38} 40}
39 41
42void machine_crash_nonpanic_core(void *unused)
43{
44 struct pt_regs regs;
45
46 crash_setup_regs(&regs, NULL);
47 printk(KERN_DEBUG "CPU %u will stop doing anything useful since another CPU has crashed\n",
48 smp_processor_id());
49 crash_save_cpu(&regs, smp_processor_id());
50 flush_cache_all();
51
52 atomic_dec(&waiting_for_crash_ipi);
53 while (1)
54 cpu_relax();
55}
56
40void machine_crash_shutdown(struct pt_regs *regs) 57void machine_crash_shutdown(struct pt_regs *regs)
41{ 58{
59 unsigned long msecs;
60
42 local_irq_disable(); 61 local_irq_disable();
62
63 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
64 smp_call_function(machine_crash_nonpanic_core, NULL, false);
65 msecs = 1000; /* Wait at most a second for the other cpus to stop */
66 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
67 mdelay(1);
68 msecs--;
69 }
70 if (atomic_read(&waiting_for_crash_ipi) > 0)
71 printk(KERN_WARNING "Non-crashing CPUs did not react to IPI\n");
72
43 crash_save_cpu(regs, smp_processor_id()); 73 crash_save_cpu(regs, smp_processor_id());
44 74
45 printk(KERN_INFO "Loading crashdump kernel...\n"); 75 printk(KERN_INFO "Loading crashdump kernel...\n");
46} 76}
47 77
78/*
79 * Function pointer to optional machine-specific reinitialization
80 */
81void (*kexec_reinit)(void);
82
48void machine_kexec(struct kimage *image) 83void machine_kexec(struct kimage *image)
49{ 84{
50 unsigned long page_list; 85 unsigned long page_list;
@@ -74,11 +109,16 @@ void machine_kexec(struct kimage *image)
74 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE); 109 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
75 printk(KERN_INFO "Bye!\n"); 110 printk(KERN_INFO "Bye!\n");
76 111
112 if (kexec_reinit)
113 kexec_reinit();
77 local_irq_disable(); 114 local_irq_disable();
78 local_fiq_disable(); 115 local_fiq_disable();
79 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/ 116 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
80 flush_cache_all(); 117 flush_cache_all();
118 outer_flush_all();
119 outer_disable();
81 cpu_proc_fin(); 120 cpu_proc_fin();
121 outer_inv_all();
82 flush_cache_all(); 122 flush_cache_all();
83 cpu_reset(reboot_code_buffer_phys); 123 cpu_reset(reboot_code_buffer_phys);
84} 124}
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index 6b4605893f1e..016d6a0830a3 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -22,6 +22,7 @@
22 22
23#include <asm/pgtable.h> 23#include <asm/pgtable.h>
24#include <asm/sections.h> 24#include <asm/sections.h>
25#include <asm/smp_plat.h>
25#include <asm/unwind.h> 26#include <asm/unwind.h>
26 27
27#ifdef CONFIG_XIP_KERNEL 28#ifdef CONFIG_XIP_KERNEL
@@ -38,17 +39,9 @@
38#ifdef CONFIG_MMU 39#ifdef CONFIG_MMU
39void *module_alloc(unsigned long size) 40void *module_alloc(unsigned long size)
40{ 41{
41 struct vm_struct *area; 42 return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
42 43 GFP_KERNEL, PAGE_KERNEL_EXEC, -1,
43 size = PAGE_ALIGN(size); 44 __builtin_return_address(0));
44 if (!size)
45 return NULL;
46
47 area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END);
48 if (!area)
49 return NULL;
50
51 return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC);
52} 45}
53#else /* CONFIG_MMU */ 46#else /* CONFIG_MMU */
54void *module_alloc(unsigned long size) 47void *module_alloc(unsigned long size)
@@ -67,24 +60,6 @@ int module_frob_arch_sections(Elf_Ehdr *hdr,
67 char *secstrings, 60 char *secstrings,
68 struct module *mod) 61 struct module *mod)
69{ 62{
70#ifdef CONFIG_ARM_UNWIND
71 Elf_Shdr *s, *sechdrs_end = sechdrs + hdr->e_shnum;
72
73 for (s = sechdrs; s < sechdrs_end; s++) {
74 if (strcmp(".ARM.exidx.init.text", secstrings + s->sh_name) == 0)
75 mod->arch.unw_sec_init = s;
76 else if (strcmp(".ARM.exidx.devinit.text", secstrings + s->sh_name) == 0)
77 mod->arch.unw_sec_devinit = s;
78 else if (strcmp(".ARM.exidx", secstrings + s->sh_name) == 0)
79 mod->arch.unw_sec_core = s;
80 else if (strcmp(".init.text", secstrings + s->sh_name) == 0)
81 mod->arch.sec_init_text = s;
82 else if (strcmp(".devinit.text", secstrings + s->sh_name) == 0)
83 mod->arch.sec_devinit_text = s;
84 else if (strcmp(".text", secstrings + s->sh_name) == 0)
85 mod->arch.sec_core_text = s;
86 }
87#endif
88 return 0; 63 return 0;
89} 64}
90 65
@@ -101,6 +76,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
101 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) { 76 for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
102 unsigned long loc; 77 unsigned long loc;
103 Elf32_Sym *sym; 78 Elf32_Sym *sym;
79 const char *symname;
104 s32 offset; 80 s32 offset;
105#ifdef CONFIG_THUMB2_KERNEL 81#ifdef CONFIG_THUMB2_KERNEL
106 u32 upper, lower, sign, j1, j2; 82 u32 upper, lower, sign, j1, j2;
@@ -108,18 +84,18 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
108 84
109 offset = ELF32_R_SYM(rel->r_info); 85 offset = ELF32_R_SYM(rel->r_info);
110 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { 86 if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
111 printk(KERN_ERR "%s: bad relocation, section %d reloc %d\n", 87 pr_err("%s: section %u reloc %u: bad relocation sym offset\n",
112 module->name, relindex, i); 88 module->name, relindex, i);
113 return -ENOEXEC; 89 return -ENOEXEC;
114 } 90 }
115 91
116 sym = ((Elf32_Sym *)symsec->sh_addr) + offset; 92 sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
93 symname = strtab + sym->st_name;
117 94
118 if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) { 95 if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
119 printk(KERN_ERR "%s: out of bounds relocation, " 96 pr_err("%s: section %u reloc %u sym '%s': out of bounds relocation, offset %d size %u\n",
120 "section %d reloc %d offset %d size %d\n", 97 module->name, relindex, i, symname,
121 module->name, relindex, i, rel->r_offset, 98 rel->r_offset, dstsec->sh_size);
122 dstsec->sh_size);
123 return -ENOEXEC; 99 return -ENOEXEC;
124 } 100 }
125 101
@@ -145,10 +121,10 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
145 if (offset & 3 || 121 if (offset & 3 ||
146 offset <= (s32)0xfe000000 || 122 offset <= (s32)0xfe000000 ||
147 offset >= (s32)0x02000000) { 123 offset >= (s32)0x02000000) {
148 printk(KERN_ERR 124 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
149 "%s: relocation out of range, section " 125 module->name, relindex, i, symname,
150 "%d reloc %d sym '%s'\n", module->name, 126 ELF32_R_TYPE(rel->r_info), loc,
151 relindex, i, strtab + sym->st_name); 127 sym->st_value);
152 return -ENOEXEC; 128 return -ENOEXEC;
153 } 129 }
154 130
@@ -217,14 +193,23 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
217 offset -= 0x02000000; 193 offset -= 0x02000000;
218 offset += sym->st_value - loc; 194 offset += sym->st_value - loc;
219 195
220 /* only Thumb addresses allowed (no interworking) */ 196 /*
221 if (!(offset & 1) || 197 * For function symbols, only Thumb addresses are
198 * allowed (no interworking).
199 *
200 * For non-function symbols, the destination
201 * has no specific ARM/Thumb disposition, so
202 * the branch is resolved under the assumption
203 * that interworking is not required.
204 */
205 if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
206 !(offset & 1)) ||
222 offset <= (s32)0xff000000 || 207 offset <= (s32)0xff000000 ||
223 offset >= (s32)0x01000000) { 208 offset >= (s32)0x01000000) {
224 printk(KERN_ERR 209 pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
225 "%s: relocation out of range, section " 210 module->name, relindex, i, symname,
226 "%d reloc %d sym '%s'\n", module->name, 211 ELF32_R_TYPE(rel->r_info), loc,
227 relindex, i, strtab + sym->st_name); 212 sym->st_value);
228 return -ENOEXEC; 213 return -ENOEXEC;
229 } 214 }
230 215
@@ -289,50 +274,94 @@ apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
289 return -ENOEXEC; 274 return -ENOEXEC;
290} 275}
291 276
292#ifdef CONFIG_ARM_UNWIND 277struct mod_unwind_map {
293static void register_unwind_tables(struct module *mod) 278 const Elf_Shdr *unw_sec;
294{ 279 const Elf_Shdr *txt_sec;
295 if (mod->arch.unw_sec_init && mod->arch.sec_init_text) 280};
296 mod->arch.unwind_init =
297 unwind_table_add(mod->arch.unw_sec_init->sh_addr,
298 mod->arch.unw_sec_init->sh_size,
299 mod->arch.sec_init_text->sh_addr,
300 mod->arch.sec_init_text->sh_size);
301 if (mod->arch.unw_sec_devinit && mod->arch.sec_devinit_text)
302 mod->arch.unwind_devinit =
303 unwind_table_add(mod->arch.unw_sec_devinit->sh_addr,
304 mod->arch.unw_sec_devinit->sh_size,
305 mod->arch.sec_devinit_text->sh_addr,
306 mod->arch.sec_devinit_text->sh_size);
307 if (mod->arch.unw_sec_core && mod->arch.sec_core_text)
308 mod->arch.unwind_core =
309 unwind_table_add(mod->arch.unw_sec_core->sh_addr,
310 mod->arch.unw_sec_core->sh_size,
311 mod->arch.sec_core_text->sh_addr,
312 mod->arch.sec_core_text->sh_size);
313}
314 281
315static void unregister_unwind_tables(struct module *mod) 282static const Elf_Shdr *find_mod_section(const Elf32_Ehdr *hdr,
283 const Elf_Shdr *sechdrs, const char *name)
316{ 284{
317 unwind_table_del(mod->arch.unwind_init); 285 const Elf_Shdr *s, *se;
318 unwind_table_del(mod->arch.unwind_devinit); 286 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
319 unwind_table_del(mod->arch.unwind_core); 287
288 for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++)
289 if (strcmp(name, secstrs + s->sh_name) == 0)
290 return s;
291
292 return NULL;
320} 293}
321#else
322static inline void register_unwind_tables(struct module *mod) { }
323static inline void unregister_unwind_tables(struct module *mod) { }
324#endif
325 294
326int 295extern void fixup_pv_table(const void *, unsigned long);
327module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, 296extern void fixup_smp(const void *, unsigned long);
328 struct module *module) 297
298int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs,
299 struct module *mod)
329{ 300{
330 register_unwind_tables(module); 301 const Elf_Shdr *s = NULL;
302#ifdef CONFIG_ARM_UNWIND
303 const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
304 const Elf_Shdr *sechdrs_end = sechdrs + hdr->e_shnum;
305 struct mod_unwind_map maps[ARM_SEC_MAX];
306 int i;
307
308 memset(maps, 0, sizeof(maps));
309
310 for (s = sechdrs; s < sechdrs_end; s++) {
311 const char *secname = secstrs + s->sh_name;
312
313 if (!(s->sh_flags & SHF_ALLOC))
314 continue;
315
316 if (strcmp(".ARM.exidx.init.text", secname) == 0)
317 maps[ARM_SEC_INIT].unw_sec = s;
318 else if (strcmp(".ARM.exidx.devinit.text", secname) == 0)
319 maps[ARM_SEC_DEVINIT].unw_sec = s;
320 else if (strcmp(".ARM.exidx", secname) == 0)
321 maps[ARM_SEC_CORE].unw_sec = s;
322 else if (strcmp(".ARM.exidx.exit.text", secname) == 0)
323 maps[ARM_SEC_EXIT].unw_sec = s;
324 else if (strcmp(".ARM.exidx.devexit.text", secname) == 0)
325 maps[ARM_SEC_DEVEXIT].unw_sec = s;
326 else if (strcmp(".init.text", secname) == 0)
327 maps[ARM_SEC_INIT].txt_sec = s;
328 else if (strcmp(".devinit.text", secname) == 0)
329 maps[ARM_SEC_DEVINIT].txt_sec = s;
330 else if (strcmp(".text", secname) == 0)
331 maps[ARM_SEC_CORE].txt_sec = s;
332 else if (strcmp(".exit.text", secname) == 0)
333 maps[ARM_SEC_EXIT].txt_sec = s;
334 else if (strcmp(".devexit.text", secname) == 0)
335 maps[ARM_SEC_DEVEXIT].txt_sec = s;
336 }
337
338 for (i = 0; i < ARM_SEC_MAX; i++)
339 if (maps[i].unw_sec && maps[i].txt_sec)
340 mod->arch.unwind[i] =
341 unwind_table_add(maps[i].unw_sec->sh_addr,
342 maps[i].unw_sec->sh_size,
343 maps[i].txt_sec->sh_addr,
344 maps[i].txt_sec->sh_size);
345#endif
346#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
347 s = find_mod_section(hdr, sechdrs, ".pv_table");
348 if (s)
349 fixup_pv_table((void *)s->sh_addr, s->sh_size);
350#endif
351 s = find_mod_section(hdr, sechdrs, ".alt.smp.init");
352 if (s && !is_smp())
353 fixup_smp((void *)s->sh_addr, s->sh_size);
331 return 0; 354 return 0;
332} 355}
333 356
334void 357void
335module_arch_cleanup(struct module *mod) 358module_arch_cleanup(struct module *mod)
336{ 359{
337 unregister_unwind_tables(mod); 360#ifdef CONFIG_ARM_UNWIND
361 int i;
362
363 for (i = 0; i < ARM_SEC_MAX; i++)
364 if (mod->arch.unwind[i])
365 unwind_table_del(mod->arch.unwind[i]);
366#endif
338} 367}
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index ecbb0288e5dd..2b5b1421596c 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -4,9 +4,7 @@
4 * ARM performance counter support. 4 * ARM performance counter support.
5 * 5 *
6 * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles 6 * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
7 * 7 * Copyright (C) 2010 ARM Ltd., Will Deacon <will.deacon@arm.com>
8 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
9 * 2010 (c) MontaVista Software, LLC.
10 * 8 *
11 * This code is based on the sparc64 perf event code, which is in turn based 9 * This code is based on the sparc64 perf event code, which is in turn based
12 * on the x86 code. Callchain code is based on the ARM OProfile backtrace 10 * on the x86 code. Callchain code is based on the ARM OProfile backtrace
@@ -34,7 +32,7 @@ static struct platform_device *pmu_device;
34 * Hardware lock to serialize accesses to PMU registers. Needed for the 32 * Hardware lock to serialize accesses to PMU registers. Needed for the
35 * read/modify/write sequences. 33 * read/modify/write sequences.
36 */ 34 */
37DEFINE_SPINLOCK(pmu_lock); 35static DEFINE_RAW_SPINLOCK(pmu_lock);
38 36
39/* 37/*
40 * ARMv6 supports a maximum of 3 events, starting from index 1. If we add 38 * ARMv6 supports a maximum of 3 events, starting from index 1. If we add
@@ -67,31 +65,26 @@ struct cpu_hw_events {
67 */ 65 */
68 unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)]; 66 unsigned long active_mask[BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)];
69}; 67};
70DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events); 68static DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
71
72/* PMU names. */
73static const char *arm_pmu_names[] = {
74 [ARM_PERF_PMU_ID_XSCALE1] = "xscale1",
75 [ARM_PERF_PMU_ID_XSCALE2] = "xscale2",
76 [ARM_PERF_PMU_ID_V6] = "v6",
77 [ARM_PERF_PMU_ID_V6MP] = "v6mpcore",
78 [ARM_PERF_PMU_ID_CA8] = "ARMv7 Cortex-A8",
79 [ARM_PERF_PMU_ID_CA9] = "ARMv7 Cortex-A9",
80};
81 69
82struct arm_pmu { 70struct arm_pmu {
83 enum arm_perf_pmu_ids id; 71 enum arm_perf_pmu_ids id;
72 const char *name;
84 irqreturn_t (*handle_irq)(int irq_num, void *dev); 73 irqreturn_t (*handle_irq)(int irq_num, void *dev);
85 void (*enable)(struct hw_perf_event *evt, int idx); 74 void (*enable)(struct hw_perf_event *evt, int idx);
86 void (*disable)(struct hw_perf_event *evt, int idx); 75 void (*disable)(struct hw_perf_event *evt, int idx);
87 int (*event_map)(int evt);
88 u64 (*raw_event)(u64);
89 int (*get_event_idx)(struct cpu_hw_events *cpuc, 76 int (*get_event_idx)(struct cpu_hw_events *cpuc,
90 struct hw_perf_event *hwc); 77 struct hw_perf_event *hwc);
91 u32 (*read_counter)(int idx); 78 u32 (*read_counter)(int idx);
92 void (*write_counter)(int idx, u32 val); 79 void (*write_counter)(int idx, u32 val);
93 void (*start)(void); 80 void (*start)(void);
94 void (*stop)(void); 81 void (*stop)(void);
82 void (*reset)(void *);
83 const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
84 [PERF_COUNT_HW_CACHE_OP_MAX]
85 [PERF_COUNT_HW_CACHE_RESULT_MAX];
86 const unsigned (*event_map)[PERF_COUNT_HW_MAX];
87 u32 raw_event_mask;
95 int num_events; 88 int num_events;
96 u64 max_period; 89 u64 max_period;
97}; 90};
@@ -123,6 +116,12 @@ armpmu_get_max_events(void)
123} 116}
124EXPORT_SYMBOL_GPL(armpmu_get_max_events); 117EXPORT_SYMBOL_GPL(armpmu_get_max_events);
125 118
119int perf_num_counters(void)
120{
121 return armpmu_get_max_events();
122}
123EXPORT_SYMBOL_GPL(perf_num_counters);
124
126#define HW_OP_UNSUPPORTED 0xFFFF 125#define HW_OP_UNSUPPORTED 0xFFFF
127 126
128#define C(_x) \ 127#define C(_x) \
@@ -130,10 +129,6 @@ EXPORT_SYMBOL_GPL(armpmu_get_max_events);
130 129
131#define CACHE_OP_UNSUPPORTED 0xFFFF 130#define CACHE_OP_UNSUPPORTED 0xFFFF
132 131
133static unsigned armpmu_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
134 [PERF_COUNT_HW_CACHE_OP_MAX]
135 [PERF_COUNT_HW_CACHE_RESULT_MAX];
136
137static int 132static int
138armpmu_map_cache_event(u64 config) 133armpmu_map_cache_event(u64 config)
139{ 134{
@@ -151,7 +146,7 @@ armpmu_map_cache_event(u64 config)
151 if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX) 146 if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
152 return -EINVAL; 147 return -EINVAL;
153 148
154 ret = (int)armpmu_perf_cache_map[cache_type][cache_op][cache_result]; 149 ret = (int)(*armpmu->cache_map)[cache_type][cache_op][cache_result];
155 150
156 if (ret == CACHE_OP_UNSUPPORTED) 151 if (ret == CACHE_OP_UNSUPPORTED)
157 return -ENOENT; 152 return -ENOENT;
@@ -160,6 +155,19 @@ armpmu_map_cache_event(u64 config)
160} 155}
161 156
162static int 157static int
158armpmu_map_event(u64 config)
159{
160 int mapping = (*armpmu->event_map)[config];
161 return mapping == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : mapping;
162}
163
164static int
165armpmu_map_raw_event(u64 config)
166{
167 return (int)(config & armpmu->raw_event_mask);
168}
169
170static int
163armpmu_event_set_period(struct perf_event *event, 171armpmu_event_set_period(struct perf_event *event,
164 struct hw_perf_event *hwc, 172 struct hw_perf_event *hwc,
165 int idx) 173 int idx)
@@ -197,11 +205,9 @@ armpmu_event_set_period(struct perf_event *event,
197static u64 205static u64
198armpmu_event_update(struct perf_event *event, 206armpmu_event_update(struct perf_event *event,
199 struct hw_perf_event *hwc, 207 struct hw_perf_event *hwc,
200 int idx) 208 int idx, int overflow)
201{ 209{
202 int shift = 64 - 32; 210 u64 delta, prev_raw_count, new_raw_count;
203 s64 prev_raw_count, new_raw_count;
204 u64 delta;
205 211
206again: 212again:
207 prev_raw_count = local64_read(&hwc->prev_count); 213 prev_raw_count = local64_read(&hwc->prev_count);
@@ -211,8 +217,13 @@ again:
211 new_raw_count) != prev_raw_count) 217 new_raw_count) != prev_raw_count)
212 goto again; 218 goto again;
213 219
214 delta = (new_raw_count << shift) - (prev_raw_count << shift); 220 new_raw_count &= armpmu->max_period;
215 delta >>= shift; 221 prev_raw_count &= armpmu->max_period;
222
223 if (overflow)
224 delta = armpmu->max_period - prev_raw_count + new_raw_count + 1;
225 else
226 delta = new_raw_count - prev_raw_count;
216 227
217 local64_add(delta, &event->count); 228 local64_add(delta, &event->count);
218 local64_sub(delta, &hwc->period_left); 229 local64_sub(delta, &hwc->period_left);
@@ -221,46 +232,56 @@ again:
221} 232}
222 233
223static void 234static void
224armpmu_disable(struct perf_event *event) 235armpmu_read(struct perf_event *event)
225{ 236{
226 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
227 struct hw_perf_event *hwc = &event->hw; 237 struct hw_perf_event *hwc = &event->hw;
228 int idx = hwc->idx;
229
230 WARN_ON(idx < 0);
231
232 clear_bit(idx, cpuc->active_mask);
233 armpmu->disable(hwc, idx);
234 238
235 barrier(); 239 /* Don't read disabled counters! */
236 240 if (hwc->idx < 0)
237 armpmu_event_update(event, hwc, idx); 241 return;
238 cpuc->events[idx] = NULL;
239 clear_bit(idx, cpuc->used_mask);
240 242
241 perf_event_update_userpage(event); 243 armpmu_event_update(event, hwc, hwc->idx, 0);
242} 244}
243 245
244static void 246static void
245armpmu_read(struct perf_event *event) 247armpmu_stop(struct perf_event *event, int flags)
246{ 248{
247 struct hw_perf_event *hwc = &event->hw; 249 struct hw_perf_event *hwc = &event->hw;
248 250
249 /* Don't read disabled counters! */ 251 if (!armpmu)
250 if (hwc->idx < 0)
251 return; 252 return;
252 253
253 armpmu_event_update(event, hwc, hwc->idx); 254 /*
255 * ARM pmu always has to update the counter, so ignore
256 * PERF_EF_UPDATE, see comments in armpmu_start().
257 */
258 if (!(hwc->state & PERF_HES_STOPPED)) {
259 armpmu->disable(hwc, hwc->idx);
260 barrier(); /* why? */
261 armpmu_event_update(event, hwc, hwc->idx, 0);
262 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
263 }
254} 264}
255 265
256static void 266static void
257armpmu_unthrottle(struct perf_event *event) 267armpmu_start(struct perf_event *event, int flags)
258{ 268{
259 struct hw_perf_event *hwc = &event->hw; 269 struct hw_perf_event *hwc = &event->hw;
260 270
271 if (!armpmu)
272 return;
273
274 /*
275 * ARM pmu always has to reprogram the period, so ignore
276 * PERF_EF_RELOAD, see the comment below.
277 */
278 if (flags & PERF_EF_RELOAD)
279 WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
280
281 hwc->state = 0;
261 /* 282 /*
262 * Set the period again. Some counters can't be stopped, so when we 283 * Set the period again. Some counters can't be stopped, so when we
263 * were throttled we simply disabled the IRQ source and the counter 284 * were stopped we simply disabled the IRQ source and the counter
264 * may have been left counting. If we don't do this step then we may 285 * may have been left counting. If we don't do this step then we may
265 * get an interrupt too soon or *way* too late if the overflow has 286 * get an interrupt too soon or *way* too late if the overflow has
266 * happened since disabling. 287 * happened since disabling.
@@ -269,14 +290,33 @@ armpmu_unthrottle(struct perf_event *event)
269 armpmu->enable(hwc, hwc->idx); 290 armpmu->enable(hwc, hwc->idx);
270} 291}
271 292
293static void
294armpmu_del(struct perf_event *event, int flags)
295{
296 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
297 struct hw_perf_event *hwc = &event->hw;
298 int idx = hwc->idx;
299
300 WARN_ON(idx < 0);
301
302 clear_bit(idx, cpuc->active_mask);
303 armpmu_stop(event, PERF_EF_UPDATE);
304 cpuc->events[idx] = NULL;
305 clear_bit(idx, cpuc->used_mask);
306
307 perf_event_update_userpage(event);
308}
309
272static int 310static int
273armpmu_enable(struct perf_event *event) 311armpmu_add(struct perf_event *event, int flags)
274{ 312{
275 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 313 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
276 struct hw_perf_event *hwc = &event->hw; 314 struct hw_perf_event *hwc = &event->hw;
277 int idx; 315 int idx;
278 int err = 0; 316 int err = 0;
279 317
318 perf_pmu_disable(event->pmu);
319
280 /* If we don't have a space for the counter then finish early. */ 320 /* If we don't have a space for the counter then finish early. */
281 idx = armpmu->get_event_idx(cpuc, hwc); 321 idx = armpmu->get_event_idx(cpuc, hwc);
282 if (idx < 0) { 322 if (idx < 0) {
@@ -293,25 +333,19 @@ armpmu_enable(struct perf_event *event)
293 cpuc->events[idx] = event; 333 cpuc->events[idx] = event;
294 set_bit(idx, cpuc->active_mask); 334 set_bit(idx, cpuc->active_mask);
295 335
296 /* Set the period for the event. */ 336 hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
297 armpmu_event_set_period(event, hwc, idx); 337 if (flags & PERF_EF_START)
298 338 armpmu_start(event, PERF_EF_RELOAD);
299 /* Enable the event. */
300 armpmu->enable(hwc, idx);
301 339
302 /* Propagate our changes to the userspace mapping. */ 340 /* Propagate our changes to the userspace mapping. */
303 perf_event_update_userpage(event); 341 perf_event_update_userpage(event);
304 342
305out: 343out:
344 perf_pmu_enable(event->pmu);
306 return err; 345 return err;
307} 346}
308 347
309static struct pmu pmu = { 348static struct pmu pmu;
310 .enable = armpmu_enable,
311 .disable = armpmu_disable,
312 .unthrottle = armpmu_unthrottle,
313 .read = armpmu_read,
314};
315 349
316static int 350static int
317validate_event(struct cpu_hw_events *cpuc, 351validate_event(struct cpu_hw_events *cpuc,
@@ -347,9 +381,18 @@ validate_group(struct perf_event *event)
347 return 0; 381 return 0;
348} 382}
349 383
384static irqreturn_t armpmu_platform_irq(int irq, void *dev)
385{
386 struct arm_pmu_platdata *plat = dev_get_platdata(&pmu_device->dev);
387
388 return plat->handle_irq(irq, dev, armpmu->handle_irq);
389}
390
350static int 391static int
351armpmu_reserve_hardware(void) 392armpmu_reserve_hardware(void)
352{ 393{
394 struct arm_pmu_platdata *plat;
395 irq_handler_t handle_irq;
353 int i, err = -ENODEV, irq; 396 int i, err = -ENODEV, irq;
354 397
355 pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU); 398 pmu_device = reserve_pmu(ARM_PMU_DEVICE_CPU);
@@ -360,6 +403,12 @@ armpmu_reserve_hardware(void)
360 403
361 init_pmu(ARM_PMU_DEVICE_CPU); 404 init_pmu(ARM_PMU_DEVICE_CPU);
362 405
406 plat = dev_get_platdata(&pmu_device->dev);
407 if (plat && plat->handle_irq)
408 handle_irq = armpmu_platform_irq;
409 else
410 handle_irq = armpmu->handle_irq;
411
363 if (pmu_device->num_resources < 1) { 412 if (pmu_device->num_resources < 1) {
364 pr_err("no irqs for PMUs defined\n"); 413 pr_err("no irqs for PMUs defined\n");
365 return -ENODEV; 414 return -ENODEV;
@@ -370,7 +419,7 @@ armpmu_reserve_hardware(void)
370 if (irq < 0) 419 if (irq < 0)
371 continue; 420 continue;
372 421
373 err = request_irq(irq, armpmu->handle_irq, 422 err = request_irq(irq, handle_irq,
374 IRQF_DISABLED | IRQF_NOBALANCING, 423 IRQF_DISABLED | IRQF_NOBALANCING,
375 "armpmu", NULL); 424 "armpmu", NULL);
376 if (err) { 425 if (err) {
@@ -429,11 +478,11 @@ __hw_perf_event_init(struct perf_event *event)
429 478
430 /* Decode the generic type into an ARM event identifier. */ 479 /* Decode the generic type into an ARM event identifier. */
431 if (PERF_TYPE_HARDWARE == event->attr.type) { 480 if (PERF_TYPE_HARDWARE == event->attr.type) {
432 mapping = armpmu->event_map(event->attr.config); 481 mapping = armpmu_map_event(event->attr.config);
433 } else if (PERF_TYPE_HW_CACHE == event->attr.type) { 482 } else if (PERF_TYPE_HW_CACHE == event->attr.type) {
434 mapping = armpmu_map_cache_event(event->attr.config); 483 mapping = armpmu_map_cache_event(event->attr.config);
435 } else if (PERF_TYPE_RAW == event->attr.type) { 484 } else if (PERF_TYPE_RAW == event->attr.type) {
436 mapping = armpmu->raw_event(event->attr.config); 485 mapping = armpmu_map_raw_event(event->attr.config);
437 } else { 486 } else {
438 pr_debug("event type %x not supported\n", event->attr.type); 487 pr_debug("event type %x not supported\n", event->attr.type);
439 return -EOPNOTSUPP; 488 return -EOPNOTSUPP;
@@ -491,22 +540,26 @@ __hw_perf_event_init(struct perf_event *event)
491 return err; 540 return err;
492} 541}
493 542
494const struct pmu * 543static int armpmu_event_init(struct perf_event *event)
495hw_perf_event_init(struct perf_event *event)
496{ 544{
497 int err = 0; 545 int err = 0;
498 546
547 switch (event->attr.type) {
548 case PERF_TYPE_RAW:
549 case PERF_TYPE_HARDWARE:
550 case PERF_TYPE_HW_CACHE:
551 break;
552
553 default:
554 return -ENOENT;
555 }
556
499 if (!armpmu) 557 if (!armpmu)
500 return ERR_PTR(-ENODEV); 558 return -ENODEV;
501 559
502 event->destroy = hw_perf_event_destroy; 560 event->destroy = hw_perf_event_destroy;
503 561
504 if (!atomic_inc_not_zero(&active_events)) { 562 if (!atomic_inc_not_zero(&active_events)) {
505 if (atomic_read(&active_events) > perf_max_events) {
506 atomic_dec(&active_events);
507 return ERR_PTR(-ENOSPC);
508 }
509
510 mutex_lock(&pmu_reserve_mutex); 563 mutex_lock(&pmu_reserve_mutex);
511 if (atomic_read(&active_events) == 0) { 564 if (atomic_read(&active_events) == 0) {
512 err = armpmu_reserve_hardware(); 565 err = armpmu_reserve_hardware();
@@ -518,20 +571,19 @@ hw_perf_event_init(struct perf_event *event)
518 } 571 }
519 572
520 if (err) 573 if (err)
521 return ERR_PTR(err); 574 return err;
522 575
523 err = __hw_perf_event_init(event); 576 err = __hw_perf_event_init(event);
524 if (err) 577 if (err)
525 hw_perf_event_destroy(event); 578 hw_perf_event_destroy(event);
526 579
527 return err ? ERR_PTR(err) : &pmu; 580 return err;
528} 581}
529 582
530void 583static void armpmu_enable(struct pmu *pmu)
531hw_perf_enable(void)
532{ 584{
533 /* Enable all of the perf events on hardware. */ 585 /* Enable all of the perf events on hardware. */
534 int idx; 586 int idx, enabled = 0;
535 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 587 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
536 588
537 if (!armpmu) 589 if (!armpmu)
@@ -544,2378 +596,47 @@ hw_perf_enable(void)
544 continue; 596 continue;
545 597
546 armpmu->enable(&event->hw, idx); 598 armpmu->enable(&event->hw, idx);
599 enabled = 1;
547 } 600 }
548 601
549 armpmu->start(); 602 if (enabled)
603 armpmu->start();
550} 604}
551 605
552void 606static void armpmu_disable(struct pmu *pmu)
553hw_perf_disable(void)
554{ 607{
555 if (armpmu) 608 if (armpmu)
556 armpmu->stop(); 609 armpmu->stop();
557} 610}
558 611
559/* 612static struct pmu pmu = {
560 * ARMv6 Performance counter handling code. 613 .pmu_enable = armpmu_enable,
561 * 614 .pmu_disable = armpmu_disable,
562 * ARMv6 has 2 configurable performance counters and a single cycle counter. 615 .event_init = armpmu_event_init,
563 * They all share a single reset bit but can be written to zero so we can use 616 .add = armpmu_add,
564 * that for a reset. 617 .del = armpmu_del,
565 * 618 .start = armpmu_start,
566 * The counters can't be individually enabled or disabled so when we remove 619 .stop = armpmu_stop,
567 * one event and replace it with another we could get spurious counts from the 620 .read = armpmu_read,
568 * wrong event. However, we can take advantage of the fact that the
569 * performance counters can export events to the event bus, and the event bus
570 * itself can be monitored. This requires that we *don't* export the events to
571 * the event bus. The procedure for disabling a configurable counter is:
572 * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
573 * effectively stops the counter from counting.
574 * - disable the counter's interrupt generation (each counter has it's
575 * own interrupt enable bit).
576 * Once stopped, the counter value can be written as 0 to reset.
577 *
578 * To enable a counter:
579 * - enable the counter's interrupt generation.
580 * - set the new event type.
581 *
582 * Note: the dedicated cycle counter only counts cycles and can't be
583 * enabled/disabled independently of the others. When we want to disable the
584 * cycle counter, we have to just disable the interrupt reporting and start
585 * ignoring that counter. When re-enabling, we have to reset the value and
586 * enable the interrupt.
587 */
588
589enum armv6_perf_types {
590 ARMV6_PERFCTR_ICACHE_MISS = 0x0,
591 ARMV6_PERFCTR_IBUF_STALL = 0x1,
592 ARMV6_PERFCTR_DDEP_STALL = 0x2,
593 ARMV6_PERFCTR_ITLB_MISS = 0x3,
594 ARMV6_PERFCTR_DTLB_MISS = 0x4,
595 ARMV6_PERFCTR_BR_EXEC = 0x5,
596 ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
597 ARMV6_PERFCTR_INSTR_EXEC = 0x7,
598 ARMV6_PERFCTR_DCACHE_HIT = 0x9,
599 ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
600 ARMV6_PERFCTR_DCACHE_MISS = 0xB,
601 ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
602 ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
603 ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
604 ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
605 ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
606 ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
607 ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
608 ARMV6_PERFCTR_NOP = 0x20,
609};
610
611enum armv6_counters {
612 ARMV6_CYCLE_COUNTER = 1,
613 ARMV6_COUNTER0,
614 ARMV6_COUNTER1,
615};
616
617/*
618 * The hardware events that we support. We do support cache operations but
619 * we have harvard caches and no way to combine instruction and data
620 * accesses/misses in hardware.
621 */
622static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
623 [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
624 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
625 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
626 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
627 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
628 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
629 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
630};
631
632static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
633 [PERF_COUNT_HW_CACHE_OP_MAX]
634 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
635 [C(L1D)] = {
636 /*
637 * The performance counters don't differentiate between read
638 * and write accesses/misses so this isn't strictly correct,
639 * but it's the best we can do. Writes and reads get
640 * combined.
641 */
642 [C(OP_READ)] = {
643 [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
644 [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
645 },
646 [C(OP_WRITE)] = {
647 [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
648 [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
649 },
650 [C(OP_PREFETCH)] = {
651 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
652 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
653 },
654 },
655 [C(L1I)] = {
656 [C(OP_READ)] = {
657 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
658 [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
659 },
660 [C(OP_WRITE)] = {
661 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
662 [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
663 },
664 [C(OP_PREFETCH)] = {
665 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
666 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
667 },
668 },
669 [C(LL)] = {
670 [C(OP_READ)] = {
671 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
672 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
673 },
674 [C(OP_WRITE)] = {
675 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
676 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
677 },
678 [C(OP_PREFETCH)] = {
679 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
680 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
681 },
682 },
683 [C(DTLB)] = {
684 /*
685 * The ARM performance counters can count micro DTLB misses,
686 * micro ITLB misses and main TLB misses. There isn't an event
687 * for TLB misses, so use the micro misses here and if users
688 * want the main TLB misses they can use a raw counter.
689 */
690 [C(OP_READ)] = {
691 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
692 [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
693 },
694 [C(OP_WRITE)] = {
695 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
696 [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
697 },
698 [C(OP_PREFETCH)] = {
699 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
700 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
701 },
702 },
703 [C(ITLB)] = {
704 [C(OP_READ)] = {
705 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
706 [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
707 },
708 [C(OP_WRITE)] = {
709 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
710 [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
711 },
712 [C(OP_PREFETCH)] = {
713 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
714 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
715 },
716 },
717 [C(BPU)] = {
718 [C(OP_READ)] = {
719 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
720 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
721 },
722 [C(OP_WRITE)] = {
723 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
724 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
725 },
726 [C(OP_PREFETCH)] = {
727 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
728 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
729 },
730 },
731};
732
733enum armv6mpcore_perf_types {
734 ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
735 ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
736 ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
737 ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
738 ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
739 ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
740 ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
741 ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
742 ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
743 ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
744 ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
745 ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
746 ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
747 ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
748 ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
749 ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
750 ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
751 ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
752 ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
753 ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
754};
755
756/*
757 * The hardware events that we support. We do support cache operations but
758 * we have harvard caches and no way to combine instruction and data
759 * accesses/misses in hardware.
760 */
761static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
762 [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
763 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
764 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
765 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
766 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
767 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
768 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
769};
770
771static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
772 [PERF_COUNT_HW_CACHE_OP_MAX]
773 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
774 [C(L1D)] = {
775 [C(OP_READ)] = {
776 [C(RESULT_ACCESS)] =
777 ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
778 [C(RESULT_MISS)] =
779 ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
780 },
781 [C(OP_WRITE)] = {
782 [C(RESULT_ACCESS)] =
783 ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
784 [C(RESULT_MISS)] =
785 ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
786 },
787 [C(OP_PREFETCH)] = {
788 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
789 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
790 },
791 },
792 [C(L1I)] = {
793 [C(OP_READ)] = {
794 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
795 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
796 },
797 [C(OP_WRITE)] = {
798 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
799 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
800 },
801 [C(OP_PREFETCH)] = {
802 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
803 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
804 },
805 },
806 [C(LL)] = {
807 [C(OP_READ)] = {
808 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
809 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
810 },
811 [C(OP_WRITE)] = {
812 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
813 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
814 },
815 [C(OP_PREFETCH)] = {
816 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
817 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
818 },
819 },
820 [C(DTLB)] = {
821 /*
822 * The ARM performance counters can count micro DTLB misses,
823 * micro ITLB misses and main TLB misses. There isn't an event
824 * for TLB misses, so use the micro misses here and if users
825 * want the main TLB misses they can use a raw counter.
826 */
827 [C(OP_READ)] = {
828 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
829 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
830 },
831 [C(OP_WRITE)] = {
832 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
833 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
834 },
835 [C(OP_PREFETCH)] = {
836 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
837 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
838 },
839 },
840 [C(ITLB)] = {
841 [C(OP_READ)] = {
842 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
843 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
844 },
845 [C(OP_WRITE)] = {
846 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
847 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
848 },
849 [C(OP_PREFETCH)] = {
850 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
851 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
852 },
853 },
854 [C(BPU)] = {
855 [C(OP_READ)] = {
856 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
857 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
858 },
859 [C(OP_WRITE)] = {
860 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
861 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
862 },
863 [C(OP_PREFETCH)] = {
864 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
865 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
866 },
867 },
868};
869
870static inline unsigned long
871armv6_pmcr_read(void)
872{
873 u32 val;
874 asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
875 return val;
876}
877
878static inline void
879armv6_pmcr_write(unsigned long val)
880{
881 asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
882}
883
884#define ARMV6_PMCR_ENABLE (1 << 0)
885#define ARMV6_PMCR_CTR01_RESET (1 << 1)
886#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
887#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
888#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
889#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
890#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
891#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
892#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
893#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
894#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
895#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
896#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
897#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
898
899#define ARMV6_PMCR_OVERFLOWED_MASK \
900 (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
901 ARMV6_PMCR_CCOUNT_OVERFLOW)
902
903static inline int
904armv6_pmcr_has_overflowed(unsigned long pmcr)
905{
906 return (pmcr & ARMV6_PMCR_OVERFLOWED_MASK);
907}
908
909static inline int
910armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
911 enum armv6_counters counter)
912{
913 int ret = 0;
914
915 if (ARMV6_CYCLE_COUNTER == counter)
916 ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
917 else if (ARMV6_COUNTER0 == counter)
918 ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
919 else if (ARMV6_COUNTER1 == counter)
920 ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
921 else
922 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
923
924 return ret;
925}
926
927static inline u32
928armv6pmu_read_counter(int counter)
929{
930 unsigned long value = 0;
931
932 if (ARMV6_CYCLE_COUNTER == counter)
933 asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
934 else if (ARMV6_COUNTER0 == counter)
935 asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
936 else if (ARMV6_COUNTER1 == counter)
937 asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
938 else
939 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
940
941 return value;
942}
943
944static inline void
945armv6pmu_write_counter(int counter,
946 u32 value)
947{
948 if (ARMV6_CYCLE_COUNTER == counter)
949 asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
950 else if (ARMV6_COUNTER0 == counter)
951 asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
952 else if (ARMV6_COUNTER1 == counter)
953 asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
954 else
955 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
956}
957
958void
959armv6pmu_enable_event(struct hw_perf_event *hwc,
960 int idx)
961{
962 unsigned long val, mask, evt, flags;
963
964 if (ARMV6_CYCLE_COUNTER == idx) {
965 mask = 0;
966 evt = ARMV6_PMCR_CCOUNT_IEN;
967 } else if (ARMV6_COUNTER0 == idx) {
968 mask = ARMV6_PMCR_EVT_COUNT0_MASK;
969 evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
970 ARMV6_PMCR_COUNT0_IEN;
971 } else if (ARMV6_COUNTER1 == idx) {
972 mask = ARMV6_PMCR_EVT_COUNT1_MASK;
973 evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
974 ARMV6_PMCR_COUNT1_IEN;
975 } else {
976 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
977 return;
978 }
979
980 /*
981 * Mask out the current event and set the counter to count the event
982 * that we're interested in.
983 */
984 spin_lock_irqsave(&pmu_lock, flags);
985 val = armv6_pmcr_read();
986 val &= ~mask;
987 val |= evt;
988 armv6_pmcr_write(val);
989 spin_unlock_irqrestore(&pmu_lock, flags);
990}
991
992static irqreturn_t
993armv6pmu_handle_irq(int irq_num,
994 void *dev)
995{
996 unsigned long pmcr = armv6_pmcr_read();
997 struct perf_sample_data data;
998 struct cpu_hw_events *cpuc;
999 struct pt_regs *regs;
1000 int idx;
1001
1002 if (!armv6_pmcr_has_overflowed(pmcr))
1003 return IRQ_NONE;
1004
1005 regs = get_irq_regs();
1006
1007 /*
1008 * The interrupts are cleared by writing the overflow flags back to
1009 * the control register. All of the other bits don't have any effect
1010 * if they are rewritten, so write the whole value back.
1011 */
1012 armv6_pmcr_write(pmcr);
1013
1014 perf_sample_data_init(&data, 0);
1015
1016 cpuc = &__get_cpu_var(cpu_hw_events);
1017 for (idx = 0; idx <= armpmu->num_events; ++idx) {
1018 struct perf_event *event = cpuc->events[idx];
1019 struct hw_perf_event *hwc;
1020
1021 if (!test_bit(idx, cpuc->active_mask))
1022 continue;
1023
1024 /*
1025 * We have a single interrupt for all counters. Check that
1026 * each counter has overflowed before we process it.
1027 */
1028 if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
1029 continue;
1030
1031 hwc = &event->hw;
1032 armpmu_event_update(event, hwc, idx);
1033 data.period = event->hw.last_period;
1034 if (!armpmu_event_set_period(event, hwc, idx))
1035 continue;
1036
1037 if (perf_event_overflow(event, 0, &data, regs))
1038 armpmu->disable(hwc, idx);
1039 }
1040
1041 /*
1042 * Handle the pending perf events.
1043 *
1044 * Note: this call *must* be run with interrupts disabled. For
1045 * platforms that can have the PMU interrupts raised as an NMI, this
1046 * will not work.
1047 */
1048 perf_event_do_pending();
1049
1050 return IRQ_HANDLED;
1051}
1052
1053static void
1054armv6pmu_start(void)
1055{
1056 unsigned long flags, val;
1057
1058 spin_lock_irqsave(&pmu_lock, flags);
1059 val = armv6_pmcr_read();
1060 val |= ARMV6_PMCR_ENABLE;
1061 armv6_pmcr_write(val);
1062 spin_unlock_irqrestore(&pmu_lock, flags);
1063}
1064
1065void
1066armv6pmu_stop(void)
1067{
1068 unsigned long flags, val;
1069
1070 spin_lock_irqsave(&pmu_lock, flags);
1071 val = armv6_pmcr_read();
1072 val &= ~ARMV6_PMCR_ENABLE;
1073 armv6_pmcr_write(val);
1074 spin_unlock_irqrestore(&pmu_lock, flags);
1075}
1076
1077static inline int
1078armv6pmu_event_map(int config)
1079{
1080 int mapping = armv6_perf_map[config];
1081 if (HW_OP_UNSUPPORTED == mapping)
1082 mapping = -EOPNOTSUPP;
1083 return mapping;
1084}
1085
1086static inline int
1087armv6mpcore_pmu_event_map(int config)
1088{
1089 int mapping = armv6mpcore_perf_map[config];
1090 if (HW_OP_UNSUPPORTED == mapping)
1091 mapping = -EOPNOTSUPP;
1092 return mapping;
1093}
1094
1095static u64
1096armv6pmu_raw_event(u64 config)
1097{
1098 return config & 0xff;
1099}
1100
1101static int
1102armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
1103 struct hw_perf_event *event)
1104{
1105 /* Always place a cycle counter into the cycle counter. */
1106 if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
1107 if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
1108 return -EAGAIN;
1109
1110 return ARMV6_CYCLE_COUNTER;
1111 } else {
1112 /*
1113 * For anything other than a cycle counter, try and use
1114 * counter0 and counter1.
1115 */
1116 if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask)) {
1117 return ARMV6_COUNTER1;
1118 }
1119
1120 if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask)) {
1121 return ARMV6_COUNTER0;
1122 }
1123
1124 /* The counters are all in use. */
1125 return -EAGAIN;
1126 }
1127}
1128
1129static void
1130armv6pmu_disable_event(struct hw_perf_event *hwc,
1131 int idx)
1132{
1133 unsigned long val, mask, evt, flags;
1134
1135 if (ARMV6_CYCLE_COUNTER == idx) {
1136 mask = ARMV6_PMCR_CCOUNT_IEN;
1137 evt = 0;
1138 } else if (ARMV6_COUNTER0 == idx) {
1139 mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
1140 evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
1141 } else if (ARMV6_COUNTER1 == idx) {
1142 mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
1143 evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
1144 } else {
1145 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
1146 return;
1147 }
1148
1149 /*
1150 * Mask out the current event and set the counter to count the number
1151 * of ETM bus signal assertion cycles. The external reporting should
1152 * be disabled and so this should never increment.
1153 */
1154 spin_lock_irqsave(&pmu_lock, flags);
1155 val = armv6_pmcr_read();
1156 val &= ~mask;
1157 val |= evt;
1158 armv6_pmcr_write(val);
1159 spin_unlock_irqrestore(&pmu_lock, flags);
1160}
1161
1162static void
1163armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
1164 int idx)
1165{
1166 unsigned long val, mask, flags, evt = 0;
1167
1168 if (ARMV6_CYCLE_COUNTER == idx) {
1169 mask = ARMV6_PMCR_CCOUNT_IEN;
1170 } else if (ARMV6_COUNTER0 == idx) {
1171 mask = ARMV6_PMCR_COUNT0_IEN;
1172 } else if (ARMV6_COUNTER1 == idx) {
1173 mask = ARMV6_PMCR_COUNT1_IEN;
1174 } else {
1175 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
1176 return;
1177 }
1178
1179 /*
1180 * Unlike UP ARMv6, we don't have a way of stopping the counters. We
1181 * simply disable the interrupt reporting.
1182 */
1183 spin_lock_irqsave(&pmu_lock, flags);
1184 val = armv6_pmcr_read();
1185 val &= ~mask;
1186 val |= evt;
1187 armv6_pmcr_write(val);
1188 spin_unlock_irqrestore(&pmu_lock, flags);
1189}
1190
1191static const struct arm_pmu armv6pmu = {
1192 .id = ARM_PERF_PMU_ID_V6,
1193 .handle_irq = armv6pmu_handle_irq,
1194 .enable = armv6pmu_enable_event,
1195 .disable = armv6pmu_disable_event,
1196 .event_map = armv6pmu_event_map,
1197 .raw_event = armv6pmu_raw_event,
1198 .read_counter = armv6pmu_read_counter,
1199 .write_counter = armv6pmu_write_counter,
1200 .get_event_idx = armv6pmu_get_event_idx,
1201 .start = armv6pmu_start,
1202 .stop = armv6pmu_stop,
1203 .num_events = 3,
1204 .max_period = (1LLU << 32) - 1,
1205};
1206
1207/*
1208 * ARMv6mpcore is almost identical to single core ARMv6 with the exception
1209 * that some of the events have different enumerations and that there is no
1210 * *hack* to stop the programmable counters. To stop the counters we simply
1211 * disable the interrupt reporting and update the event. When unthrottling we
1212 * reset the period and enable the interrupt reporting.
1213 */
1214static const struct arm_pmu armv6mpcore_pmu = {
1215 .id = ARM_PERF_PMU_ID_V6MP,
1216 .handle_irq = armv6pmu_handle_irq,
1217 .enable = armv6pmu_enable_event,
1218 .disable = armv6mpcore_pmu_disable_event,
1219 .event_map = armv6mpcore_pmu_event_map,
1220 .raw_event = armv6pmu_raw_event,
1221 .read_counter = armv6pmu_read_counter,
1222 .write_counter = armv6pmu_write_counter,
1223 .get_event_idx = armv6pmu_get_event_idx,
1224 .start = armv6pmu_start,
1225 .stop = armv6pmu_stop,
1226 .num_events = 3,
1227 .max_period = (1LLU << 32) - 1,
1228};
1229
1230/*
1231 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
1232 *
1233 * Copied from ARMv6 code, with the low level code inspired
1234 * by the ARMv7 Oprofile code.
1235 *
1236 * Cortex-A8 has up to 4 configurable performance counters and
1237 * a single cycle counter.
1238 * Cortex-A9 has up to 31 configurable performance counters and
1239 * a single cycle counter.
1240 *
1241 * All counters can be enabled/disabled and IRQ masked separately. The cycle
1242 * counter and all 4 performance counters together can be reset separately.
1243 */
1244
1245/* Common ARMv7 event types */
1246enum armv7_perf_types {
1247 ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
1248 ARMV7_PERFCTR_IFETCH_MISS = 0x01,
1249 ARMV7_PERFCTR_ITLB_MISS = 0x02,
1250 ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
1251 ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
1252 ARMV7_PERFCTR_DTLB_REFILL = 0x05,
1253 ARMV7_PERFCTR_DREAD = 0x06,
1254 ARMV7_PERFCTR_DWRITE = 0x07,
1255
1256 ARMV7_PERFCTR_EXC_TAKEN = 0x09,
1257 ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
1258 ARMV7_PERFCTR_CID_WRITE = 0x0B,
1259 /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
1260 * It counts:
1261 * - all branch instructions,
1262 * - instructions that explicitly write the PC,
1263 * - exception generating instructions.
1264 */
1265 ARMV7_PERFCTR_PC_WRITE = 0x0C,
1266 ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
1267 ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
1268 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
1269 ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
1270
1271 ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
1272
1273 ARMV7_PERFCTR_CPU_CYCLES = 0xFF
1274};
1275
1276/* ARMv7 Cortex-A8 specific event types */
1277enum armv7_a8_perf_types {
1278 ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
1279
1280 ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
1281
1282 ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
1283 ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
1284 ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
1285 ARMV7_PERFCTR_L2_ACCESS = 0x43,
1286 ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
1287 ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
1288 ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
1289 ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
1290 ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
1291 ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
1292 ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
1293 ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
1294 ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
1295 ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
1296 ARMV7_PERFCTR_L2_NEON = 0x4E,
1297 ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
1298 ARMV7_PERFCTR_L1_INST = 0x50,
1299 ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
1300 ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
1301 ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
1302 ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
1303 ARMV7_PERFCTR_OP_EXECUTED = 0x55,
1304 ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
1305 ARMV7_PERFCTR_CYCLES_INST = 0x57,
1306 ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
1307 ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
1308 ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
1309
1310 ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
1311 ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
1312 ARMV7_PERFCTR_PMU_EVENTS = 0x72,
1313};
1314
1315/* ARMv7 Cortex-A9 specific event types */
1316enum armv7_a9_perf_types {
1317 ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
1318 ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
1319 ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
1320
1321 ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
1322 ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
1323
1324 ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
1325 ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
1326 ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
1327 ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
1328 ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
1329 ARMV7_PERFCTR_DATA_EVICTION = 0x65,
1330 ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
1331 ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
1332 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
1333
1334 ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
1335
1336 ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
1337 ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
1338 ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
1339 ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
1340 ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
1341
1342 ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
1343 ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
1344 ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
1345 ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
1346 ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
1347 ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
1348 ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
1349
1350 ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
1351 ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
1352
1353 ARMV7_PERFCTR_ISB_INST = 0x90,
1354 ARMV7_PERFCTR_DSB_INST = 0x91,
1355 ARMV7_PERFCTR_DMB_INST = 0x92,
1356 ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
1357
1358 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
1359 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
1360 ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
1361 ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
1362 ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
1363 ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
1364};
1365
1366/*
1367 * Cortex-A8 HW events mapping
1368 *
1369 * The hardware events that we support. We do support cache operations but
1370 * we have harvard caches and no way to combine instruction and data
1371 * accesses/misses in hardware.
1372 */
1373static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
1374 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
1375 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
1376 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
1377 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
1378 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
1379 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1380 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
1381};
1382
1383static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
1384 [PERF_COUNT_HW_CACHE_OP_MAX]
1385 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
1386 [C(L1D)] = {
1387 /*
1388 * The performance counters don't differentiate between read
1389 * and write accesses/misses so this isn't strictly correct,
1390 * but it's the best we can do. Writes and reads get
1391 * combined.
1392 */
1393 [C(OP_READ)] = {
1394 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
1395 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
1396 },
1397 [C(OP_WRITE)] = {
1398 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
1399 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
1400 },
1401 [C(OP_PREFETCH)] = {
1402 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1403 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1404 },
1405 },
1406 [C(L1I)] = {
1407 [C(OP_READ)] = {
1408 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
1409 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
1410 },
1411 [C(OP_WRITE)] = {
1412 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
1413 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
1414 },
1415 [C(OP_PREFETCH)] = {
1416 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1417 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1418 },
1419 },
1420 [C(LL)] = {
1421 [C(OP_READ)] = {
1422 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
1423 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
1424 },
1425 [C(OP_WRITE)] = {
1426 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
1427 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
1428 },
1429 [C(OP_PREFETCH)] = {
1430 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1431 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1432 },
1433 },
1434 [C(DTLB)] = {
1435 /*
1436 * Only ITLB misses and DTLB refills are supported.
1437 * If users want the DTLB refills misses a raw counter
1438 * must be used.
1439 */
1440 [C(OP_READ)] = {
1441 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1442 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
1443 },
1444 [C(OP_WRITE)] = {
1445 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1446 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
1447 },
1448 [C(OP_PREFETCH)] = {
1449 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1450 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1451 },
1452 },
1453 [C(ITLB)] = {
1454 [C(OP_READ)] = {
1455 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1456 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
1457 },
1458 [C(OP_WRITE)] = {
1459 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1460 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
1461 },
1462 [C(OP_PREFETCH)] = {
1463 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1464 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1465 },
1466 },
1467 [C(BPU)] = {
1468 [C(OP_READ)] = {
1469 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
1470 [C(RESULT_MISS)]
1471 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1472 },
1473 [C(OP_WRITE)] = {
1474 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
1475 [C(RESULT_MISS)]
1476 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1477 },
1478 [C(OP_PREFETCH)] = {
1479 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1480 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1481 },
1482 },
1483};
1484
1485/*
1486 * Cortex-A9 HW events mapping
1487 */
1488static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
1489 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
1490 [PERF_COUNT_HW_INSTRUCTIONS] =
1491 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
1492 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
1493 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
1494 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
1495 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1496 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
1497};
1498
1499static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
1500 [PERF_COUNT_HW_CACHE_OP_MAX]
1501 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
1502 [C(L1D)] = {
1503 /*
1504 * The performance counters don't differentiate between read
1505 * and write accesses/misses so this isn't strictly correct,
1506 * but it's the best we can do. Writes and reads get
1507 * combined.
1508 */
1509 [C(OP_READ)] = {
1510 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
1511 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
1512 },
1513 [C(OP_WRITE)] = {
1514 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
1515 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
1516 },
1517 [C(OP_PREFETCH)] = {
1518 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1519 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1520 },
1521 },
1522 [C(L1I)] = {
1523 [C(OP_READ)] = {
1524 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1525 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
1526 },
1527 [C(OP_WRITE)] = {
1528 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1529 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
1530 },
1531 [C(OP_PREFETCH)] = {
1532 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1533 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1534 },
1535 },
1536 [C(LL)] = {
1537 [C(OP_READ)] = {
1538 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1539 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1540 },
1541 [C(OP_WRITE)] = {
1542 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1543 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1544 },
1545 [C(OP_PREFETCH)] = {
1546 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1547 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1548 },
1549 },
1550 [C(DTLB)] = {
1551 /*
1552 * Only ITLB misses and DTLB refills are supported.
1553 * If users want the DTLB refills misses a raw counter
1554 * must be used.
1555 */
1556 [C(OP_READ)] = {
1557 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1558 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
1559 },
1560 [C(OP_WRITE)] = {
1561 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1562 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
1563 },
1564 [C(OP_PREFETCH)] = {
1565 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1566 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1567 },
1568 },
1569 [C(ITLB)] = {
1570 [C(OP_READ)] = {
1571 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1572 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
1573 },
1574 [C(OP_WRITE)] = {
1575 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1576 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
1577 },
1578 [C(OP_PREFETCH)] = {
1579 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1580 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1581 },
1582 },
1583 [C(BPU)] = {
1584 [C(OP_READ)] = {
1585 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
1586 [C(RESULT_MISS)]
1587 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1588 },
1589 [C(OP_WRITE)] = {
1590 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
1591 [C(RESULT_MISS)]
1592 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
1593 },
1594 [C(OP_PREFETCH)] = {
1595 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
1596 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
1597 },
1598 },
1599};
1600
1601/*
1602 * Perf Events counters
1603 */
1604enum armv7_counters {
1605 ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
1606 ARMV7_COUNTER0 = 2, /* First event counter */
1607};
1608
1609/*
1610 * The cycle counter is ARMV7_CYCLE_COUNTER.
1611 * The first event counter is ARMV7_COUNTER0.
1612 * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
1613 */
1614#define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
1615
1616/*
1617 * ARMv7 low level PMNC access
1618 */
1619
1620/*
1621 * Per-CPU PMNC: config reg
1622 */
1623#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
1624#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
1625#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
1626#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
1627#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
1628#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
1629#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
1630#define ARMV7_PMNC_N_MASK 0x1f
1631#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
1632
1633/*
1634 * Available counters
1635 */
1636#define ARMV7_CNT0 0 /* First event counter */
1637#define ARMV7_CCNT 31 /* Cycle counter */
1638
1639/* Perf Event to low level counters mapping */
1640#define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
1641
1642/*
1643 * CNTENS: counters enable reg
1644 */
1645#define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
1646#define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
1647
1648/*
1649 * CNTENC: counters disable reg
1650 */
1651#define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
1652#define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
1653
1654/*
1655 * INTENS: counters overflow interrupt enable reg
1656 */
1657#define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
1658#define ARMV7_INTENS_C (1 << ARMV7_CCNT)
1659
1660/*
1661 * INTENC: counters overflow interrupt disable reg
1662 */
1663#define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
1664#define ARMV7_INTENC_C (1 << ARMV7_CCNT)
1665
1666/*
1667 * EVTSEL: Event selection reg
1668 */
1669#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
1670
1671/*
1672 * SELECT: Counter selection reg
1673 */
1674#define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
1675
1676/*
1677 * FLAG: counters overflow flag status reg
1678 */
1679#define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
1680#define ARMV7_FLAG_C (1 << ARMV7_CCNT)
1681#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
1682#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
1683
1684static inline unsigned long armv7_pmnc_read(void)
1685{
1686 u32 val;
1687 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
1688 return val;
1689}
1690
1691static inline void armv7_pmnc_write(unsigned long val)
1692{
1693 val &= ARMV7_PMNC_MASK;
1694 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
1695}
1696
1697static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
1698{
1699 return pmnc & ARMV7_OVERFLOWED_MASK;
1700}
1701
1702static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
1703 enum armv7_counters counter)
1704{
1705 int ret;
1706
1707 if (counter == ARMV7_CYCLE_COUNTER)
1708 ret = pmnc & ARMV7_FLAG_C;
1709 else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
1710 ret = pmnc & ARMV7_FLAG_P(counter);
1711 else
1712 pr_err("CPU%u checking wrong counter %d overflow status\n",
1713 smp_processor_id(), counter);
1714
1715 return ret;
1716}
1717
1718static inline int armv7_pmnc_select_counter(unsigned int idx)
1719{
1720 u32 val;
1721
1722 if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
1723 pr_err("CPU%u selecting wrong PMNC counter"
1724 " %d\n", smp_processor_id(), idx);
1725 return -1;
1726 }
1727
1728 val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
1729 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
1730
1731 return idx;
1732}
1733
1734static inline u32 armv7pmu_read_counter(int idx)
1735{
1736 unsigned long value = 0;
1737
1738 if (idx == ARMV7_CYCLE_COUNTER)
1739 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
1740 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
1741 if (armv7_pmnc_select_counter(idx) == idx)
1742 asm volatile("mrc p15, 0, %0, c9, c13, 2"
1743 : "=r" (value));
1744 } else
1745 pr_err("CPU%u reading wrong counter %d\n",
1746 smp_processor_id(), idx);
1747
1748 return value;
1749}
1750
1751static inline void armv7pmu_write_counter(int idx, u32 value)
1752{
1753 if (idx == ARMV7_CYCLE_COUNTER)
1754 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
1755 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
1756 if (armv7_pmnc_select_counter(idx) == idx)
1757 asm volatile("mcr p15, 0, %0, c9, c13, 2"
1758 : : "r" (value));
1759 } else
1760 pr_err("CPU%u writing wrong counter %d\n",
1761 smp_processor_id(), idx);
1762}
1763
1764static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
1765{
1766 if (armv7_pmnc_select_counter(idx) == idx) {
1767 val &= ARMV7_EVTSEL_MASK;
1768 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
1769 }
1770}
1771
1772static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
1773{
1774 u32 val;
1775
1776 if ((idx != ARMV7_CYCLE_COUNTER) &&
1777 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
1778 pr_err("CPU%u enabling wrong PMNC counter"
1779 " %d\n", smp_processor_id(), idx);
1780 return -1;
1781 }
1782
1783 if (idx == ARMV7_CYCLE_COUNTER)
1784 val = ARMV7_CNTENS_C;
1785 else
1786 val = ARMV7_CNTENS_P(idx);
1787
1788 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
1789
1790 return idx;
1791}
1792
1793static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
1794{
1795 u32 val;
1796
1797
1798 if ((idx != ARMV7_CYCLE_COUNTER) &&
1799 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
1800 pr_err("CPU%u disabling wrong PMNC counter"
1801 " %d\n", smp_processor_id(), idx);
1802 return -1;
1803 }
1804
1805 if (idx == ARMV7_CYCLE_COUNTER)
1806 val = ARMV7_CNTENC_C;
1807 else
1808 val = ARMV7_CNTENC_P(idx);
1809
1810 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
1811
1812 return idx;
1813}
1814
1815static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
1816{
1817 u32 val;
1818
1819 if ((idx != ARMV7_CYCLE_COUNTER) &&
1820 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
1821 pr_err("CPU%u enabling wrong PMNC counter"
1822 " interrupt enable %d\n", smp_processor_id(), idx);
1823 return -1;
1824 }
1825
1826 if (idx == ARMV7_CYCLE_COUNTER)
1827 val = ARMV7_INTENS_C;
1828 else
1829 val = ARMV7_INTENS_P(idx);
1830
1831 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
1832
1833 return idx;
1834}
1835
1836static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
1837{
1838 u32 val;
1839
1840 if ((idx != ARMV7_CYCLE_COUNTER) &&
1841 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
1842 pr_err("CPU%u disabling wrong PMNC counter"
1843 " interrupt enable %d\n", smp_processor_id(), idx);
1844 return -1;
1845 }
1846
1847 if (idx == ARMV7_CYCLE_COUNTER)
1848 val = ARMV7_INTENC_C;
1849 else
1850 val = ARMV7_INTENC_P(idx);
1851
1852 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
1853
1854 return idx;
1855}
1856
1857static inline u32 armv7_pmnc_getreset_flags(void)
1858{
1859 u32 val;
1860
1861 /* Read */
1862 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
1863
1864 /* Write to clear flags */
1865 val &= ARMV7_FLAG_MASK;
1866 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
1867
1868 return val;
1869}
1870
1871#ifdef DEBUG
1872static void armv7_pmnc_dump_regs(void)
1873{
1874 u32 val;
1875 unsigned int cnt;
1876
1877 printk(KERN_INFO "PMNC registers dump:\n");
1878
1879 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
1880 printk(KERN_INFO "PMNC =0x%08x\n", val);
1881
1882 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
1883 printk(KERN_INFO "CNTENS=0x%08x\n", val);
1884
1885 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
1886 printk(KERN_INFO "INTENS=0x%08x\n", val);
1887
1888 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
1889 printk(KERN_INFO "FLAGS =0x%08x\n", val);
1890
1891 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
1892 printk(KERN_INFO "SELECT=0x%08x\n", val);
1893
1894 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
1895 printk(KERN_INFO "CCNT =0x%08x\n", val);
1896
1897 for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
1898 armv7_pmnc_select_counter(cnt);
1899 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
1900 printk(KERN_INFO "CNT[%d] count =0x%08x\n",
1901 cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
1902 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
1903 printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
1904 cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
1905 }
1906}
1907#endif
1908
1909void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
1910{
1911 unsigned long flags;
1912
1913 /*
1914 * Enable counter and interrupt, and set the counter to count
1915 * the event that we're interested in.
1916 */
1917 spin_lock_irqsave(&pmu_lock, flags);
1918
1919 /*
1920 * Disable counter
1921 */
1922 armv7_pmnc_disable_counter(idx);
1923
1924 /*
1925 * Set event (if destined for PMNx counters)
1926 * We don't need to set the event if it's a cycle count
1927 */
1928 if (idx != ARMV7_CYCLE_COUNTER)
1929 armv7_pmnc_write_evtsel(idx, hwc->config_base);
1930
1931 /*
1932 * Enable interrupt for this counter
1933 */
1934 armv7_pmnc_enable_intens(idx);
1935
1936 /*
1937 * Enable counter
1938 */
1939 armv7_pmnc_enable_counter(idx);
1940
1941 spin_unlock_irqrestore(&pmu_lock, flags);
1942}
1943
1944static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
1945{
1946 unsigned long flags;
1947
1948 /*
1949 * Disable counter and interrupt
1950 */
1951 spin_lock_irqsave(&pmu_lock, flags);
1952
1953 /*
1954 * Disable counter
1955 */
1956 armv7_pmnc_disable_counter(idx);
1957
1958 /*
1959 * Disable interrupt for this counter
1960 */
1961 armv7_pmnc_disable_intens(idx);
1962
1963 spin_unlock_irqrestore(&pmu_lock, flags);
1964}
1965
1966static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
1967{
1968 unsigned long pmnc;
1969 struct perf_sample_data data;
1970 struct cpu_hw_events *cpuc;
1971 struct pt_regs *regs;
1972 int idx;
1973
1974 /*
1975 * Get and reset the IRQ flags
1976 */
1977 pmnc = armv7_pmnc_getreset_flags();
1978
1979 /*
1980 * Did an overflow occur?
1981 */
1982 if (!armv7_pmnc_has_overflowed(pmnc))
1983 return IRQ_NONE;
1984
1985 /*
1986 * Handle the counter(s) overflow(s)
1987 */
1988 regs = get_irq_regs();
1989
1990 perf_sample_data_init(&data, 0);
1991
1992 cpuc = &__get_cpu_var(cpu_hw_events);
1993 for (idx = 0; idx <= armpmu->num_events; ++idx) {
1994 struct perf_event *event = cpuc->events[idx];
1995 struct hw_perf_event *hwc;
1996
1997 if (!test_bit(idx, cpuc->active_mask))
1998 continue;
1999
2000 /*
2001 * We have a single interrupt for all counters. Check that
2002 * each counter has overflowed before we process it.
2003 */
2004 if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
2005 continue;
2006
2007 hwc = &event->hw;
2008 armpmu_event_update(event, hwc, idx);
2009 data.period = event->hw.last_period;
2010 if (!armpmu_event_set_period(event, hwc, idx))
2011 continue;
2012
2013 if (perf_event_overflow(event, 0, &data, regs))
2014 armpmu->disable(hwc, idx);
2015 }
2016
2017 /*
2018 * Handle the pending perf events.
2019 *
2020 * Note: this call *must* be run with interrupts disabled. For
2021 * platforms that can have the PMU interrupts raised as an NMI, this
2022 * will not work.
2023 */
2024 perf_event_do_pending();
2025
2026 return IRQ_HANDLED;
2027}
2028
2029static void armv7pmu_start(void)
2030{
2031 unsigned long flags;
2032
2033 spin_lock_irqsave(&pmu_lock, flags);
2034 /* Enable all counters */
2035 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
2036 spin_unlock_irqrestore(&pmu_lock, flags);
2037}
2038
2039static void armv7pmu_stop(void)
2040{
2041 unsigned long flags;
2042
2043 spin_lock_irqsave(&pmu_lock, flags);
2044 /* Disable all counters */
2045 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
2046 spin_unlock_irqrestore(&pmu_lock, flags);
2047}
2048
2049static inline int armv7_a8_pmu_event_map(int config)
2050{
2051 int mapping = armv7_a8_perf_map[config];
2052 if (HW_OP_UNSUPPORTED == mapping)
2053 mapping = -EOPNOTSUPP;
2054 return mapping;
2055}
2056
2057static inline int armv7_a9_pmu_event_map(int config)
2058{
2059 int mapping = armv7_a9_perf_map[config];
2060 if (HW_OP_UNSUPPORTED == mapping)
2061 mapping = -EOPNOTSUPP;
2062 return mapping;
2063}
2064
2065static u64 armv7pmu_raw_event(u64 config)
2066{
2067 return config & 0xff;
2068}
2069
2070static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
2071 struct hw_perf_event *event)
2072{
2073 int idx;
2074
2075 /* Always place a cycle counter into the cycle counter. */
2076 if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
2077 if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
2078 return -EAGAIN;
2079
2080 return ARMV7_CYCLE_COUNTER;
2081 } else {
2082 /*
2083 * For anything other than a cycle counter, try and use
2084 * the events counters
2085 */
2086 for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
2087 if (!test_and_set_bit(idx, cpuc->used_mask))
2088 return idx;
2089 }
2090
2091 /* The counters are all in use. */
2092 return -EAGAIN;
2093 }
2094}
2095
2096static struct arm_pmu armv7pmu = {
2097 .handle_irq = armv7pmu_handle_irq,
2098 .enable = armv7pmu_enable_event,
2099 .disable = armv7pmu_disable_event,
2100 .raw_event = armv7pmu_raw_event,
2101 .read_counter = armv7pmu_read_counter,
2102 .write_counter = armv7pmu_write_counter,
2103 .get_event_idx = armv7pmu_get_event_idx,
2104 .start = armv7pmu_start,
2105 .stop = armv7pmu_stop,
2106 .max_period = (1LLU << 32) - 1,
2107}; 621};
2108 622
2109static u32 __init armv7_reset_read_pmnc(void) 623/* Include the PMU-specific implementations. */
2110{ 624#include "perf_event_xscale.c"
2111 u32 nb_cnt; 625#include "perf_event_v6.c"
2112 626#include "perf_event_v7.c"
2113 /* Initialize & Reset PMNC: C and P bits */
2114 armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
2115
2116 /* Read the nb of CNTx counters supported from PMNC */
2117 nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
2118
2119 /* Add the CPU cycles counter and return */
2120 return nb_cnt + 1;
2121}
2122 627
2123/* 628/*
2124 * ARMv5 [xscale] Performance counter handling code. 629 * Ensure the PMU has sane values out of reset.
2125 * 630 * This requires SMP to be available, so exists as a separate initcall.
2126 * Based on xscale OProfile code.
2127 *
2128 * There are two variants of the xscale PMU that we support:
2129 * - xscale1pmu: 2 event counters and a cycle counter
2130 * - xscale2pmu: 4 event counters and a cycle counter
2131 * The two variants share event definitions, but have different
2132 * PMU structures.
2133 */ 631 */
2134 632static int __init
2135enum xscale_perf_types { 633armpmu_reset(void)
2136 XSCALE_PERFCTR_ICACHE_MISS = 0x00,
2137 XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
2138 XSCALE_PERFCTR_DATA_STALL = 0x02,
2139 XSCALE_PERFCTR_ITLB_MISS = 0x03,
2140 XSCALE_PERFCTR_DTLB_MISS = 0x04,
2141 XSCALE_PERFCTR_BRANCH = 0x05,
2142 XSCALE_PERFCTR_BRANCH_MISS = 0x06,
2143 XSCALE_PERFCTR_INSTRUCTION = 0x07,
2144 XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
2145 XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
2146 XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
2147 XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
2148 XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
2149 XSCALE_PERFCTR_PC_CHANGED = 0x0D,
2150 XSCALE_PERFCTR_BCU_REQUEST = 0x10,
2151 XSCALE_PERFCTR_BCU_FULL = 0x11,
2152 XSCALE_PERFCTR_BCU_DRAIN = 0x12,
2153 XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
2154 XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
2155 XSCALE_PERFCTR_RMW = 0x16,
2156 /* XSCALE_PERFCTR_CCNT is not hardware defined */
2157 XSCALE_PERFCTR_CCNT = 0xFE,
2158 XSCALE_PERFCTR_UNUSED = 0xFF,
2159};
2160
2161enum xscale_counters {
2162 XSCALE_CYCLE_COUNTER = 1,
2163 XSCALE_COUNTER0,
2164 XSCALE_COUNTER1,
2165 XSCALE_COUNTER2,
2166 XSCALE_COUNTER3,
2167};
2168
2169static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
2170 [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
2171 [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
2172 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
2173 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
2174 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
2175 [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
2176 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
2177};
2178
2179static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
2180 [PERF_COUNT_HW_CACHE_OP_MAX]
2181 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
2182 [C(L1D)] = {
2183 [C(OP_READ)] = {
2184 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
2185 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
2186 },
2187 [C(OP_WRITE)] = {
2188 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
2189 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
2190 },
2191 [C(OP_PREFETCH)] = {
2192 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2193 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2194 },
2195 },
2196 [C(L1I)] = {
2197 [C(OP_READ)] = {
2198 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2199 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
2200 },
2201 [C(OP_WRITE)] = {
2202 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2203 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
2204 },
2205 [C(OP_PREFETCH)] = {
2206 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2207 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2208 },
2209 },
2210 [C(LL)] = {
2211 [C(OP_READ)] = {
2212 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2213 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2214 },
2215 [C(OP_WRITE)] = {
2216 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2217 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2218 },
2219 [C(OP_PREFETCH)] = {
2220 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2221 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2222 },
2223 },
2224 [C(DTLB)] = {
2225 [C(OP_READ)] = {
2226 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2227 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
2228 },
2229 [C(OP_WRITE)] = {
2230 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2231 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
2232 },
2233 [C(OP_PREFETCH)] = {
2234 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2235 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2236 },
2237 },
2238 [C(ITLB)] = {
2239 [C(OP_READ)] = {
2240 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2241 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
2242 },
2243 [C(OP_WRITE)] = {
2244 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2245 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
2246 },
2247 [C(OP_PREFETCH)] = {
2248 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2249 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2250 },
2251 },
2252 [C(BPU)] = {
2253 [C(OP_READ)] = {
2254 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2255 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2256 },
2257 [C(OP_WRITE)] = {
2258 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2259 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2260 },
2261 [C(OP_PREFETCH)] = {
2262 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
2263 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
2264 },
2265 },
2266};
2267
2268#define XSCALE_PMU_ENABLE 0x001
2269#define XSCALE_PMN_RESET 0x002
2270#define XSCALE_CCNT_RESET 0x004
2271#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
2272#define XSCALE_PMU_CNT64 0x008
2273
2274static inline int
2275xscalepmu_event_map(int config)
2276{
2277 int mapping = xscale_perf_map[config];
2278 if (HW_OP_UNSUPPORTED == mapping)
2279 mapping = -EOPNOTSUPP;
2280 return mapping;
2281}
2282
2283static u64
2284xscalepmu_raw_event(u64 config)
2285{
2286 return config & 0xff;
2287}
2288
2289#define XSCALE1_OVERFLOWED_MASK 0x700
2290#define XSCALE1_CCOUNT_OVERFLOW 0x400
2291#define XSCALE1_COUNT0_OVERFLOW 0x100
2292#define XSCALE1_COUNT1_OVERFLOW 0x200
2293#define XSCALE1_CCOUNT_INT_EN 0x040
2294#define XSCALE1_COUNT0_INT_EN 0x010
2295#define XSCALE1_COUNT1_INT_EN 0x020
2296#define XSCALE1_COUNT0_EVT_SHFT 12
2297#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
2298#define XSCALE1_COUNT1_EVT_SHFT 20
2299#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
2300
2301static inline u32
2302xscale1pmu_read_pmnc(void)
2303{
2304 u32 val;
2305 asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
2306 return val;
2307}
2308
2309static inline void
2310xscale1pmu_write_pmnc(u32 val)
2311{
2312 /* upper 4bits and 7, 11 are write-as-0 */
2313 val &= 0xffff77f;
2314 asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
2315}
2316
2317static inline int
2318xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
2319 enum xscale_counters counter)
2320{
2321 int ret = 0;
2322
2323 switch (counter) {
2324 case XSCALE_CYCLE_COUNTER:
2325 ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
2326 break;
2327 case XSCALE_COUNTER0:
2328 ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
2329 break;
2330 case XSCALE_COUNTER1:
2331 ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
2332 break;
2333 default:
2334 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
2335 }
2336
2337 return ret;
2338}
2339
2340static irqreturn_t
2341xscale1pmu_handle_irq(int irq_num, void *dev)
2342{
2343 unsigned long pmnc;
2344 struct perf_sample_data data;
2345 struct cpu_hw_events *cpuc;
2346 struct pt_regs *regs;
2347 int idx;
2348
2349 /*
2350 * NOTE: there's an A stepping erratum that states if an overflow
2351 * bit already exists and another occurs, the previous
2352 * Overflow bit gets cleared. There's no workaround.
2353 * Fixed in B stepping or later.
2354 */
2355 pmnc = xscale1pmu_read_pmnc();
2356
2357 /*
2358 * Write the value back to clear the overflow flags. Overflow
2359 * flags remain in pmnc for use below. We also disable the PMU
2360 * while we process the interrupt.
2361 */
2362 xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
2363
2364 if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
2365 return IRQ_NONE;
2366
2367 regs = get_irq_regs();
2368
2369 perf_sample_data_init(&data, 0);
2370
2371 cpuc = &__get_cpu_var(cpu_hw_events);
2372 for (idx = 0; idx <= armpmu->num_events; ++idx) {
2373 struct perf_event *event = cpuc->events[idx];
2374 struct hw_perf_event *hwc;
2375
2376 if (!test_bit(idx, cpuc->active_mask))
2377 continue;
2378
2379 if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
2380 continue;
2381
2382 hwc = &event->hw;
2383 armpmu_event_update(event, hwc, idx);
2384 data.period = event->hw.last_period;
2385 if (!armpmu_event_set_period(event, hwc, idx))
2386 continue;
2387
2388 if (perf_event_overflow(event, 0, &data, regs))
2389 armpmu->disable(hwc, idx);
2390 }
2391
2392 perf_event_do_pending();
2393
2394 /*
2395 * Re-enable the PMU.
2396 */
2397 pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
2398 xscale1pmu_write_pmnc(pmnc);
2399
2400 return IRQ_HANDLED;
2401}
2402
2403static void
2404xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
2405{
2406 unsigned long val, mask, evt, flags;
2407
2408 switch (idx) {
2409 case XSCALE_CYCLE_COUNTER:
2410 mask = 0;
2411 evt = XSCALE1_CCOUNT_INT_EN;
2412 break;
2413 case XSCALE_COUNTER0:
2414 mask = XSCALE1_COUNT0_EVT_MASK;
2415 evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
2416 XSCALE1_COUNT0_INT_EN;
2417 break;
2418 case XSCALE_COUNTER1:
2419 mask = XSCALE1_COUNT1_EVT_MASK;
2420 evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
2421 XSCALE1_COUNT1_INT_EN;
2422 break;
2423 default:
2424 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
2425 return;
2426 }
2427
2428 spin_lock_irqsave(&pmu_lock, flags);
2429 val = xscale1pmu_read_pmnc();
2430 val &= ~mask;
2431 val |= evt;
2432 xscale1pmu_write_pmnc(val);
2433 spin_unlock_irqrestore(&pmu_lock, flags);
2434}
2435
2436static void
2437xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
2438{
2439 unsigned long val, mask, evt, flags;
2440
2441 switch (idx) {
2442 case XSCALE_CYCLE_COUNTER:
2443 mask = XSCALE1_CCOUNT_INT_EN;
2444 evt = 0;
2445 break;
2446 case XSCALE_COUNTER0:
2447 mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
2448 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
2449 break;
2450 case XSCALE_COUNTER1:
2451 mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
2452 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
2453 break;
2454 default:
2455 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
2456 return;
2457 }
2458
2459 spin_lock_irqsave(&pmu_lock, flags);
2460 val = xscale1pmu_read_pmnc();
2461 val &= ~mask;
2462 val |= evt;
2463 xscale1pmu_write_pmnc(val);
2464 spin_unlock_irqrestore(&pmu_lock, flags);
2465}
2466
2467static int
2468xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
2469 struct hw_perf_event *event)
2470{
2471 if (XSCALE_PERFCTR_CCNT == event->config_base) {
2472 if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
2473 return -EAGAIN;
2474
2475 return XSCALE_CYCLE_COUNTER;
2476 } else {
2477 if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask)) {
2478 return XSCALE_COUNTER1;
2479 }
2480
2481 if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask)) {
2482 return XSCALE_COUNTER0;
2483 }
2484
2485 return -EAGAIN;
2486 }
2487}
2488
2489static void
2490xscale1pmu_start(void)
2491{
2492 unsigned long flags, val;
2493
2494 spin_lock_irqsave(&pmu_lock, flags);
2495 val = xscale1pmu_read_pmnc();
2496 val |= XSCALE_PMU_ENABLE;
2497 xscale1pmu_write_pmnc(val);
2498 spin_unlock_irqrestore(&pmu_lock, flags);
2499}
2500
2501static void
2502xscale1pmu_stop(void)
2503{
2504 unsigned long flags, val;
2505
2506 spin_lock_irqsave(&pmu_lock, flags);
2507 val = xscale1pmu_read_pmnc();
2508 val &= ~XSCALE_PMU_ENABLE;
2509 xscale1pmu_write_pmnc(val);
2510 spin_unlock_irqrestore(&pmu_lock, flags);
2511}
2512
2513static inline u32
2514xscale1pmu_read_counter(int counter)
2515{
2516 u32 val = 0;
2517
2518 switch (counter) {
2519 case XSCALE_CYCLE_COUNTER:
2520 asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
2521 break;
2522 case XSCALE_COUNTER0:
2523 asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
2524 break;
2525 case XSCALE_COUNTER1:
2526 asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
2527 break;
2528 }
2529
2530 return val;
2531}
2532
2533static inline void
2534xscale1pmu_write_counter(int counter, u32 val)
2535{
2536 switch (counter) {
2537 case XSCALE_CYCLE_COUNTER:
2538 asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
2539 break;
2540 case XSCALE_COUNTER0:
2541 asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
2542 break;
2543 case XSCALE_COUNTER1:
2544 asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
2545 break;
2546 }
2547}
2548
2549static const struct arm_pmu xscale1pmu = {
2550 .id = ARM_PERF_PMU_ID_XSCALE1,
2551 .handle_irq = xscale1pmu_handle_irq,
2552 .enable = xscale1pmu_enable_event,
2553 .disable = xscale1pmu_disable_event,
2554 .event_map = xscalepmu_event_map,
2555 .raw_event = xscalepmu_raw_event,
2556 .read_counter = xscale1pmu_read_counter,
2557 .write_counter = xscale1pmu_write_counter,
2558 .get_event_idx = xscale1pmu_get_event_idx,
2559 .start = xscale1pmu_start,
2560 .stop = xscale1pmu_stop,
2561 .num_events = 3,
2562 .max_period = (1LLU << 32) - 1,
2563};
2564
2565#define XSCALE2_OVERFLOWED_MASK 0x01f
2566#define XSCALE2_CCOUNT_OVERFLOW 0x001
2567#define XSCALE2_COUNT0_OVERFLOW 0x002
2568#define XSCALE2_COUNT1_OVERFLOW 0x004
2569#define XSCALE2_COUNT2_OVERFLOW 0x008
2570#define XSCALE2_COUNT3_OVERFLOW 0x010
2571#define XSCALE2_CCOUNT_INT_EN 0x001
2572#define XSCALE2_COUNT0_INT_EN 0x002
2573#define XSCALE2_COUNT1_INT_EN 0x004
2574#define XSCALE2_COUNT2_INT_EN 0x008
2575#define XSCALE2_COUNT3_INT_EN 0x010
2576#define XSCALE2_COUNT0_EVT_SHFT 0
2577#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
2578#define XSCALE2_COUNT1_EVT_SHFT 8
2579#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
2580#define XSCALE2_COUNT2_EVT_SHFT 16
2581#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
2582#define XSCALE2_COUNT3_EVT_SHFT 24
2583#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
2584
2585static inline u32
2586xscale2pmu_read_pmnc(void)
2587{
2588 u32 val;
2589 asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
2590 /* bits 1-2 and 4-23 are read-unpredictable */
2591 return val & 0xff000009;
2592}
2593
2594static inline void
2595xscale2pmu_write_pmnc(u32 val)
2596{
2597 /* bits 4-23 are write-as-0, 24-31 are write ignored */
2598 val &= 0xf;
2599 asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
2600}
2601
2602static inline u32
2603xscale2pmu_read_overflow_flags(void)
2604{
2605 u32 val;
2606 asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
2607 return val;
2608}
2609
2610static inline void
2611xscale2pmu_write_overflow_flags(u32 val)
2612{
2613 asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
2614}
2615
2616static inline u32
2617xscale2pmu_read_event_select(void)
2618{
2619 u32 val;
2620 asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
2621 return val;
2622}
2623
2624static inline void
2625xscale2pmu_write_event_select(u32 val)
2626{
2627 asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
2628}
2629
2630static inline u32
2631xscale2pmu_read_int_enable(void)
2632{
2633 u32 val;
2634 asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
2635 return val;
2636}
2637
2638static void
2639xscale2pmu_write_int_enable(u32 val)
2640{
2641 asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
2642}
2643
2644static inline int
2645xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
2646 enum xscale_counters counter)
2647{
2648 int ret = 0;
2649
2650 switch (counter) {
2651 case XSCALE_CYCLE_COUNTER:
2652 ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
2653 break;
2654 case XSCALE_COUNTER0:
2655 ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
2656 break;
2657 case XSCALE_COUNTER1:
2658 ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
2659 break;
2660 case XSCALE_COUNTER2:
2661 ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
2662 break;
2663 case XSCALE_COUNTER3:
2664 ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
2665 break;
2666 default:
2667 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
2668 }
2669
2670 return ret;
2671}
2672
2673static irqreturn_t
2674xscale2pmu_handle_irq(int irq_num, void *dev)
2675{
2676 unsigned long pmnc, of_flags;
2677 struct perf_sample_data data;
2678 struct cpu_hw_events *cpuc;
2679 struct pt_regs *regs;
2680 int idx;
2681
2682 /* Disable the PMU. */
2683 pmnc = xscale2pmu_read_pmnc();
2684 xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
2685
2686 /* Check the overflow flag register. */
2687 of_flags = xscale2pmu_read_overflow_flags();
2688 if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
2689 return IRQ_NONE;
2690
2691 /* Clear the overflow bits. */
2692 xscale2pmu_write_overflow_flags(of_flags);
2693
2694 regs = get_irq_regs();
2695
2696 perf_sample_data_init(&data, 0);
2697
2698 cpuc = &__get_cpu_var(cpu_hw_events);
2699 for (idx = 0; idx <= armpmu->num_events; ++idx) {
2700 struct perf_event *event = cpuc->events[idx];
2701 struct hw_perf_event *hwc;
2702
2703 if (!test_bit(idx, cpuc->active_mask))
2704 continue;
2705
2706 if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
2707 continue;
2708
2709 hwc = &event->hw;
2710 armpmu_event_update(event, hwc, idx);
2711 data.period = event->hw.last_period;
2712 if (!armpmu_event_set_period(event, hwc, idx))
2713 continue;
2714
2715 if (perf_event_overflow(event, 0, &data, regs))
2716 armpmu->disable(hwc, idx);
2717 }
2718
2719 perf_event_do_pending();
2720
2721 /*
2722 * Re-enable the PMU.
2723 */
2724 pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
2725 xscale2pmu_write_pmnc(pmnc);
2726
2727 return IRQ_HANDLED;
2728}
2729
2730static void
2731xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
2732{
2733 unsigned long flags, ien, evtsel;
2734
2735 ien = xscale2pmu_read_int_enable();
2736 evtsel = xscale2pmu_read_event_select();
2737
2738 switch (idx) {
2739 case XSCALE_CYCLE_COUNTER:
2740 ien |= XSCALE2_CCOUNT_INT_EN;
2741 break;
2742 case XSCALE_COUNTER0:
2743 ien |= XSCALE2_COUNT0_INT_EN;
2744 evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
2745 evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
2746 break;
2747 case XSCALE_COUNTER1:
2748 ien |= XSCALE2_COUNT1_INT_EN;
2749 evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
2750 evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
2751 break;
2752 case XSCALE_COUNTER2:
2753 ien |= XSCALE2_COUNT2_INT_EN;
2754 evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
2755 evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
2756 break;
2757 case XSCALE_COUNTER3:
2758 ien |= XSCALE2_COUNT3_INT_EN;
2759 evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
2760 evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
2761 break;
2762 default:
2763 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
2764 return;
2765 }
2766
2767 spin_lock_irqsave(&pmu_lock, flags);
2768 xscale2pmu_write_event_select(evtsel);
2769 xscale2pmu_write_int_enable(ien);
2770 spin_unlock_irqrestore(&pmu_lock, flags);
2771}
2772
2773static void
2774xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
2775{
2776 unsigned long flags, ien, evtsel;
2777
2778 ien = xscale2pmu_read_int_enable();
2779 evtsel = xscale2pmu_read_event_select();
2780
2781 switch (idx) {
2782 case XSCALE_CYCLE_COUNTER:
2783 ien &= ~XSCALE2_CCOUNT_INT_EN;
2784 break;
2785 case XSCALE_COUNTER0:
2786 ien &= ~XSCALE2_COUNT0_INT_EN;
2787 evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
2788 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
2789 break;
2790 case XSCALE_COUNTER1:
2791 ien &= ~XSCALE2_COUNT1_INT_EN;
2792 evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
2793 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
2794 break;
2795 case XSCALE_COUNTER2:
2796 ien &= ~XSCALE2_COUNT2_INT_EN;
2797 evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
2798 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
2799 break;
2800 case XSCALE_COUNTER3:
2801 ien &= ~XSCALE2_COUNT3_INT_EN;
2802 evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
2803 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
2804 break;
2805 default:
2806 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
2807 return;
2808 }
2809
2810 spin_lock_irqsave(&pmu_lock, flags);
2811 xscale2pmu_write_event_select(evtsel);
2812 xscale2pmu_write_int_enable(ien);
2813 spin_unlock_irqrestore(&pmu_lock, flags);
2814}
2815
2816static int
2817xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
2818 struct hw_perf_event *event)
2819{
2820 int idx = xscale1pmu_get_event_idx(cpuc, event);
2821 if (idx >= 0)
2822 goto out;
2823
2824 if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
2825 idx = XSCALE_COUNTER3;
2826 else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
2827 idx = XSCALE_COUNTER2;
2828out:
2829 return idx;
2830}
2831
2832static void
2833xscale2pmu_start(void)
2834{
2835 unsigned long flags, val;
2836
2837 spin_lock_irqsave(&pmu_lock, flags);
2838 val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
2839 val |= XSCALE_PMU_ENABLE;
2840 xscale2pmu_write_pmnc(val);
2841 spin_unlock_irqrestore(&pmu_lock, flags);
2842}
2843
2844static void
2845xscale2pmu_stop(void)
2846{
2847 unsigned long flags, val;
2848
2849 spin_lock_irqsave(&pmu_lock, flags);
2850 val = xscale2pmu_read_pmnc();
2851 val &= ~XSCALE_PMU_ENABLE;
2852 xscale2pmu_write_pmnc(val);
2853 spin_unlock_irqrestore(&pmu_lock, flags);
2854}
2855
2856static inline u32
2857xscale2pmu_read_counter(int counter)
2858{
2859 u32 val = 0;
2860
2861 switch (counter) {
2862 case XSCALE_CYCLE_COUNTER:
2863 asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
2864 break;
2865 case XSCALE_COUNTER0:
2866 asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
2867 break;
2868 case XSCALE_COUNTER1:
2869 asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
2870 break;
2871 case XSCALE_COUNTER2:
2872 asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
2873 break;
2874 case XSCALE_COUNTER3:
2875 asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
2876 break;
2877 }
2878
2879 return val;
2880}
2881
2882static inline void
2883xscale2pmu_write_counter(int counter, u32 val)
2884{ 634{
2885 switch (counter) { 635 if (armpmu && armpmu->reset)
2886 case XSCALE_CYCLE_COUNTER: 636 return on_each_cpu(armpmu->reset, NULL, 1);
2887 asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val)); 637 return 0;
2888 break;
2889 case XSCALE_COUNTER0:
2890 asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
2891 break;
2892 case XSCALE_COUNTER1:
2893 asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
2894 break;
2895 case XSCALE_COUNTER2:
2896 asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
2897 break;
2898 case XSCALE_COUNTER3:
2899 asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
2900 break;
2901 }
2902} 638}
2903 639arch_initcall(armpmu_reset);
2904static const struct arm_pmu xscale2pmu = {
2905 .id = ARM_PERF_PMU_ID_XSCALE2,
2906 .handle_irq = xscale2pmu_handle_irq,
2907 .enable = xscale2pmu_enable_event,
2908 .disable = xscale2pmu_disable_event,
2909 .event_map = xscalepmu_event_map,
2910 .raw_event = xscalepmu_raw_event,
2911 .read_counter = xscale2pmu_read_counter,
2912 .write_counter = xscale2pmu_write_counter,
2913 .get_event_idx = xscale2pmu_get_event_idx,
2914 .start = xscale2pmu_start,
2915 .stop = xscale2pmu_stop,
2916 .num_events = 5,
2917 .max_period = (1LLU << 32) - 1,
2918};
2919 640
2920static int __init 641static int __init
2921init_hw_perf_events(void) 642init_hw_perf_events(void)
@@ -2930,41 +651,16 @@ init_hw_perf_events(void)
2930 case 0xB360: /* ARM1136 */ 651 case 0xB360: /* ARM1136 */
2931 case 0xB560: /* ARM1156 */ 652 case 0xB560: /* ARM1156 */
2932 case 0xB760: /* ARM1176 */ 653 case 0xB760: /* ARM1176 */
2933 armpmu = &armv6pmu; 654 armpmu = armv6pmu_init();
2934 memcpy(armpmu_perf_cache_map, armv6_perf_cache_map,
2935 sizeof(armv6_perf_cache_map));
2936 perf_max_events = armv6pmu.num_events;
2937 break; 655 break;
2938 case 0xB020: /* ARM11mpcore */ 656 case 0xB020: /* ARM11mpcore */
2939 armpmu = &armv6mpcore_pmu; 657 armpmu = armv6mpcore_pmu_init();
2940 memcpy(armpmu_perf_cache_map,
2941 armv6mpcore_perf_cache_map,
2942 sizeof(armv6mpcore_perf_cache_map));
2943 perf_max_events = armv6mpcore_pmu.num_events;
2944 break; 658 break;
2945 case 0xC080: /* Cortex-A8 */ 659 case 0xC080: /* Cortex-A8 */
2946 armv7pmu.id = ARM_PERF_PMU_ID_CA8; 660 armpmu = armv7_a8_pmu_init();
2947 memcpy(armpmu_perf_cache_map, armv7_a8_perf_cache_map,
2948 sizeof(armv7_a8_perf_cache_map));
2949 armv7pmu.event_map = armv7_a8_pmu_event_map;
2950 armpmu = &armv7pmu;
2951
2952 /* Reset PMNC and read the nb of CNTx counters
2953 supported */
2954 armv7pmu.num_events = armv7_reset_read_pmnc();
2955 perf_max_events = armv7pmu.num_events;
2956 break; 661 break;
2957 case 0xC090: /* Cortex-A9 */ 662 case 0xC090: /* Cortex-A9 */
2958 armv7pmu.id = ARM_PERF_PMU_ID_CA9; 663 armpmu = armv7_a9_pmu_init();
2959 memcpy(armpmu_perf_cache_map, armv7_a9_perf_cache_map,
2960 sizeof(armv7_a9_perf_cache_map));
2961 armv7pmu.event_map = armv7_a9_pmu_event_map;
2962 armpmu = &armv7pmu;
2963
2964 /* Reset PMNC and read the nb of CNTx counters
2965 supported */
2966 armv7pmu.num_events = armv7_reset_read_pmnc();
2967 perf_max_events = armv7pmu.num_events;
2968 break; 664 break;
2969 } 665 }
2970 /* Intel CPUs [xscale]. */ 666 /* Intel CPUs [xscale]. */
@@ -2972,42 +668,30 @@ init_hw_perf_events(void)
2972 part_number = (cpuid >> 13) & 0x7; 668 part_number = (cpuid >> 13) & 0x7;
2973 switch (part_number) { 669 switch (part_number) {
2974 case 1: 670 case 1:
2975 armpmu = &xscale1pmu; 671 armpmu = xscale1pmu_init();
2976 memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
2977 sizeof(xscale_perf_cache_map));
2978 perf_max_events = xscale1pmu.num_events;
2979 break; 672 break;
2980 case 2: 673 case 2:
2981 armpmu = &xscale2pmu; 674 armpmu = xscale2pmu_init();
2982 memcpy(armpmu_perf_cache_map, xscale_perf_cache_map,
2983 sizeof(xscale_perf_cache_map));
2984 perf_max_events = xscale2pmu.num_events;
2985 break; 675 break;
2986 } 676 }
2987 } 677 }
2988 678
2989 if (armpmu) { 679 if (armpmu) {
2990 pr_info("enabled with %s PMU driver, %d counters available\n", 680 pr_info("enabled with %s PMU driver, %d counters available\n",
2991 arm_pmu_names[armpmu->id], armpmu->num_events); 681 armpmu->name, armpmu->num_events);
2992 } else { 682 } else {
2993 pr_info("no hardware support available\n"); 683 pr_info("no hardware support available\n");
2994 perf_max_events = -1;
2995 } 684 }
2996 685
686 perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
687
2997 return 0; 688 return 0;
2998} 689}
2999arch_initcall(init_hw_perf_events); 690early_initcall(init_hw_perf_events);
3000 691
3001/* 692/*
3002 * Callchain handling code. 693 * Callchain handling code.
3003 */ 694 */
3004static inline void
3005callchain_store(struct perf_callchain_entry *entry,
3006 u64 ip)
3007{
3008 if (entry->nr < PERF_MAX_STACK_DEPTH)
3009 entry->ip[entry->nr++] = ip;
3010}
3011 695
3012/* 696/*
3013 * The registers we're interested in are at the end of the variable 697 * The registers we're interested in are at the end of the variable
@@ -3018,17 +702,17 @@ callchain_store(struct perf_callchain_entry *entry,
3018 * This code has been adapted from the ARM OProfile support. 702 * This code has been adapted from the ARM OProfile support.
3019 */ 703 */
3020struct frame_tail { 704struct frame_tail {
3021 struct frame_tail *fp; 705 struct frame_tail __user *fp;
3022 unsigned long sp; 706 unsigned long sp;
3023 unsigned long lr; 707 unsigned long lr;
3024} __attribute__((packed)); 708} __attribute__((packed));
3025 709
3026/* 710/*
3027 * Get the return address for a single stackframe and return a pointer to the 711 * Get the return address for a single stackframe and return a pointer to the
3028 * next frame tail. 712 * next frame tail.
3029 */ 713 */
3030static struct frame_tail * 714static struct frame_tail __user *
3031user_backtrace(struct frame_tail *tail, 715user_backtrace(struct frame_tail __user *tail,
3032 struct perf_callchain_entry *entry) 716 struct perf_callchain_entry *entry)
3033{ 717{
3034 struct frame_tail buftail; 718 struct frame_tail buftail;
@@ -3039,32 +723,28 @@ user_backtrace(struct frame_tail *tail,
3039 if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail))) 723 if (__copy_from_user_inatomic(&buftail, tail, sizeof(buftail)))
3040 return NULL; 724 return NULL;
3041 725
3042 callchain_store(entry, buftail.lr); 726 perf_callchain_store(entry, buftail.lr);
3043 727
3044 /* 728 /*
3045 * Frame pointers should strictly progress back up the stack 729 * Frame pointers should strictly progress back up the stack
3046 * (towards higher addresses). 730 * (towards higher addresses).
3047 */ 731 */
3048 if (tail >= buftail.fp) 732 if (tail + 1 >= buftail.fp)
3049 return NULL; 733 return NULL;
3050 734
3051 return buftail.fp - 1; 735 return buftail.fp - 1;
3052} 736}
3053 737
3054static void 738void
3055perf_callchain_user(struct pt_regs *regs, 739perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
3056 struct perf_callchain_entry *entry)
3057{ 740{
3058 struct frame_tail *tail; 741 struct frame_tail __user *tail;
3059
3060 callchain_store(entry, PERF_CONTEXT_USER);
3061 742
3062 if (!user_mode(regs))
3063 regs = task_pt_regs(current);
3064 743
3065 tail = (struct frame_tail *)regs->ARM_fp - 1; 744 tail = (struct frame_tail __user *)regs->ARM_fp - 1;
3066 745
3067 while (tail && !((unsigned long)tail & 0x3)) 746 while ((entry->nr < PERF_MAX_STACK_DEPTH) &&
747 tail && !((unsigned long)tail & 0x3))
3068 tail = user_backtrace(tail, entry); 748 tail = user_backtrace(tail, entry);
3069} 749}
3070 750
@@ -3078,56 +758,18 @@ callchain_trace(struct stackframe *fr,
3078 void *data) 758 void *data)
3079{ 759{
3080 struct perf_callchain_entry *entry = data; 760 struct perf_callchain_entry *entry = data;
3081 callchain_store(entry, fr->pc); 761 perf_callchain_store(entry, fr->pc);
3082 return 0; 762 return 0;
3083} 763}
3084 764
3085static void 765void
3086perf_callchain_kernel(struct pt_regs *regs, 766perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
3087 struct perf_callchain_entry *entry)
3088{ 767{
3089 struct stackframe fr; 768 struct stackframe fr;
3090 769
3091 callchain_store(entry, PERF_CONTEXT_KERNEL);
3092 fr.fp = regs->ARM_fp; 770 fr.fp = regs->ARM_fp;
3093 fr.sp = regs->ARM_sp; 771 fr.sp = regs->ARM_sp;
3094 fr.lr = regs->ARM_lr; 772 fr.lr = regs->ARM_lr;
3095 fr.pc = regs->ARM_pc; 773 fr.pc = regs->ARM_pc;
3096 walk_stackframe(&fr, callchain_trace, entry); 774 walk_stackframe(&fr, callchain_trace, entry);
3097} 775}
3098
3099static void
3100perf_do_callchain(struct pt_regs *regs,
3101 struct perf_callchain_entry *entry)
3102{
3103 int is_user;
3104
3105 if (!regs)
3106 return;
3107
3108 is_user = user_mode(regs);
3109
3110 if (!current || !current->pid)
3111 return;
3112
3113 if (is_user && current->state != TASK_RUNNING)
3114 return;
3115
3116 if (!is_user)
3117 perf_callchain_kernel(regs, entry);
3118
3119 if (current->mm)
3120 perf_callchain_user(regs, entry);
3121}
3122
3123static DEFINE_PER_CPU(struct perf_callchain_entry, pmc_irq_entry);
3124
3125struct perf_callchain_entry *
3126perf_callchain(struct pt_regs *regs)
3127{
3128 struct perf_callchain_entry *entry = &__get_cpu_var(pmc_irq_entry);
3129
3130 entry->nr = 0;
3131 perf_do_callchain(regs, entry);
3132 return entry;
3133}
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
new file mode 100644
index 000000000000..f1e8dd94afe8
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -0,0 +1,672 @@
1/*
2 * ARMv6 Performance counter handling code.
3 *
4 * Copyright (C) 2009 picoChip Designs, Ltd., Jamie Iles
5 *
6 * ARMv6 has 2 configurable performance counters and a single cycle counter.
7 * They all share a single reset bit but can be written to zero so we can use
8 * that for a reset.
9 *
10 * The counters can't be individually enabled or disabled so when we remove
11 * one event and replace it with another we could get spurious counts from the
12 * wrong event. However, we can take advantage of the fact that the
13 * performance counters can export events to the event bus, and the event bus
14 * itself can be monitored. This requires that we *don't* export the events to
15 * the event bus. The procedure for disabling a configurable counter is:
16 * - change the counter to count the ETMEXTOUT[0] signal (0x20). This
17 * effectively stops the counter from counting.
18 * - disable the counter's interrupt generation (each counter has it's
19 * own interrupt enable bit).
20 * Once stopped, the counter value can be written as 0 to reset.
21 *
22 * To enable a counter:
23 * - enable the counter's interrupt generation.
24 * - set the new event type.
25 *
26 * Note: the dedicated cycle counter only counts cycles and can't be
27 * enabled/disabled independently of the others. When we want to disable the
28 * cycle counter, we have to just disable the interrupt reporting and start
29 * ignoring that counter. When re-enabling, we have to reset the value and
30 * enable the interrupt.
31 */
32
33#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
34enum armv6_perf_types {
35 ARMV6_PERFCTR_ICACHE_MISS = 0x0,
36 ARMV6_PERFCTR_IBUF_STALL = 0x1,
37 ARMV6_PERFCTR_DDEP_STALL = 0x2,
38 ARMV6_PERFCTR_ITLB_MISS = 0x3,
39 ARMV6_PERFCTR_DTLB_MISS = 0x4,
40 ARMV6_PERFCTR_BR_EXEC = 0x5,
41 ARMV6_PERFCTR_BR_MISPREDICT = 0x6,
42 ARMV6_PERFCTR_INSTR_EXEC = 0x7,
43 ARMV6_PERFCTR_DCACHE_HIT = 0x9,
44 ARMV6_PERFCTR_DCACHE_ACCESS = 0xA,
45 ARMV6_PERFCTR_DCACHE_MISS = 0xB,
46 ARMV6_PERFCTR_DCACHE_WBACK = 0xC,
47 ARMV6_PERFCTR_SW_PC_CHANGE = 0xD,
48 ARMV6_PERFCTR_MAIN_TLB_MISS = 0xF,
49 ARMV6_PERFCTR_EXPL_D_ACCESS = 0x10,
50 ARMV6_PERFCTR_LSU_FULL_STALL = 0x11,
51 ARMV6_PERFCTR_WBUF_DRAINED = 0x12,
52 ARMV6_PERFCTR_CPU_CYCLES = 0xFF,
53 ARMV6_PERFCTR_NOP = 0x20,
54};
55
56enum armv6_counters {
57 ARMV6_CYCLE_COUNTER = 1,
58 ARMV6_COUNTER0,
59 ARMV6_COUNTER1,
60};
61
62/*
63 * The hardware events that we support. We do support cache operations but
64 * we have harvard caches and no way to combine instruction and data
65 * accesses/misses in hardware.
66 */
67static const unsigned armv6_perf_map[PERF_COUNT_HW_MAX] = {
68 [PERF_COUNT_HW_CPU_CYCLES] = ARMV6_PERFCTR_CPU_CYCLES,
69 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6_PERFCTR_INSTR_EXEC,
70 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
71 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
72 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6_PERFCTR_BR_EXEC,
73 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6_PERFCTR_BR_MISPREDICT,
74 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
75};
76
77static const unsigned armv6_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
78 [PERF_COUNT_HW_CACHE_OP_MAX]
79 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
80 [C(L1D)] = {
81 /*
82 * The performance counters don't differentiate between read
83 * and write accesses/misses so this isn't strictly correct,
84 * but it's the best we can do. Writes and reads get
85 * combined.
86 */
87 [C(OP_READ)] = {
88 [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
89 [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
90 },
91 [C(OP_WRITE)] = {
92 [C(RESULT_ACCESS)] = ARMV6_PERFCTR_DCACHE_ACCESS,
93 [C(RESULT_MISS)] = ARMV6_PERFCTR_DCACHE_MISS,
94 },
95 [C(OP_PREFETCH)] = {
96 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
97 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
98 },
99 },
100 [C(L1I)] = {
101 [C(OP_READ)] = {
102 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
103 [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
104 },
105 [C(OP_WRITE)] = {
106 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
107 [C(RESULT_MISS)] = ARMV6_PERFCTR_ICACHE_MISS,
108 },
109 [C(OP_PREFETCH)] = {
110 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
111 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
112 },
113 },
114 [C(LL)] = {
115 [C(OP_READ)] = {
116 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
117 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
118 },
119 [C(OP_WRITE)] = {
120 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
121 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
122 },
123 [C(OP_PREFETCH)] = {
124 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
125 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
126 },
127 },
128 [C(DTLB)] = {
129 /*
130 * The ARM performance counters can count micro DTLB misses,
131 * micro ITLB misses and main TLB misses. There isn't an event
132 * for TLB misses, so use the micro misses here and if users
133 * want the main TLB misses they can use a raw counter.
134 */
135 [C(OP_READ)] = {
136 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
137 [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
138 },
139 [C(OP_WRITE)] = {
140 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
141 [C(RESULT_MISS)] = ARMV6_PERFCTR_DTLB_MISS,
142 },
143 [C(OP_PREFETCH)] = {
144 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
145 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
146 },
147 },
148 [C(ITLB)] = {
149 [C(OP_READ)] = {
150 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
151 [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
152 },
153 [C(OP_WRITE)] = {
154 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
155 [C(RESULT_MISS)] = ARMV6_PERFCTR_ITLB_MISS,
156 },
157 [C(OP_PREFETCH)] = {
158 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
159 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
160 },
161 },
162 [C(BPU)] = {
163 [C(OP_READ)] = {
164 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
165 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
166 },
167 [C(OP_WRITE)] = {
168 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
169 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
170 },
171 [C(OP_PREFETCH)] = {
172 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
173 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
174 },
175 },
176};
177
178enum armv6mpcore_perf_types {
179 ARMV6MPCORE_PERFCTR_ICACHE_MISS = 0x0,
180 ARMV6MPCORE_PERFCTR_IBUF_STALL = 0x1,
181 ARMV6MPCORE_PERFCTR_DDEP_STALL = 0x2,
182 ARMV6MPCORE_PERFCTR_ITLB_MISS = 0x3,
183 ARMV6MPCORE_PERFCTR_DTLB_MISS = 0x4,
184 ARMV6MPCORE_PERFCTR_BR_EXEC = 0x5,
185 ARMV6MPCORE_PERFCTR_BR_NOTPREDICT = 0x6,
186 ARMV6MPCORE_PERFCTR_BR_MISPREDICT = 0x7,
187 ARMV6MPCORE_PERFCTR_INSTR_EXEC = 0x8,
188 ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS = 0xA,
189 ARMV6MPCORE_PERFCTR_DCACHE_RDMISS = 0xB,
190 ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS = 0xC,
191 ARMV6MPCORE_PERFCTR_DCACHE_WRMISS = 0xD,
192 ARMV6MPCORE_PERFCTR_DCACHE_EVICTION = 0xE,
193 ARMV6MPCORE_PERFCTR_SW_PC_CHANGE = 0xF,
194 ARMV6MPCORE_PERFCTR_MAIN_TLB_MISS = 0x10,
195 ARMV6MPCORE_PERFCTR_EXPL_MEM_ACCESS = 0x11,
196 ARMV6MPCORE_PERFCTR_LSU_FULL_STALL = 0x12,
197 ARMV6MPCORE_PERFCTR_WBUF_DRAINED = 0x13,
198 ARMV6MPCORE_PERFCTR_CPU_CYCLES = 0xFF,
199};
200
201/*
202 * The hardware events that we support. We do support cache operations but
203 * we have harvard caches and no way to combine instruction and data
204 * accesses/misses in hardware.
205 */
206static const unsigned armv6mpcore_perf_map[PERF_COUNT_HW_MAX] = {
207 [PERF_COUNT_HW_CPU_CYCLES] = ARMV6MPCORE_PERFCTR_CPU_CYCLES,
208 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_INSTR_EXEC,
209 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
210 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
211 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV6MPCORE_PERFCTR_BR_EXEC,
212 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV6MPCORE_PERFCTR_BR_MISPREDICT,
213 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
214};
215
216static const unsigned armv6mpcore_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
217 [PERF_COUNT_HW_CACHE_OP_MAX]
218 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
219 [C(L1D)] = {
220 [C(OP_READ)] = {
221 [C(RESULT_ACCESS)] =
222 ARMV6MPCORE_PERFCTR_DCACHE_RDACCESS,
223 [C(RESULT_MISS)] =
224 ARMV6MPCORE_PERFCTR_DCACHE_RDMISS,
225 },
226 [C(OP_WRITE)] = {
227 [C(RESULT_ACCESS)] =
228 ARMV6MPCORE_PERFCTR_DCACHE_WRACCESS,
229 [C(RESULT_MISS)] =
230 ARMV6MPCORE_PERFCTR_DCACHE_WRMISS,
231 },
232 [C(OP_PREFETCH)] = {
233 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
234 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
235 },
236 },
237 [C(L1I)] = {
238 [C(OP_READ)] = {
239 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
240 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
241 },
242 [C(OP_WRITE)] = {
243 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
244 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ICACHE_MISS,
245 },
246 [C(OP_PREFETCH)] = {
247 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
248 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
249 },
250 },
251 [C(LL)] = {
252 [C(OP_READ)] = {
253 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
254 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
255 },
256 [C(OP_WRITE)] = {
257 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
258 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
259 },
260 [C(OP_PREFETCH)] = {
261 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
262 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
263 },
264 },
265 [C(DTLB)] = {
266 /*
267 * The ARM performance counters can count micro DTLB misses,
268 * micro ITLB misses and main TLB misses. There isn't an event
269 * for TLB misses, so use the micro misses here and if users
270 * want the main TLB misses they can use a raw counter.
271 */
272 [C(OP_READ)] = {
273 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
274 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
275 },
276 [C(OP_WRITE)] = {
277 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
278 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_DTLB_MISS,
279 },
280 [C(OP_PREFETCH)] = {
281 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
282 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
283 },
284 },
285 [C(ITLB)] = {
286 [C(OP_READ)] = {
287 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
288 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
289 },
290 [C(OP_WRITE)] = {
291 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
292 [C(RESULT_MISS)] = ARMV6MPCORE_PERFCTR_ITLB_MISS,
293 },
294 [C(OP_PREFETCH)] = {
295 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
296 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
297 },
298 },
299 [C(BPU)] = {
300 [C(OP_READ)] = {
301 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
302 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
303 },
304 [C(OP_WRITE)] = {
305 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
306 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
307 },
308 [C(OP_PREFETCH)] = {
309 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
310 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
311 },
312 },
313};
314
315static inline unsigned long
316armv6_pmcr_read(void)
317{
318 u32 val;
319 asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r"(val));
320 return val;
321}
322
323static inline void
324armv6_pmcr_write(unsigned long val)
325{
326 asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r"(val));
327}
328
329#define ARMV6_PMCR_ENABLE (1 << 0)
330#define ARMV6_PMCR_CTR01_RESET (1 << 1)
331#define ARMV6_PMCR_CCOUNT_RESET (1 << 2)
332#define ARMV6_PMCR_CCOUNT_DIV (1 << 3)
333#define ARMV6_PMCR_COUNT0_IEN (1 << 4)
334#define ARMV6_PMCR_COUNT1_IEN (1 << 5)
335#define ARMV6_PMCR_CCOUNT_IEN (1 << 6)
336#define ARMV6_PMCR_COUNT0_OVERFLOW (1 << 8)
337#define ARMV6_PMCR_COUNT1_OVERFLOW (1 << 9)
338#define ARMV6_PMCR_CCOUNT_OVERFLOW (1 << 10)
339#define ARMV6_PMCR_EVT_COUNT0_SHIFT 20
340#define ARMV6_PMCR_EVT_COUNT0_MASK (0xFF << ARMV6_PMCR_EVT_COUNT0_SHIFT)
341#define ARMV6_PMCR_EVT_COUNT1_SHIFT 12
342#define ARMV6_PMCR_EVT_COUNT1_MASK (0xFF << ARMV6_PMCR_EVT_COUNT1_SHIFT)
343
344#define ARMV6_PMCR_OVERFLOWED_MASK \
345 (ARMV6_PMCR_COUNT0_OVERFLOW | ARMV6_PMCR_COUNT1_OVERFLOW | \
346 ARMV6_PMCR_CCOUNT_OVERFLOW)
347
348static inline int
349armv6_pmcr_has_overflowed(unsigned long pmcr)
350{
351 return pmcr & ARMV6_PMCR_OVERFLOWED_MASK;
352}
353
354static inline int
355armv6_pmcr_counter_has_overflowed(unsigned long pmcr,
356 enum armv6_counters counter)
357{
358 int ret = 0;
359
360 if (ARMV6_CYCLE_COUNTER == counter)
361 ret = pmcr & ARMV6_PMCR_CCOUNT_OVERFLOW;
362 else if (ARMV6_COUNTER0 == counter)
363 ret = pmcr & ARMV6_PMCR_COUNT0_OVERFLOW;
364 else if (ARMV6_COUNTER1 == counter)
365 ret = pmcr & ARMV6_PMCR_COUNT1_OVERFLOW;
366 else
367 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
368
369 return ret;
370}
371
372static inline u32
373armv6pmu_read_counter(int counter)
374{
375 unsigned long value = 0;
376
377 if (ARMV6_CYCLE_COUNTER == counter)
378 asm volatile("mrc p15, 0, %0, c15, c12, 1" : "=r"(value));
379 else if (ARMV6_COUNTER0 == counter)
380 asm volatile("mrc p15, 0, %0, c15, c12, 2" : "=r"(value));
381 else if (ARMV6_COUNTER1 == counter)
382 asm volatile("mrc p15, 0, %0, c15, c12, 3" : "=r"(value));
383 else
384 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
385
386 return value;
387}
388
389static inline void
390armv6pmu_write_counter(int counter,
391 u32 value)
392{
393 if (ARMV6_CYCLE_COUNTER == counter)
394 asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r"(value));
395 else if (ARMV6_COUNTER0 == counter)
396 asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r"(value));
397 else if (ARMV6_COUNTER1 == counter)
398 asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r"(value));
399 else
400 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
401}
402
403static void
404armv6pmu_enable_event(struct hw_perf_event *hwc,
405 int idx)
406{
407 unsigned long val, mask, evt, flags;
408
409 if (ARMV6_CYCLE_COUNTER == idx) {
410 mask = 0;
411 evt = ARMV6_PMCR_CCOUNT_IEN;
412 } else if (ARMV6_COUNTER0 == idx) {
413 mask = ARMV6_PMCR_EVT_COUNT0_MASK;
414 evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT0_SHIFT) |
415 ARMV6_PMCR_COUNT0_IEN;
416 } else if (ARMV6_COUNTER1 == idx) {
417 mask = ARMV6_PMCR_EVT_COUNT1_MASK;
418 evt = (hwc->config_base << ARMV6_PMCR_EVT_COUNT1_SHIFT) |
419 ARMV6_PMCR_COUNT1_IEN;
420 } else {
421 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
422 return;
423 }
424
425 /*
426 * Mask out the current event and set the counter to count the event
427 * that we're interested in.
428 */
429 raw_spin_lock_irqsave(&pmu_lock, flags);
430 val = armv6_pmcr_read();
431 val &= ~mask;
432 val |= evt;
433 armv6_pmcr_write(val);
434 raw_spin_unlock_irqrestore(&pmu_lock, flags);
435}
436
437static irqreturn_t
438armv6pmu_handle_irq(int irq_num,
439 void *dev)
440{
441 unsigned long pmcr = armv6_pmcr_read();
442 struct perf_sample_data data;
443 struct cpu_hw_events *cpuc;
444 struct pt_regs *regs;
445 int idx;
446
447 if (!armv6_pmcr_has_overflowed(pmcr))
448 return IRQ_NONE;
449
450 regs = get_irq_regs();
451
452 /*
453 * The interrupts are cleared by writing the overflow flags back to
454 * the control register. All of the other bits don't have any effect
455 * if they are rewritten, so write the whole value back.
456 */
457 armv6_pmcr_write(pmcr);
458
459 perf_sample_data_init(&data, 0);
460
461 cpuc = &__get_cpu_var(cpu_hw_events);
462 for (idx = 0; idx <= armpmu->num_events; ++idx) {
463 struct perf_event *event = cpuc->events[idx];
464 struct hw_perf_event *hwc;
465
466 if (!test_bit(idx, cpuc->active_mask))
467 continue;
468
469 /*
470 * We have a single interrupt for all counters. Check that
471 * each counter has overflowed before we process it.
472 */
473 if (!armv6_pmcr_counter_has_overflowed(pmcr, idx))
474 continue;
475
476 hwc = &event->hw;
477 armpmu_event_update(event, hwc, idx, 1);
478 data.period = event->hw.last_period;
479 if (!armpmu_event_set_period(event, hwc, idx))
480 continue;
481
482 if (perf_event_overflow(event, 0, &data, regs))
483 armpmu->disable(hwc, idx);
484 }
485
486 /*
487 * Handle the pending perf events.
488 *
489 * Note: this call *must* be run with interrupts disabled. For
490 * platforms that can have the PMU interrupts raised as an NMI, this
491 * will not work.
492 */
493 irq_work_run();
494
495 return IRQ_HANDLED;
496}
497
498static void
499armv6pmu_start(void)
500{
501 unsigned long flags, val;
502
503 raw_spin_lock_irqsave(&pmu_lock, flags);
504 val = armv6_pmcr_read();
505 val |= ARMV6_PMCR_ENABLE;
506 armv6_pmcr_write(val);
507 raw_spin_unlock_irqrestore(&pmu_lock, flags);
508}
509
510static void
511armv6pmu_stop(void)
512{
513 unsigned long flags, val;
514
515 raw_spin_lock_irqsave(&pmu_lock, flags);
516 val = armv6_pmcr_read();
517 val &= ~ARMV6_PMCR_ENABLE;
518 armv6_pmcr_write(val);
519 raw_spin_unlock_irqrestore(&pmu_lock, flags);
520}
521
522static int
523armv6pmu_get_event_idx(struct cpu_hw_events *cpuc,
524 struct hw_perf_event *event)
525{
526 /* Always place a cycle counter into the cycle counter. */
527 if (ARMV6_PERFCTR_CPU_CYCLES == event->config_base) {
528 if (test_and_set_bit(ARMV6_CYCLE_COUNTER, cpuc->used_mask))
529 return -EAGAIN;
530
531 return ARMV6_CYCLE_COUNTER;
532 } else {
533 /*
534 * For anything other than a cycle counter, try and use
535 * counter0 and counter1.
536 */
537 if (!test_and_set_bit(ARMV6_COUNTER1, cpuc->used_mask))
538 return ARMV6_COUNTER1;
539
540 if (!test_and_set_bit(ARMV6_COUNTER0, cpuc->used_mask))
541 return ARMV6_COUNTER0;
542
543 /* The counters are all in use. */
544 return -EAGAIN;
545 }
546}
547
548static void
549armv6pmu_disable_event(struct hw_perf_event *hwc,
550 int idx)
551{
552 unsigned long val, mask, evt, flags;
553
554 if (ARMV6_CYCLE_COUNTER == idx) {
555 mask = ARMV6_PMCR_CCOUNT_IEN;
556 evt = 0;
557 } else if (ARMV6_COUNTER0 == idx) {
558 mask = ARMV6_PMCR_COUNT0_IEN | ARMV6_PMCR_EVT_COUNT0_MASK;
559 evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT0_SHIFT;
560 } else if (ARMV6_COUNTER1 == idx) {
561 mask = ARMV6_PMCR_COUNT1_IEN | ARMV6_PMCR_EVT_COUNT1_MASK;
562 evt = ARMV6_PERFCTR_NOP << ARMV6_PMCR_EVT_COUNT1_SHIFT;
563 } else {
564 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
565 return;
566 }
567
568 /*
569 * Mask out the current event and set the counter to count the number
570 * of ETM bus signal assertion cycles. The external reporting should
571 * be disabled and so this should never increment.
572 */
573 raw_spin_lock_irqsave(&pmu_lock, flags);
574 val = armv6_pmcr_read();
575 val &= ~mask;
576 val |= evt;
577 armv6_pmcr_write(val);
578 raw_spin_unlock_irqrestore(&pmu_lock, flags);
579}
580
581static void
582armv6mpcore_pmu_disable_event(struct hw_perf_event *hwc,
583 int idx)
584{
585 unsigned long val, mask, flags, evt = 0;
586
587 if (ARMV6_CYCLE_COUNTER == idx) {
588 mask = ARMV6_PMCR_CCOUNT_IEN;
589 } else if (ARMV6_COUNTER0 == idx) {
590 mask = ARMV6_PMCR_COUNT0_IEN;
591 } else if (ARMV6_COUNTER1 == idx) {
592 mask = ARMV6_PMCR_COUNT1_IEN;
593 } else {
594 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
595 return;
596 }
597
598 /*
599 * Unlike UP ARMv6, we don't have a way of stopping the counters. We
600 * simply disable the interrupt reporting.
601 */
602 raw_spin_lock_irqsave(&pmu_lock, flags);
603 val = armv6_pmcr_read();
604 val &= ~mask;
605 val |= evt;
606 armv6_pmcr_write(val);
607 raw_spin_unlock_irqrestore(&pmu_lock, flags);
608}
609
610static const struct arm_pmu armv6pmu = {
611 .id = ARM_PERF_PMU_ID_V6,
612 .name = "v6",
613 .handle_irq = armv6pmu_handle_irq,
614 .enable = armv6pmu_enable_event,
615 .disable = armv6pmu_disable_event,
616 .read_counter = armv6pmu_read_counter,
617 .write_counter = armv6pmu_write_counter,
618 .get_event_idx = armv6pmu_get_event_idx,
619 .start = armv6pmu_start,
620 .stop = armv6pmu_stop,
621 .cache_map = &armv6_perf_cache_map,
622 .event_map = &armv6_perf_map,
623 .raw_event_mask = 0xFF,
624 .num_events = 3,
625 .max_period = (1LLU << 32) - 1,
626};
627
628static const struct arm_pmu *__init armv6pmu_init(void)
629{
630 return &armv6pmu;
631}
632
633/*
634 * ARMv6mpcore is almost identical to single core ARMv6 with the exception
635 * that some of the events have different enumerations and that there is no
636 * *hack* to stop the programmable counters. To stop the counters we simply
637 * disable the interrupt reporting and update the event. When unthrottling we
638 * reset the period and enable the interrupt reporting.
639 */
640static const struct arm_pmu armv6mpcore_pmu = {
641 .id = ARM_PERF_PMU_ID_V6MP,
642 .name = "v6mpcore",
643 .handle_irq = armv6pmu_handle_irq,
644 .enable = armv6pmu_enable_event,
645 .disable = armv6mpcore_pmu_disable_event,
646 .read_counter = armv6pmu_read_counter,
647 .write_counter = armv6pmu_write_counter,
648 .get_event_idx = armv6pmu_get_event_idx,
649 .start = armv6pmu_start,
650 .stop = armv6pmu_stop,
651 .cache_map = &armv6mpcore_perf_cache_map,
652 .event_map = &armv6mpcore_perf_map,
653 .raw_event_mask = 0xFF,
654 .num_events = 3,
655 .max_period = (1LLU << 32) - 1,
656};
657
658static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
659{
660 return &armv6mpcore_pmu;
661}
662#else
663static const struct arm_pmu *__init armv6pmu_init(void)
664{
665 return NULL;
666}
667
668static const struct arm_pmu *__init armv6mpcore_pmu_init(void)
669{
670 return NULL;
671}
672#endif /* CONFIG_CPU_V6 || CONFIG_CPU_V6K */
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
new file mode 100644
index 000000000000..4960686afb58
--- /dev/null
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -0,0 +1,918 @@
1/*
2 * ARMv7 Cortex-A8 and Cortex-A9 Performance Events handling code.
3 *
4 * ARMv7 support: Jean Pihet <jpihet@mvista.com>
5 * 2010 (c) MontaVista Software, LLC.
6 *
7 * Copied from ARMv6 code, with the low level code inspired
8 * by the ARMv7 Oprofile code.
9 *
10 * Cortex-A8 has up to 4 configurable performance counters and
11 * a single cycle counter.
12 * Cortex-A9 has up to 31 configurable performance counters and
13 * a single cycle counter.
14 *
15 * All counters can be enabled/disabled and IRQ masked separately. The cycle
16 * counter and all 4 performance counters together can be reset separately.
17 */
18
19#ifdef CONFIG_CPU_V7
20/* Common ARMv7 event types */
21enum armv7_perf_types {
22 ARMV7_PERFCTR_PMNC_SW_INCR = 0x00,
23 ARMV7_PERFCTR_IFETCH_MISS = 0x01,
24 ARMV7_PERFCTR_ITLB_MISS = 0x02,
25 ARMV7_PERFCTR_DCACHE_REFILL = 0x03,
26 ARMV7_PERFCTR_DCACHE_ACCESS = 0x04,
27 ARMV7_PERFCTR_DTLB_REFILL = 0x05,
28 ARMV7_PERFCTR_DREAD = 0x06,
29 ARMV7_PERFCTR_DWRITE = 0x07,
30
31 ARMV7_PERFCTR_EXC_TAKEN = 0x09,
32 ARMV7_PERFCTR_EXC_EXECUTED = 0x0A,
33 ARMV7_PERFCTR_CID_WRITE = 0x0B,
34 /* ARMV7_PERFCTR_PC_WRITE is equivalent to HW_BRANCH_INSTRUCTIONS.
35 * It counts:
36 * - all branch instructions,
37 * - instructions that explicitly write the PC,
38 * - exception generating instructions.
39 */
40 ARMV7_PERFCTR_PC_WRITE = 0x0C,
41 ARMV7_PERFCTR_PC_IMM_BRANCH = 0x0D,
42 ARMV7_PERFCTR_UNALIGNED_ACCESS = 0x0F,
43 ARMV7_PERFCTR_PC_BRANCH_MIS_PRED = 0x10,
44 ARMV7_PERFCTR_CLOCK_CYCLES = 0x11,
45
46 ARMV7_PERFCTR_PC_BRANCH_MIS_USED = 0x12,
47
48 ARMV7_PERFCTR_CPU_CYCLES = 0xFF
49};
50
51/* ARMv7 Cortex-A8 specific event types */
52enum armv7_a8_perf_types {
53 ARMV7_PERFCTR_INSTR_EXECUTED = 0x08,
54
55 ARMV7_PERFCTR_PC_PROC_RETURN = 0x0E,
56
57 ARMV7_PERFCTR_WRITE_BUFFER_FULL = 0x40,
58 ARMV7_PERFCTR_L2_STORE_MERGED = 0x41,
59 ARMV7_PERFCTR_L2_STORE_BUFF = 0x42,
60 ARMV7_PERFCTR_L2_ACCESS = 0x43,
61 ARMV7_PERFCTR_L2_CACH_MISS = 0x44,
62 ARMV7_PERFCTR_AXI_READ_CYCLES = 0x45,
63 ARMV7_PERFCTR_AXI_WRITE_CYCLES = 0x46,
64 ARMV7_PERFCTR_MEMORY_REPLAY = 0x47,
65 ARMV7_PERFCTR_UNALIGNED_ACCESS_REPLAY = 0x48,
66 ARMV7_PERFCTR_L1_DATA_MISS = 0x49,
67 ARMV7_PERFCTR_L1_INST_MISS = 0x4A,
68 ARMV7_PERFCTR_L1_DATA_COLORING = 0x4B,
69 ARMV7_PERFCTR_L1_NEON_DATA = 0x4C,
70 ARMV7_PERFCTR_L1_NEON_CACH_DATA = 0x4D,
71 ARMV7_PERFCTR_L2_NEON = 0x4E,
72 ARMV7_PERFCTR_L2_NEON_HIT = 0x4F,
73 ARMV7_PERFCTR_L1_INST = 0x50,
74 ARMV7_PERFCTR_PC_RETURN_MIS_PRED = 0x51,
75 ARMV7_PERFCTR_PC_BRANCH_FAILED = 0x52,
76 ARMV7_PERFCTR_PC_BRANCH_TAKEN = 0x53,
77 ARMV7_PERFCTR_PC_BRANCH_EXECUTED = 0x54,
78 ARMV7_PERFCTR_OP_EXECUTED = 0x55,
79 ARMV7_PERFCTR_CYCLES_INST_STALL = 0x56,
80 ARMV7_PERFCTR_CYCLES_INST = 0x57,
81 ARMV7_PERFCTR_CYCLES_NEON_DATA_STALL = 0x58,
82 ARMV7_PERFCTR_CYCLES_NEON_INST_STALL = 0x59,
83 ARMV7_PERFCTR_NEON_CYCLES = 0x5A,
84
85 ARMV7_PERFCTR_PMU0_EVENTS = 0x70,
86 ARMV7_PERFCTR_PMU1_EVENTS = 0x71,
87 ARMV7_PERFCTR_PMU_EVENTS = 0x72,
88};
89
90/* ARMv7 Cortex-A9 specific event types */
91enum armv7_a9_perf_types {
92 ARMV7_PERFCTR_JAVA_HW_BYTECODE_EXEC = 0x40,
93 ARMV7_PERFCTR_JAVA_SW_BYTECODE_EXEC = 0x41,
94 ARMV7_PERFCTR_JAZELLE_BRANCH_EXEC = 0x42,
95
96 ARMV7_PERFCTR_COHERENT_LINE_MISS = 0x50,
97 ARMV7_PERFCTR_COHERENT_LINE_HIT = 0x51,
98
99 ARMV7_PERFCTR_ICACHE_DEP_STALL_CYCLES = 0x60,
100 ARMV7_PERFCTR_DCACHE_DEP_STALL_CYCLES = 0x61,
101 ARMV7_PERFCTR_TLB_MISS_DEP_STALL_CYCLES = 0x62,
102 ARMV7_PERFCTR_STREX_EXECUTED_PASSED = 0x63,
103 ARMV7_PERFCTR_STREX_EXECUTED_FAILED = 0x64,
104 ARMV7_PERFCTR_DATA_EVICTION = 0x65,
105 ARMV7_PERFCTR_ISSUE_STAGE_NO_INST = 0x66,
106 ARMV7_PERFCTR_ISSUE_STAGE_EMPTY = 0x67,
107 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE = 0x68,
108
109 ARMV7_PERFCTR_PREDICTABLE_FUNCT_RETURNS = 0x6E,
110
111 ARMV7_PERFCTR_MAIN_UNIT_EXECUTED_INST = 0x70,
112 ARMV7_PERFCTR_SECOND_UNIT_EXECUTED_INST = 0x71,
113 ARMV7_PERFCTR_LD_ST_UNIT_EXECUTED_INST = 0x72,
114 ARMV7_PERFCTR_FP_EXECUTED_INST = 0x73,
115 ARMV7_PERFCTR_NEON_EXECUTED_INST = 0x74,
116
117 ARMV7_PERFCTR_PLD_FULL_DEP_STALL_CYCLES = 0x80,
118 ARMV7_PERFCTR_DATA_WR_DEP_STALL_CYCLES = 0x81,
119 ARMV7_PERFCTR_ITLB_MISS_DEP_STALL_CYCLES = 0x82,
120 ARMV7_PERFCTR_DTLB_MISS_DEP_STALL_CYCLES = 0x83,
121 ARMV7_PERFCTR_MICRO_ITLB_MISS_DEP_STALL_CYCLES = 0x84,
122 ARMV7_PERFCTR_MICRO_DTLB_MISS_DEP_STALL_CYCLES = 0x85,
123 ARMV7_PERFCTR_DMB_DEP_STALL_CYCLES = 0x86,
124
125 ARMV7_PERFCTR_INTGR_CLK_ENABLED_CYCLES = 0x8A,
126 ARMV7_PERFCTR_DATA_ENGINE_CLK_EN_CYCLES = 0x8B,
127
128 ARMV7_PERFCTR_ISB_INST = 0x90,
129 ARMV7_PERFCTR_DSB_INST = 0x91,
130 ARMV7_PERFCTR_DMB_INST = 0x92,
131 ARMV7_PERFCTR_EXT_INTERRUPTS = 0x93,
132
133 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_COMPLETED = 0xA0,
134 ARMV7_PERFCTR_PLE_CACHE_LINE_RQST_SKIPPED = 0xA1,
135 ARMV7_PERFCTR_PLE_FIFO_FLUSH = 0xA2,
136 ARMV7_PERFCTR_PLE_RQST_COMPLETED = 0xA3,
137 ARMV7_PERFCTR_PLE_FIFO_OVERFLOW = 0xA4,
138 ARMV7_PERFCTR_PLE_RQST_PROG = 0xA5
139};
140
141/*
142 * Cortex-A8 HW events mapping
143 *
144 * The hardware events that we support. We do support cache operations but
145 * we have harvard caches and no way to combine instruction and data
146 * accesses/misses in hardware.
147 */
148static const unsigned armv7_a8_perf_map[PERF_COUNT_HW_MAX] = {
149 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
150 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
151 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
152 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
153 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
154 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
155 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
156};
157
158static const unsigned armv7_a8_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
159 [PERF_COUNT_HW_CACHE_OP_MAX]
160 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
161 [C(L1D)] = {
162 /*
163 * The performance counters don't differentiate between read
164 * and write accesses/misses so this isn't strictly correct,
165 * but it's the best we can do. Writes and reads get
166 * combined.
167 */
168 [C(OP_READ)] = {
169 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
170 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
171 },
172 [C(OP_WRITE)] = {
173 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
174 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
175 },
176 [C(OP_PREFETCH)] = {
177 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
178 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
179 },
180 },
181 [C(L1I)] = {
182 [C(OP_READ)] = {
183 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
184 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
185 },
186 [C(OP_WRITE)] = {
187 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_INST,
188 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_INST_MISS,
189 },
190 [C(OP_PREFETCH)] = {
191 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
192 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
193 },
194 },
195 [C(LL)] = {
196 [C(OP_READ)] = {
197 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
198 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
199 },
200 [C(OP_WRITE)] = {
201 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L2_ACCESS,
202 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACH_MISS,
203 },
204 [C(OP_PREFETCH)] = {
205 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
206 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
207 },
208 },
209 [C(DTLB)] = {
210 /*
211 * Only ITLB misses and DTLB refills are supported.
212 * If users want the DTLB refills misses a raw counter
213 * must be used.
214 */
215 [C(OP_READ)] = {
216 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
217 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
218 },
219 [C(OP_WRITE)] = {
220 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
221 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
222 },
223 [C(OP_PREFETCH)] = {
224 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
225 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
226 },
227 },
228 [C(ITLB)] = {
229 [C(OP_READ)] = {
230 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
231 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
232 },
233 [C(OP_WRITE)] = {
234 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
235 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
236 },
237 [C(OP_PREFETCH)] = {
238 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
239 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
240 },
241 },
242 [C(BPU)] = {
243 [C(OP_READ)] = {
244 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
245 [C(RESULT_MISS)]
246 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
247 },
248 [C(OP_WRITE)] = {
249 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
250 [C(RESULT_MISS)]
251 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
252 },
253 [C(OP_PREFETCH)] = {
254 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
255 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
256 },
257 },
258};
259
260/*
261 * Cortex-A9 HW events mapping
262 */
263static const unsigned armv7_a9_perf_map[PERF_COUNT_HW_MAX] = {
264 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
265 [PERF_COUNT_HW_INSTRUCTIONS] =
266 ARMV7_PERFCTR_INST_OUT_OF_RENAME_STAGE,
267 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_COHERENT_LINE_HIT,
268 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_COHERENT_LINE_MISS,
269 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
270 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
271 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
272};
273
274static const unsigned armv7_a9_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
275 [PERF_COUNT_HW_CACHE_OP_MAX]
276 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
277 [C(L1D)] = {
278 /*
279 * The performance counters don't differentiate between read
280 * and write accesses/misses so this isn't strictly correct,
281 * but it's the best we can do. Writes and reads get
282 * combined.
283 */
284 [C(OP_READ)] = {
285 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
286 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
287 },
288 [C(OP_WRITE)] = {
289 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_DCACHE_ACCESS,
290 [C(RESULT_MISS)] = ARMV7_PERFCTR_DCACHE_REFILL,
291 },
292 [C(OP_PREFETCH)] = {
293 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
294 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
295 },
296 },
297 [C(L1I)] = {
298 [C(OP_READ)] = {
299 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
300 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
301 },
302 [C(OP_WRITE)] = {
303 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
304 [C(RESULT_MISS)] = ARMV7_PERFCTR_IFETCH_MISS,
305 },
306 [C(OP_PREFETCH)] = {
307 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
308 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
309 },
310 },
311 [C(LL)] = {
312 [C(OP_READ)] = {
313 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
314 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
315 },
316 [C(OP_WRITE)] = {
317 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
318 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
319 },
320 [C(OP_PREFETCH)] = {
321 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
322 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
323 },
324 },
325 [C(DTLB)] = {
326 /*
327 * Only ITLB misses and DTLB refills are supported.
328 * If users want the DTLB refills misses a raw counter
329 * must be used.
330 */
331 [C(OP_READ)] = {
332 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
333 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
334 },
335 [C(OP_WRITE)] = {
336 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
337 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
338 },
339 [C(OP_PREFETCH)] = {
340 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
341 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
342 },
343 },
344 [C(ITLB)] = {
345 [C(OP_READ)] = {
346 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
347 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
348 },
349 [C(OP_WRITE)] = {
350 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
351 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_MISS,
352 },
353 [C(OP_PREFETCH)] = {
354 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
355 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
356 },
357 },
358 [C(BPU)] = {
359 [C(OP_READ)] = {
360 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
361 [C(RESULT_MISS)]
362 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
363 },
364 [C(OP_WRITE)] = {
365 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_WRITE,
366 [C(RESULT_MISS)]
367 = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
368 },
369 [C(OP_PREFETCH)] = {
370 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
371 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
372 },
373 },
374};
375
376/*
377 * Perf Events counters
378 */
379enum armv7_counters {
380 ARMV7_CYCLE_COUNTER = 1, /* Cycle counter */
381 ARMV7_COUNTER0 = 2, /* First event counter */
382};
383
384/*
385 * The cycle counter is ARMV7_CYCLE_COUNTER.
386 * The first event counter is ARMV7_COUNTER0.
387 * The last event counter is (ARMV7_COUNTER0 + armpmu->num_events - 1).
388 */
389#define ARMV7_COUNTER_LAST (ARMV7_COUNTER0 + armpmu->num_events - 1)
390
391/*
392 * ARMv7 low level PMNC access
393 */
394
395/*
396 * Per-CPU PMNC: config reg
397 */
398#define ARMV7_PMNC_E (1 << 0) /* Enable all counters */
399#define ARMV7_PMNC_P (1 << 1) /* Reset all counters */
400#define ARMV7_PMNC_C (1 << 2) /* Cycle counter reset */
401#define ARMV7_PMNC_D (1 << 3) /* CCNT counts every 64th cpu cycle */
402#define ARMV7_PMNC_X (1 << 4) /* Export to ETM */
403#define ARMV7_PMNC_DP (1 << 5) /* Disable CCNT if non-invasive debug*/
404#define ARMV7_PMNC_N_SHIFT 11 /* Number of counters supported */
405#define ARMV7_PMNC_N_MASK 0x1f
406#define ARMV7_PMNC_MASK 0x3f /* Mask for writable bits */
407
408/*
409 * Available counters
410 */
411#define ARMV7_CNT0 0 /* First event counter */
412#define ARMV7_CCNT 31 /* Cycle counter */
413
414/* Perf Event to low level counters mapping */
415#define ARMV7_EVENT_CNT_TO_CNTx (ARMV7_COUNTER0 - ARMV7_CNT0)
416
417/*
418 * CNTENS: counters enable reg
419 */
420#define ARMV7_CNTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
421#define ARMV7_CNTENS_C (1 << ARMV7_CCNT)
422
423/*
424 * CNTENC: counters disable reg
425 */
426#define ARMV7_CNTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
427#define ARMV7_CNTENC_C (1 << ARMV7_CCNT)
428
429/*
430 * INTENS: counters overflow interrupt enable reg
431 */
432#define ARMV7_INTENS_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
433#define ARMV7_INTENS_C (1 << ARMV7_CCNT)
434
435/*
436 * INTENC: counters overflow interrupt disable reg
437 */
438#define ARMV7_INTENC_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
439#define ARMV7_INTENC_C (1 << ARMV7_CCNT)
440
441/*
442 * EVTSEL: Event selection reg
443 */
444#define ARMV7_EVTSEL_MASK 0xff /* Mask for writable bits */
445
446/*
447 * SELECT: Counter selection reg
448 */
449#define ARMV7_SELECT_MASK 0x1f /* Mask for writable bits */
450
451/*
452 * FLAG: counters overflow flag status reg
453 */
454#define ARMV7_FLAG_P(idx) (1 << (idx - ARMV7_EVENT_CNT_TO_CNTx))
455#define ARMV7_FLAG_C (1 << ARMV7_CCNT)
456#define ARMV7_FLAG_MASK 0xffffffff /* Mask for writable bits */
457#define ARMV7_OVERFLOWED_MASK ARMV7_FLAG_MASK
458
459static inline unsigned long armv7_pmnc_read(void)
460{
461 u32 val;
462 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
463 return val;
464}
465
466static inline void armv7_pmnc_write(unsigned long val)
467{
468 val &= ARMV7_PMNC_MASK;
469 isb();
470 asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
471}
472
473static inline int armv7_pmnc_has_overflowed(unsigned long pmnc)
474{
475 return pmnc & ARMV7_OVERFLOWED_MASK;
476}
477
478static inline int armv7_pmnc_counter_has_overflowed(unsigned long pmnc,
479 enum armv7_counters counter)
480{
481 int ret = 0;
482
483 if (counter == ARMV7_CYCLE_COUNTER)
484 ret = pmnc & ARMV7_FLAG_C;
485 else if ((counter >= ARMV7_COUNTER0) && (counter <= ARMV7_COUNTER_LAST))
486 ret = pmnc & ARMV7_FLAG_P(counter);
487 else
488 pr_err("CPU%u checking wrong counter %d overflow status\n",
489 smp_processor_id(), counter);
490
491 return ret;
492}
493
494static inline int armv7_pmnc_select_counter(unsigned int idx)
495{
496 u32 val;
497
498 if ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST)) {
499 pr_err("CPU%u selecting wrong PMNC counter"
500 " %d\n", smp_processor_id(), idx);
501 return -1;
502 }
503
504 val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
505 asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
506 isb();
507
508 return idx;
509}
510
511static inline u32 armv7pmu_read_counter(int idx)
512{
513 unsigned long value = 0;
514
515 if (idx == ARMV7_CYCLE_COUNTER)
516 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (value));
517 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
518 if (armv7_pmnc_select_counter(idx) == idx)
519 asm volatile("mrc p15, 0, %0, c9, c13, 2"
520 : "=r" (value));
521 } else
522 pr_err("CPU%u reading wrong counter %d\n",
523 smp_processor_id(), idx);
524
525 return value;
526}
527
528static inline void armv7pmu_write_counter(int idx, u32 value)
529{
530 if (idx == ARMV7_CYCLE_COUNTER)
531 asm volatile("mcr p15, 0, %0, c9, c13, 0" : : "r" (value));
532 else if ((idx >= ARMV7_COUNTER0) && (idx <= ARMV7_COUNTER_LAST)) {
533 if (armv7_pmnc_select_counter(idx) == idx)
534 asm volatile("mcr p15, 0, %0, c9, c13, 2"
535 : : "r" (value));
536 } else
537 pr_err("CPU%u writing wrong counter %d\n",
538 smp_processor_id(), idx);
539}
540
541static inline void armv7_pmnc_write_evtsel(unsigned int idx, u32 val)
542{
543 if (armv7_pmnc_select_counter(idx) == idx) {
544 val &= ARMV7_EVTSEL_MASK;
545 asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r" (val));
546 }
547}
548
549static inline u32 armv7_pmnc_enable_counter(unsigned int idx)
550{
551 u32 val;
552
553 if ((idx != ARMV7_CYCLE_COUNTER) &&
554 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
555 pr_err("CPU%u enabling wrong PMNC counter"
556 " %d\n", smp_processor_id(), idx);
557 return -1;
558 }
559
560 if (idx == ARMV7_CYCLE_COUNTER)
561 val = ARMV7_CNTENS_C;
562 else
563 val = ARMV7_CNTENS_P(idx);
564
565 asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
566
567 return idx;
568}
569
570static inline u32 armv7_pmnc_disable_counter(unsigned int idx)
571{
572 u32 val;
573
574
575 if ((idx != ARMV7_CYCLE_COUNTER) &&
576 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
577 pr_err("CPU%u disabling wrong PMNC counter"
578 " %d\n", smp_processor_id(), idx);
579 return -1;
580 }
581
582 if (idx == ARMV7_CYCLE_COUNTER)
583 val = ARMV7_CNTENC_C;
584 else
585 val = ARMV7_CNTENC_P(idx);
586
587 asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
588
589 return idx;
590}
591
592static inline u32 armv7_pmnc_enable_intens(unsigned int idx)
593{
594 u32 val;
595
596 if ((idx != ARMV7_CYCLE_COUNTER) &&
597 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
598 pr_err("CPU%u enabling wrong PMNC counter"
599 " interrupt enable %d\n", smp_processor_id(), idx);
600 return -1;
601 }
602
603 if (idx == ARMV7_CYCLE_COUNTER)
604 val = ARMV7_INTENS_C;
605 else
606 val = ARMV7_INTENS_P(idx);
607
608 asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (val));
609
610 return idx;
611}
612
613static inline u32 armv7_pmnc_disable_intens(unsigned int idx)
614{
615 u32 val;
616
617 if ((idx != ARMV7_CYCLE_COUNTER) &&
618 ((idx < ARMV7_COUNTER0) || (idx > ARMV7_COUNTER_LAST))) {
619 pr_err("CPU%u disabling wrong PMNC counter"
620 " interrupt enable %d\n", smp_processor_id(), idx);
621 return -1;
622 }
623
624 if (idx == ARMV7_CYCLE_COUNTER)
625 val = ARMV7_INTENC_C;
626 else
627 val = ARMV7_INTENC_P(idx);
628
629 asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (val));
630
631 return idx;
632}
633
634static inline u32 armv7_pmnc_getreset_flags(void)
635{
636 u32 val;
637
638 /* Read */
639 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
640
641 /* Write to clear flags */
642 val &= ARMV7_FLAG_MASK;
643 asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (val));
644
645 return val;
646}
647
648#ifdef DEBUG
649static void armv7_pmnc_dump_regs(void)
650{
651 u32 val;
652 unsigned int cnt;
653
654 printk(KERN_INFO "PMNC registers dump:\n");
655
656 asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r" (val));
657 printk(KERN_INFO "PMNC =0x%08x\n", val);
658
659 asm volatile("mrc p15, 0, %0, c9, c12, 1" : "=r" (val));
660 printk(KERN_INFO "CNTENS=0x%08x\n", val);
661
662 asm volatile("mrc p15, 0, %0, c9, c14, 1" : "=r" (val));
663 printk(KERN_INFO "INTENS=0x%08x\n", val);
664
665 asm volatile("mrc p15, 0, %0, c9, c12, 3" : "=r" (val));
666 printk(KERN_INFO "FLAGS =0x%08x\n", val);
667
668 asm volatile("mrc p15, 0, %0, c9, c12, 5" : "=r" (val));
669 printk(KERN_INFO "SELECT=0x%08x\n", val);
670
671 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val));
672 printk(KERN_INFO "CCNT =0x%08x\n", val);
673
674 for (cnt = ARMV7_COUNTER0; cnt < ARMV7_COUNTER_LAST; cnt++) {
675 armv7_pmnc_select_counter(cnt);
676 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val));
677 printk(KERN_INFO "CNT[%d] count =0x%08x\n",
678 cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
679 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val));
680 printk(KERN_INFO "CNT[%d] evtsel=0x%08x\n",
681 cnt-ARMV7_EVENT_CNT_TO_CNTx, val);
682 }
683}
684#endif
685
686static void armv7pmu_enable_event(struct hw_perf_event *hwc, int idx)
687{
688 unsigned long flags;
689
690 /*
691 * Enable counter and interrupt, and set the counter to count
692 * the event that we're interested in.
693 */
694 raw_spin_lock_irqsave(&pmu_lock, flags);
695
696 /*
697 * Disable counter
698 */
699 armv7_pmnc_disable_counter(idx);
700
701 /*
702 * Set event (if destined for PMNx counters)
703 * We don't need to set the event if it's a cycle count
704 */
705 if (idx != ARMV7_CYCLE_COUNTER)
706 armv7_pmnc_write_evtsel(idx, hwc->config_base);
707
708 /*
709 * Enable interrupt for this counter
710 */
711 armv7_pmnc_enable_intens(idx);
712
713 /*
714 * Enable counter
715 */
716 armv7_pmnc_enable_counter(idx);
717
718 raw_spin_unlock_irqrestore(&pmu_lock, flags);
719}
720
721static void armv7pmu_disable_event(struct hw_perf_event *hwc, int idx)
722{
723 unsigned long flags;
724
725 /*
726 * Disable counter and interrupt
727 */
728 raw_spin_lock_irqsave(&pmu_lock, flags);
729
730 /*
731 * Disable counter
732 */
733 armv7_pmnc_disable_counter(idx);
734
735 /*
736 * Disable interrupt for this counter
737 */
738 armv7_pmnc_disable_intens(idx);
739
740 raw_spin_unlock_irqrestore(&pmu_lock, flags);
741}
742
743static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
744{
745 unsigned long pmnc;
746 struct perf_sample_data data;
747 struct cpu_hw_events *cpuc;
748 struct pt_regs *regs;
749 int idx;
750
751 /*
752 * Get and reset the IRQ flags
753 */
754 pmnc = armv7_pmnc_getreset_flags();
755
756 /*
757 * Did an overflow occur?
758 */
759 if (!armv7_pmnc_has_overflowed(pmnc))
760 return IRQ_NONE;
761
762 /*
763 * Handle the counter(s) overflow(s)
764 */
765 regs = get_irq_regs();
766
767 perf_sample_data_init(&data, 0);
768
769 cpuc = &__get_cpu_var(cpu_hw_events);
770 for (idx = 0; idx <= armpmu->num_events; ++idx) {
771 struct perf_event *event = cpuc->events[idx];
772 struct hw_perf_event *hwc;
773
774 if (!test_bit(idx, cpuc->active_mask))
775 continue;
776
777 /*
778 * We have a single interrupt for all counters. Check that
779 * each counter has overflowed before we process it.
780 */
781 if (!armv7_pmnc_counter_has_overflowed(pmnc, idx))
782 continue;
783
784 hwc = &event->hw;
785 armpmu_event_update(event, hwc, idx, 1);
786 data.period = event->hw.last_period;
787 if (!armpmu_event_set_period(event, hwc, idx))
788 continue;
789
790 if (perf_event_overflow(event, 0, &data, regs))
791 armpmu->disable(hwc, idx);
792 }
793
794 /*
795 * Handle the pending perf events.
796 *
797 * Note: this call *must* be run with interrupts disabled. For
798 * platforms that can have the PMU interrupts raised as an NMI, this
799 * will not work.
800 */
801 irq_work_run();
802
803 return IRQ_HANDLED;
804}
805
806static void armv7pmu_start(void)
807{
808 unsigned long flags;
809
810 raw_spin_lock_irqsave(&pmu_lock, flags);
811 /* Enable all counters */
812 armv7_pmnc_write(armv7_pmnc_read() | ARMV7_PMNC_E);
813 raw_spin_unlock_irqrestore(&pmu_lock, flags);
814}
815
816static void armv7pmu_stop(void)
817{
818 unsigned long flags;
819
820 raw_spin_lock_irqsave(&pmu_lock, flags);
821 /* Disable all counters */
822 armv7_pmnc_write(armv7_pmnc_read() & ~ARMV7_PMNC_E);
823 raw_spin_unlock_irqrestore(&pmu_lock, flags);
824}
825
826static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
827 struct hw_perf_event *event)
828{
829 int idx;
830
831 /* Always place a cycle counter into the cycle counter. */
832 if (event->config_base == ARMV7_PERFCTR_CPU_CYCLES) {
833 if (test_and_set_bit(ARMV7_CYCLE_COUNTER, cpuc->used_mask))
834 return -EAGAIN;
835
836 return ARMV7_CYCLE_COUNTER;
837 } else {
838 /*
839 * For anything other than a cycle counter, try and use
840 * the events counters
841 */
842 for (idx = ARMV7_COUNTER0; idx <= armpmu->num_events; ++idx) {
843 if (!test_and_set_bit(idx, cpuc->used_mask))
844 return idx;
845 }
846
847 /* The counters are all in use. */
848 return -EAGAIN;
849 }
850}
851
852static void armv7pmu_reset(void *info)
853{
854 u32 idx, nb_cnt = armpmu->num_events;
855
856 /* The counter and interrupt enable registers are unknown at reset. */
857 for (idx = 1; idx < nb_cnt; ++idx)
858 armv7pmu_disable_event(NULL, idx);
859
860 /* Initialize & Reset PMNC: C and P bits */
861 armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
862}
863
864static struct arm_pmu armv7pmu = {
865 .handle_irq = armv7pmu_handle_irq,
866 .enable = armv7pmu_enable_event,
867 .disable = armv7pmu_disable_event,
868 .read_counter = armv7pmu_read_counter,
869 .write_counter = armv7pmu_write_counter,
870 .get_event_idx = armv7pmu_get_event_idx,
871 .start = armv7pmu_start,
872 .stop = armv7pmu_stop,
873 .reset = armv7pmu_reset,
874 .raw_event_mask = 0xFF,
875 .max_period = (1LLU << 32) - 1,
876};
877
878static u32 __init armv7_read_num_pmnc_events(void)
879{
880 u32 nb_cnt;
881
882 /* Read the nb of CNTx counters supported from PMNC */
883 nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
884
885 /* Add the CPU cycles counter and return */
886 return nb_cnt + 1;
887}
888
889static const struct arm_pmu *__init armv7_a8_pmu_init(void)
890{
891 armv7pmu.id = ARM_PERF_PMU_ID_CA8;
892 armv7pmu.name = "ARMv7 Cortex-A8";
893 armv7pmu.cache_map = &armv7_a8_perf_cache_map;
894 armv7pmu.event_map = &armv7_a8_perf_map;
895 armv7pmu.num_events = armv7_read_num_pmnc_events();
896 return &armv7pmu;
897}
898
899static const struct arm_pmu *__init armv7_a9_pmu_init(void)
900{
901 armv7pmu.id = ARM_PERF_PMU_ID_CA9;
902 armv7pmu.name = "ARMv7 Cortex-A9";
903 armv7pmu.cache_map = &armv7_a9_perf_cache_map;
904 armv7pmu.event_map = &armv7_a9_perf_map;
905 armv7pmu.num_events = armv7_read_num_pmnc_events();
906 return &armv7pmu;
907}
908#else
909static const struct arm_pmu *__init armv7_a8_pmu_init(void)
910{
911 return NULL;
912}
913
914static const struct arm_pmu *__init armv7_a9_pmu_init(void)
915{
916 return NULL;
917}
918#endif /* CONFIG_CPU_V7 */
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
new file mode 100644
index 000000000000..39affbe4fdb2
--- /dev/null
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -0,0 +1,807 @@
1/*
2 * ARMv5 [xscale] Performance counter handling code.
3 *
4 * Copyright (C) 2010, ARM Ltd., Will Deacon <will.deacon@arm.com>
5 *
6 * Based on the previous xscale OProfile code.
7 *
8 * There are two variants of the xscale PMU that we support:
9 * - xscale1pmu: 2 event counters and a cycle counter
10 * - xscale2pmu: 4 event counters and a cycle counter
11 * The two variants share event definitions, but have different
12 * PMU structures.
13 */
14
15#ifdef CONFIG_CPU_XSCALE
16enum xscale_perf_types {
17 XSCALE_PERFCTR_ICACHE_MISS = 0x00,
18 XSCALE_PERFCTR_ICACHE_NO_DELIVER = 0x01,
19 XSCALE_PERFCTR_DATA_STALL = 0x02,
20 XSCALE_PERFCTR_ITLB_MISS = 0x03,
21 XSCALE_PERFCTR_DTLB_MISS = 0x04,
22 XSCALE_PERFCTR_BRANCH = 0x05,
23 XSCALE_PERFCTR_BRANCH_MISS = 0x06,
24 XSCALE_PERFCTR_INSTRUCTION = 0x07,
25 XSCALE_PERFCTR_DCACHE_FULL_STALL = 0x08,
26 XSCALE_PERFCTR_DCACHE_FULL_STALL_CONTIG = 0x09,
27 XSCALE_PERFCTR_DCACHE_ACCESS = 0x0A,
28 XSCALE_PERFCTR_DCACHE_MISS = 0x0B,
29 XSCALE_PERFCTR_DCACHE_WRITE_BACK = 0x0C,
30 XSCALE_PERFCTR_PC_CHANGED = 0x0D,
31 XSCALE_PERFCTR_BCU_REQUEST = 0x10,
32 XSCALE_PERFCTR_BCU_FULL = 0x11,
33 XSCALE_PERFCTR_BCU_DRAIN = 0x12,
34 XSCALE_PERFCTR_BCU_ECC_NO_ELOG = 0x14,
35 XSCALE_PERFCTR_BCU_1_BIT_ERR = 0x15,
36 XSCALE_PERFCTR_RMW = 0x16,
37 /* XSCALE_PERFCTR_CCNT is not hardware defined */
38 XSCALE_PERFCTR_CCNT = 0xFE,
39 XSCALE_PERFCTR_UNUSED = 0xFF,
40};
41
42enum xscale_counters {
43 XSCALE_CYCLE_COUNTER = 1,
44 XSCALE_COUNTER0,
45 XSCALE_COUNTER1,
46 XSCALE_COUNTER2,
47 XSCALE_COUNTER3,
48};
49
50static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = {
51 [PERF_COUNT_HW_CPU_CYCLES] = XSCALE_PERFCTR_CCNT,
52 [PERF_COUNT_HW_INSTRUCTIONS] = XSCALE_PERFCTR_INSTRUCTION,
53 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
54 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
55 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = XSCALE_PERFCTR_BRANCH,
56 [PERF_COUNT_HW_BRANCH_MISSES] = XSCALE_PERFCTR_BRANCH_MISS,
57 [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
58};
59
60static const unsigned xscale_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
61 [PERF_COUNT_HW_CACHE_OP_MAX]
62 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
63 [C(L1D)] = {
64 [C(OP_READ)] = {
65 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
66 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
67 },
68 [C(OP_WRITE)] = {
69 [C(RESULT_ACCESS)] = XSCALE_PERFCTR_DCACHE_ACCESS,
70 [C(RESULT_MISS)] = XSCALE_PERFCTR_DCACHE_MISS,
71 },
72 [C(OP_PREFETCH)] = {
73 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
74 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
75 },
76 },
77 [C(L1I)] = {
78 [C(OP_READ)] = {
79 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
80 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
81 },
82 [C(OP_WRITE)] = {
83 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
84 [C(RESULT_MISS)] = XSCALE_PERFCTR_ICACHE_MISS,
85 },
86 [C(OP_PREFETCH)] = {
87 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
88 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
89 },
90 },
91 [C(LL)] = {
92 [C(OP_READ)] = {
93 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
94 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
95 },
96 [C(OP_WRITE)] = {
97 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
98 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
99 },
100 [C(OP_PREFETCH)] = {
101 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
102 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
103 },
104 },
105 [C(DTLB)] = {
106 [C(OP_READ)] = {
107 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
108 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
109 },
110 [C(OP_WRITE)] = {
111 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
112 [C(RESULT_MISS)] = XSCALE_PERFCTR_DTLB_MISS,
113 },
114 [C(OP_PREFETCH)] = {
115 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
116 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
117 },
118 },
119 [C(ITLB)] = {
120 [C(OP_READ)] = {
121 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
122 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
123 },
124 [C(OP_WRITE)] = {
125 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
126 [C(RESULT_MISS)] = XSCALE_PERFCTR_ITLB_MISS,
127 },
128 [C(OP_PREFETCH)] = {
129 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
130 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
131 },
132 },
133 [C(BPU)] = {
134 [C(OP_READ)] = {
135 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
136 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
137 },
138 [C(OP_WRITE)] = {
139 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
140 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
141 },
142 [C(OP_PREFETCH)] = {
143 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
144 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
145 },
146 },
147};
148
149#define XSCALE_PMU_ENABLE 0x001
150#define XSCALE_PMN_RESET 0x002
151#define XSCALE_CCNT_RESET 0x004
152#define XSCALE_PMU_RESET (CCNT_RESET | PMN_RESET)
153#define XSCALE_PMU_CNT64 0x008
154
155#define XSCALE1_OVERFLOWED_MASK 0x700
156#define XSCALE1_CCOUNT_OVERFLOW 0x400
157#define XSCALE1_COUNT0_OVERFLOW 0x100
158#define XSCALE1_COUNT1_OVERFLOW 0x200
159#define XSCALE1_CCOUNT_INT_EN 0x040
160#define XSCALE1_COUNT0_INT_EN 0x010
161#define XSCALE1_COUNT1_INT_EN 0x020
162#define XSCALE1_COUNT0_EVT_SHFT 12
163#define XSCALE1_COUNT0_EVT_MASK (0xff << XSCALE1_COUNT0_EVT_SHFT)
164#define XSCALE1_COUNT1_EVT_SHFT 20
165#define XSCALE1_COUNT1_EVT_MASK (0xff << XSCALE1_COUNT1_EVT_SHFT)
166
167static inline u32
168xscale1pmu_read_pmnc(void)
169{
170 u32 val;
171 asm volatile("mrc p14, 0, %0, c0, c0, 0" : "=r" (val));
172 return val;
173}
174
175static inline void
176xscale1pmu_write_pmnc(u32 val)
177{
178 /* upper 4bits and 7, 11 are write-as-0 */
179 val &= 0xffff77f;
180 asm volatile("mcr p14, 0, %0, c0, c0, 0" : : "r" (val));
181}
182
183static inline int
184xscale1_pmnc_counter_has_overflowed(unsigned long pmnc,
185 enum xscale_counters counter)
186{
187 int ret = 0;
188
189 switch (counter) {
190 case XSCALE_CYCLE_COUNTER:
191 ret = pmnc & XSCALE1_CCOUNT_OVERFLOW;
192 break;
193 case XSCALE_COUNTER0:
194 ret = pmnc & XSCALE1_COUNT0_OVERFLOW;
195 break;
196 case XSCALE_COUNTER1:
197 ret = pmnc & XSCALE1_COUNT1_OVERFLOW;
198 break;
199 default:
200 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
201 }
202
203 return ret;
204}
205
206static irqreturn_t
207xscale1pmu_handle_irq(int irq_num, void *dev)
208{
209 unsigned long pmnc;
210 struct perf_sample_data data;
211 struct cpu_hw_events *cpuc;
212 struct pt_regs *regs;
213 int idx;
214
215 /*
216 * NOTE: there's an A stepping erratum that states if an overflow
217 * bit already exists and another occurs, the previous
218 * Overflow bit gets cleared. There's no workaround.
219 * Fixed in B stepping or later.
220 */
221 pmnc = xscale1pmu_read_pmnc();
222
223 /*
224 * Write the value back to clear the overflow flags. Overflow
225 * flags remain in pmnc for use below. We also disable the PMU
226 * while we process the interrupt.
227 */
228 xscale1pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
229
230 if (!(pmnc & XSCALE1_OVERFLOWED_MASK))
231 return IRQ_NONE;
232
233 regs = get_irq_regs();
234
235 perf_sample_data_init(&data, 0);
236
237 cpuc = &__get_cpu_var(cpu_hw_events);
238 for (idx = 0; idx <= armpmu->num_events; ++idx) {
239 struct perf_event *event = cpuc->events[idx];
240 struct hw_perf_event *hwc;
241
242 if (!test_bit(idx, cpuc->active_mask))
243 continue;
244
245 if (!xscale1_pmnc_counter_has_overflowed(pmnc, idx))
246 continue;
247
248 hwc = &event->hw;
249 armpmu_event_update(event, hwc, idx, 1);
250 data.period = event->hw.last_period;
251 if (!armpmu_event_set_period(event, hwc, idx))
252 continue;
253
254 if (perf_event_overflow(event, 0, &data, regs))
255 armpmu->disable(hwc, idx);
256 }
257
258 irq_work_run();
259
260 /*
261 * Re-enable the PMU.
262 */
263 pmnc = xscale1pmu_read_pmnc() | XSCALE_PMU_ENABLE;
264 xscale1pmu_write_pmnc(pmnc);
265
266 return IRQ_HANDLED;
267}
268
269static void
270xscale1pmu_enable_event(struct hw_perf_event *hwc, int idx)
271{
272 unsigned long val, mask, evt, flags;
273
274 switch (idx) {
275 case XSCALE_CYCLE_COUNTER:
276 mask = 0;
277 evt = XSCALE1_CCOUNT_INT_EN;
278 break;
279 case XSCALE_COUNTER0:
280 mask = XSCALE1_COUNT0_EVT_MASK;
281 evt = (hwc->config_base << XSCALE1_COUNT0_EVT_SHFT) |
282 XSCALE1_COUNT0_INT_EN;
283 break;
284 case XSCALE_COUNTER1:
285 mask = XSCALE1_COUNT1_EVT_MASK;
286 evt = (hwc->config_base << XSCALE1_COUNT1_EVT_SHFT) |
287 XSCALE1_COUNT1_INT_EN;
288 break;
289 default:
290 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
291 return;
292 }
293
294 raw_spin_lock_irqsave(&pmu_lock, flags);
295 val = xscale1pmu_read_pmnc();
296 val &= ~mask;
297 val |= evt;
298 xscale1pmu_write_pmnc(val);
299 raw_spin_unlock_irqrestore(&pmu_lock, flags);
300}
301
302static void
303xscale1pmu_disable_event(struct hw_perf_event *hwc, int idx)
304{
305 unsigned long val, mask, evt, flags;
306
307 switch (idx) {
308 case XSCALE_CYCLE_COUNTER:
309 mask = XSCALE1_CCOUNT_INT_EN;
310 evt = 0;
311 break;
312 case XSCALE_COUNTER0:
313 mask = XSCALE1_COUNT0_INT_EN | XSCALE1_COUNT0_EVT_MASK;
314 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT0_EVT_SHFT;
315 break;
316 case XSCALE_COUNTER1:
317 mask = XSCALE1_COUNT1_INT_EN | XSCALE1_COUNT1_EVT_MASK;
318 evt = XSCALE_PERFCTR_UNUSED << XSCALE1_COUNT1_EVT_SHFT;
319 break;
320 default:
321 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
322 return;
323 }
324
325 raw_spin_lock_irqsave(&pmu_lock, flags);
326 val = xscale1pmu_read_pmnc();
327 val &= ~mask;
328 val |= evt;
329 xscale1pmu_write_pmnc(val);
330 raw_spin_unlock_irqrestore(&pmu_lock, flags);
331}
332
333static int
334xscale1pmu_get_event_idx(struct cpu_hw_events *cpuc,
335 struct hw_perf_event *event)
336{
337 if (XSCALE_PERFCTR_CCNT == event->config_base) {
338 if (test_and_set_bit(XSCALE_CYCLE_COUNTER, cpuc->used_mask))
339 return -EAGAIN;
340
341 return XSCALE_CYCLE_COUNTER;
342 } else {
343 if (!test_and_set_bit(XSCALE_COUNTER1, cpuc->used_mask))
344 return XSCALE_COUNTER1;
345
346 if (!test_and_set_bit(XSCALE_COUNTER0, cpuc->used_mask))
347 return XSCALE_COUNTER0;
348
349 return -EAGAIN;
350 }
351}
352
353static void
354xscale1pmu_start(void)
355{
356 unsigned long flags, val;
357
358 raw_spin_lock_irqsave(&pmu_lock, flags);
359 val = xscale1pmu_read_pmnc();
360 val |= XSCALE_PMU_ENABLE;
361 xscale1pmu_write_pmnc(val);
362 raw_spin_unlock_irqrestore(&pmu_lock, flags);
363}
364
365static void
366xscale1pmu_stop(void)
367{
368 unsigned long flags, val;
369
370 raw_spin_lock_irqsave(&pmu_lock, flags);
371 val = xscale1pmu_read_pmnc();
372 val &= ~XSCALE_PMU_ENABLE;
373 xscale1pmu_write_pmnc(val);
374 raw_spin_unlock_irqrestore(&pmu_lock, flags);
375}
376
377static inline u32
378xscale1pmu_read_counter(int counter)
379{
380 u32 val = 0;
381
382 switch (counter) {
383 case XSCALE_CYCLE_COUNTER:
384 asm volatile("mrc p14, 0, %0, c1, c0, 0" : "=r" (val));
385 break;
386 case XSCALE_COUNTER0:
387 asm volatile("mrc p14, 0, %0, c2, c0, 0" : "=r" (val));
388 break;
389 case XSCALE_COUNTER1:
390 asm volatile("mrc p14, 0, %0, c3, c0, 0" : "=r" (val));
391 break;
392 }
393
394 return val;
395}
396
397static inline void
398xscale1pmu_write_counter(int counter, u32 val)
399{
400 switch (counter) {
401 case XSCALE_CYCLE_COUNTER:
402 asm volatile("mcr p14, 0, %0, c1, c0, 0" : : "r" (val));
403 break;
404 case XSCALE_COUNTER0:
405 asm volatile("mcr p14, 0, %0, c2, c0, 0" : : "r" (val));
406 break;
407 case XSCALE_COUNTER1:
408 asm volatile("mcr p14, 0, %0, c3, c0, 0" : : "r" (val));
409 break;
410 }
411}
412
413static const struct arm_pmu xscale1pmu = {
414 .id = ARM_PERF_PMU_ID_XSCALE1,
415 .name = "xscale1",
416 .handle_irq = xscale1pmu_handle_irq,
417 .enable = xscale1pmu_enable_event,
418 .disable = xscale1pmu_disable_event,
419 .read_counter = xscale1pmu_read_counter,
420 .write_counter = xscale1pmu_write_counter,
421 .get_event_idx = xscale1pmu_get_event_idx,
422 .start = xscale1pmu_start,
423 .stop = xscale1pmu_stop,
424 .cache_map = &xscale_perf_cache_map,
425 .event_map = &xscale_perf_map,
426 .raw_event_mask = 0xFF,
427 .num_events = 3,
428 .max_period = (1LLU << 32) - 1,
429};
430
431static const struct arm_pmu *__init xscale1pmu_init(void)
432{
433 return &xscale1pmu;
434}
435
436#define XSCALE2_OVERFLOWED_MASK 0x01f
437#define XSCALE2_CCOUNT_OVERFLOW 0x001
438#define XSCALE2_COUNT0_OVERFLOW 0x002
439#define XSCALE2_COUNT1_OVERFLOW 0x004
440#define XSCALE2_COUNT2_OVERFLOW 0x008
441#define XSCALE2_COUNT3_OVERFLOW 0x010
442#define XSCALE2_CCOUNT_INT_EN 0x001
443#define XSCALE2_COUNT0_INT_EN 0x002
444#define XSCALE2_COUNT1_INT_EN 0x004
445#define XSCALE2_COUNT2_INT_EN 0x008
446#define XSCALE2_COUNT3_INT_EN 0x010
447#define XSCALE2_COUNT0_EVT_SHFT 0
448#define XSCALE2_COUNT0_EVT_MASK (0xff << XSCALE2_COUNT0_EVT_SHFT)
449#define XSCALE2_COUNT1_EVT_SHFT 8
450#define XSCALE2_COUNT1_EVT_MASK (0xff << XSCALE2_COUNT1_EVT_SHFT)
451#define XSCALE2_COUNT2_EVT_SHFT 16
452#define XSCALE2_COUNT2_EVT_MASK (0xff << XSCALE2_COUNT2_EVT_SHFT)
453#define XSCALE2_COUNT3_EVT_SHFT 24
454#define XSCALE2_COUNT3_EVT_MASK (0xff << XSCALE2_COUNT3_EVT_SHFT)
455
456static inline u32
457xscale2pmu_read_pmnc(void)
458{
459 u32 val;
460 asm volatile("mrc p14, 0, %0, c0, c1, 0" : "=r" (val));
461 /* bits 1-2 and 4-23 are read-unpredictable */
462 return val & 0xff000009;
463}
464
465static inline void
466xscale2pmu_write_pmnc(u32 val)
467{
468 /* bits 4-23 are write-as-0, 24-31 are write ignored */
469 val &= 0xf;
470 asm volatile("mcr p14, 0, %0, c0, c1, 0" : : "r" (val));
471}
472
473static inline u32
474xscale2pmu_read_overflow_flags(void)
475{
476 u32 val;
477 asm volatile("mrc p14, 0, %0, c5, c1, 0" : "=r" (val));
478 return val;
479}
480
481static inline void
482xscale2pmu_write_overflow_flags(u32 val)
483{
484 asm volatile("mcr p14, 0, %0, c5, c1, 0" : : "r" (val));
485}
486
487static inline u32
488xscale2pmu_read_event_select(void)
489{
490 u32 val;
491 asm volatile("mrc p14, 0, %0, c8, c1, 0" : "=r" (val));
492 return val;
493}
494
495static inline void
496xscale2pmu_write_event_select(u32 val)
497{
498 asm volatile("mcr p14, 0, %0, c8, c1, 0" : : "r"(val));
499}
500
501static inline u32
502xscale2pmu_read_int_enable(void)
503{
504 u32 val;
505 asm volatile("mrc p14, 0, %0, c4, c1, 0" : "=r" (val));
506 return val;
507}
508
509static void
510xscale2pmu_write_int_enable(u32 val)
511{
512 asm volatile("mcr p14, 0, %0, c4, c1, 0" : : "r" (val));
513}
514
515static inline int
516xscale2_pmnc_counter_has_overflowed(unsigned long of_flags,
517 enum xscale_counters counter)
518{
519 int ret = 0;
520
521 switch (counter) {
522 case XSCALE_CYCLE_COUNTER:
523 ret = of_flags & XSCALE2_CCOUNT_OVERFLOW;
524 break;
525 case XSCALE_COUNTER0:
526 ret = of_flags & XSCALE2_COUNT0_OVERFLOW;
527 break;
528 case XSCALE_COUNTER1:
529 ret = of_flags & XSCALE2_COUNT1_OVERFLOW;
530 break;
531 case XSCALE_COUNTER2:
532 ret = of_flags & XSCALE2_COUNT2_OVERFLOW;
533 break;
534 case XSCALE_COUNTER3:
535 ret = of_flags & XSCALE2_COUNT3_OVERFLOW;
536 break;
537 default:
538 WARN_ONCE(1, "invalid counter number (%d)\n", counter);
539 }
540
541 return ret;
542}
543
544static irqreturn_t
545xscale2pmu_handle_irq(int irq_num, void *dev)
546{
547 unsigned long pmnc, of_flags;
548 struct perf_sample_data data;
549 struct cpu_hw_events *cpuc;
550 struct pt_regs *regs;
551 int idx;
552
553 /* Disable the PMU. */
554 pmnc = xscale2pmu_read_pmnc();
555 xscale2pmu_write_pmnc(pmnc & ~XSCALE_PMU_ENABLE);
556
557 /* Check the overflow flag register. */
558 of_flags = xscale2pmu_read_overflow_flags();
559 if (!(of_flags & XSCALE2_OVERFLOWED_MASK))
560 return IRQ_NONE;
561
562 /* Clear the overflow bits. */
563 xscale2pmu_write_overflow_flags(of_flags);
564
565 regs = get_irq_regs();
566
567 perf_sample_data_init(&data, 0);
568
569 cpuc = &__get_cpu_var(cpu_hw_events);
570 for (idx = 0; idx <= armpmu->num_events; ++idx) {
571 struct perf_event *event = cpuc->events[idx];
572 struct hw_perf_event *hwc;
573
574 if (!test_bit(idx, cpuc->active_mask))
575 continue;
576
577 if (!xscale2_pmnc_counter_has_overflowed(pmnc, idx))
578 continue;
579
580 hwc = &event->hw;
581 armpmu_event_update(event, hwc, idx, 1);
582 data.period = event->hw.last_period;
583 if (!armpmu_event_set_period(event, hwc, idx))
584 continue;
585
586 if (perf_event_overflow(event, 0, &data, regs))
587 armpmu->disable(hwc, idx);
588 }
589
590 irq_work_run();
591
592 /*
593 * Re-enable the PMU.
594 */
595 pmnc = xscale2pmu_read_pmnc() | XSCALE_PMU_ENABLE;
596 xscale2pmu_write_pmnc(pmnc);
597
598 return IRQ_HANDLED;
599}
600
601static void
602xscale2pmu_enable_event(struct hw_perf_event *hwc, int idx)
603{
604 unsigned long flags, ien, evtsel;
605
606 ien = xscale2pmu_read_int_enable();
607 evtsel = xscale2pmu_read_event_select();
608
609 switch (idx) {
610 case XSCALE_CYCLE_COUNTER:
611 ien |= XSCALE2_CCOUNT_INT_EN;
612 break;
613 case XSCALE_COUNTER0:
614 ien |= XSCALE2_COUNT0_INT_EN;
615 evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
616 evtsel |= hwc->config_base << XSCALE2_COUNT0_EVT_SHFT;
617 break;
618 case XSCALE_COUNTER1:
619 ien |= XSCALE2_COUNT1_INT_EN;
620 evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
621 evtsel |= hwc->config_base << XSCALE2_COUNT1_EVT_SHFT;
622 break;
623 case XSCALE_COUNTER2:
624 ien |= XSCALE2_COUNT2_INT_EN;
625 evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
626 evtsel |= hwc->config_base << XSCALE2_COUNT2_EVT_SHFT;
627 break;
628 case XSCALE_COUNTER3:
629 ien |= XSCALE2_COUNT3_INT_EN;
630 evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
631 evtsel |= hwc->config_base << XSCALE2_COUNT3_EVT_SHFT;
632 break;
633 default:
634 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
635 return;
636 }
637
638 raw_spin_lock_irqsave(&pmu_lock, flags);
639 xscale2pmu_write_event_select(evtsel);
640 xscale2pmu_write_int_enable(ien);
641 raw_spin_unlock_irqrestore(&pmu_lock, flags);
642}
643
644static void
645xscale2pmu_disable_event(struct hw_perf_event *hwc, int idx)
646{
647 unsigned long flags, ien, evtsel;
648
649 ien = xscale2pmu_read_int_enable();
650 evtsel = xscale2pmu_read_event_select();
651
652 switch (idx) {
653 case XSCALE_CYCLE_COUNTER:
654 ien &= ~XSCALE2_CCOUNT_INT_EN;
655 break;
656 case XSCALE_COUNTER0:
657 ien &= ~XSCALE2_COUNT0_INT_EN;
658 evtsel &= ~XSCALE2_COUNT0_EVT_MASK;
659 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT0_EVT_SHFT;
660 break;
661 case XSCALE_COUNTER1:
662 ien &= ~XSCALE2_COUNT1_INT_EN;
663 evtsel &= ~XSCALE2_COUNT1_EVT_MASK;
664 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT1_EVT_SHFT;
665 break;
666 case XSCALE_COUNTER2:
667 ien &= ~XSCALE2_COUNT2_INT_EN;
668 evtsel &= ~XSCALE2_COUNT2_EVT_MASK;
669 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT2_EVT_SHFT;
670 break;
671 case XSCALE_COUNTER3:
672 ien &= ~XSCALE2_COUNT3_INT_EN;
673 evtsel &= ~XSCALE2_COUNT3_EVT_MASK;
674 evtsel |= XSCALE_PERFCTR_UNUSED << XSCALE2_COUNT3_EVT_SHFT;
675 break;
676 default:
677 WARN_ONCE(1, "invalid counter number (%d)\n", idx);
678 return;
679 }
680
681 raw_spin_lock_irqsave(&pmu_lock, flags);
682 xscale2pmu_write_event_select(evtsel);
683 xscale2pmu_write_int_enable(ien);
684 raw_spin_unlock_irqrestore(&pmu_lock, flags);
685}
686
687static int
688xscale2pmu_get_event_idx(struct cpu_hw_events *cpuc,
689 struct hw_perf_event *event)
690{
691 int idx = xscale1pmu_get_event_idx(cpuc, event);
692 if (idx >= 0)
693 goto out;
694
695 if (!test_and_set_bit(XSCALE_COUNTER3, cpuc->used_mask))
696 idx = XSCALE_COUNTER3;
697 else if (!test_and_set_bit(XSCALE_COUNTER2, cpuc->used_mask))
698 idx = XSCALE_COUNTER2;
699out:
700 return idx;
701}
702
703static void
704xscale2pmu_start(void)
705{
706 unsigned long flags, val;
707
708 raw_spin_lock_irqsave(&pmu_lock, flags);
709 val = xscale2pmu_read_pmnc() & ~XSCALE_PMU_CNT64;
710 val |= XSCALE_PMU_ENABLE;
711 xscale2pmu_write_pmnc(val);
712 raw_spin_unlock_irqrestore(&pmu_lock, flags);
713}
714
715static void
716xscale2pmu_stop(void)
717{
718 unsigned long flags, val;
719
720 raw_spin_lock_irqsave(&pmu_lock, flags);
721 val = xscale2pmu_read_pmnc();
722 val &= ~XSCALE_PMU_ENABLE;
723 xscale2pmu_write_pmnc(val);
724 raw_spin_unlock_irqrestore(&pmu_lock, flags);
725}
726
727static inline u32
728xscale2pmu_read_counter(int counter)
729{
730 u32 val = 0;
731
732 switch (counter) {
733 case XSCALE_CYCLE_COUNTER:
734 asm volatile("mrc p14, 0, %0, c1, c1, 0" : "=r" (val));
735 break;
736 case XSCALE_COUNTER0:
737 asm volatile("mrc p14, 0, %0, c0, c2, 0" : "=r" (val));
738 break;
739 case XSCALE_COUNTER1:
740 asm volatile("mrc p14, 0, %0, c1, c2, 0" : "=r" (val));
741 break;
742 case XSCALE_COUNTER2:
743 asm volatile("mrc p14, 0, %0, c2, c2, 0" : "=r" (val));
744 break;
745 case XSCALE_COUNTER3:
746 asm volatile("mrc p14, 0, %0, c3, c2, 0" : "=r" (val));
747 break;
748 }
749
750 return val;
751}
752
753static inline void
754xscale2pmu_write_counter(int counter, u32 val)
755{
756 switch (counter) {
757 case XSCALE_CYCLE_COUNTER:
758 asm volatile("mcr p14, 0, %0, c1, c1, 0" : : "r" (val));
759 break;
760 case XSCALE_COUNTER0:
761 asm volatile("mcr p14, 0, %0, c0, c2, 0" : : "r" (val));
762 break;
763 case XSCALE_COUNTER1:
764 asm volatile("mcr p14, 0, %0, c1, c2, 0" : : "r" (val));
765 break;
766 case XSCALE_COUNTER2:
767 asm volatile("mcr p14, 0, %0, c2, c2, 0" : : "r" (val));
768 break;
769 case XSCALE_COUNTER3:
770 asm volatile("mcr p14, 0, %0, c3, c2, 0" : : "r" (val));
771 break;
772 }
773}
774
775static const struct arm_pmu xscale2pmu = {
776 .id = ARM_PERF_PMU_ID_XSCALE2,
777 .name = "xscale2",
778 .handle_irq = xscale2pmu_handle_irq,
779 .enable = xscale2pmu_enable_event,
780 .disable = xscale2pmu_disable_event,
781 .read_counter = xscale2pmu_read_counter,
782 .write_counter = xscale2pmu_write_counter,
783 .get_event_idx = xscale2pmu_get_event_idx,
784 .start = xscale2pmu_start,
785 .stop = xscale2pmu_stop,
786 .cache_map = &xscale_perf_cache_map,
787 .event_map = &xscale_perf_map,
788 .raw_event_mask = 0xFF,
789 .num_events = 5,
790 .max_period = (1LLU << 32) - 1,
791};
792
793static const struct arm_pmu *__init xscale2pmu_init(void)
794{
795 return &xscale2pmu;
796}
797#else
798static const struct arm_pmu *__init xscale1pmu_init(void)
799{
800 return NULL;
801}
802
803static const struct arm_pmu *__init xscale2pmu_init(void)
804{
805 return NULL;
806}
807#endif /* CONFIG_CPU_XSCALE */
diff --git a/arch/arm/kernel/pj4-cp0.c b/arch/arm/kernel/pj4-cp0.c
new file mode 100644
index 000000000000..a4b1b0748fd3
--- /dev/null
+++ b/arch/arm/kernel/pj4-cp0.c
@@ -0,0 +1,94 @@
1/*
2 * linux/arch/arm/kernel/pj4-cp0.c
3 *
4 * PJ4 iWMMXt coprocessor context switching and handling
5 *
6 * Copyright (c) 2010 Marvell International Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/signal.h>
17#include <linux/sched.h>
18#include <linux/init.h>
19#include <linux/io.h>
20#include <asm/thread_notify.h>
21
22static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
23{
24 struct thread_info *thread = t;
25
26 switch (cmd) {
27 case THREAD_NOTIFY_FLUSH:
28 /*
29 * flush_thread() zeroes thread->fpstate, so no need
30 * to do anything here.
31 *
32 * FALLTHROUGH: Ensure we don't try to overwrite our newly
33 * initialised state information on the first fault.
34 */
35
36 case THREAD_NOTIFY_EXIT:
37 iwmmxt_task_release(thread);
38 break;
39
40 case THREAD_NOTIFY_SWITCH:
41 iwmmxt_task_switch(thread);
42 break;
43 }
44
45 return NOTIFY_DONE;
46}
47
48static struct notifier_block iwmmxt_notifier_block = {
49 .notifier_call = iwmmxt_do,
50};
51
52
53static u32 __init pj4_cp_access_read(void)
54{
55 u32 value;
56
57 __asm__ __volatile__ (
58 "mrc p15, 0, %0, c1, c0, 2\n\t"
59 : "=r" (value));
60 return value;
61}
62
63static void __init pj4_cp_access_write(u32 value)
64{
65 u32 temp;
66
67 __asm__ __volatile__ (
68 "mcr p15, 0, %1, c1, c0, 2\n\t"
69 "mrc p15, 0, %0, c1, c0, 2\n\t"
70 "mov %0, %0\n\t"
71 "sub pc, pc, #4\n\t"
72 : "=r" (temp) : "r" (value));
73}
74
75
76/*
77 * Disable CP0/CP1 on boot, and let call_fpe() and the iWMMXt lazy
78 * switch code handle iWMMXt context switching.
79 */
80static int __init pj4_cp0_init(void)
81{
82 u32 cp_access;
83
84 cp_access = pj4_cp_access_read() & ~0xf;
85 pj4_cp_access_write(cp_access);
86
87 printk(KERN_INFO "PJ4 iWMMXt coprocessor enabled.\n");
88 elf_hwcap |= HWCAP_IWMMXT;
89 thread_register_notifier(&iwmmxt_notifier_block);
90
91 return 0;
92}
93
94late_initcall(pj4_cp0_init);
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c
index b8af96ea62e6..2c79eec19262 100644
--- a/arch/arm/kernel/pmu.c
+++ b/arch/arm/kernel/pmu.c
@@ -97,28 +97,34 @@ set_irq_affinity(int irq,
97 irq, cpu); 97 irq, cpu);
98 return err; 98 return err;
99#else 99#else
100 return 0; 100 return -EINVAL;
101#endif 101#endif
102} 102}
103 103
104static int 104static int
105init_cpu_pmu(void) 105init_cpu_pmu(void)
106{ 106{
107 int i, err = 0; 107 int i, irqs, err = 0;
108 struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU]; 108 struct platform_device *pdev = pmu_devices[ARM_PMU_DEVICE_CPU];
109 109
110 if (!pdev) { 110 if (!pdev)
111 err = -ENODEV; 111 return -ENODEV;
112 goto out; 112
113 } 113 irqs = pdev->num_resources;
114
115 /*
116 * If we have a single PMU interrupt that we can't shift, assume that
117 * we're running on a uniprocessor machine and continue.
118 */
119 if (irqs == 1 && !irq_can_set_affinity(platform_get_irq(pdev, 0)))
120 return 0;
114 121
115 for (i = 0; i < pdev->num_resources; ++i) { 122 for (i = 0; i < irqs; ++i) {
116 err = set_irq_affinity(platform_get_irq(pdev, i), i); 123 err = set_irq_affinity(platform_get_irq(pdev, i), i);
117 if (err) 124 if (err)
118 break; 125 break;
119 } 126 }
120 127
121out:
122 return err; 128 return err;
123} 129}
124 130
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 401e38be1f78..5e1e54197227 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -29,6 +29,7 @@
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/random.h> 31#include <linux/random.h>
32#include <linux/hw_breakpoint.h>
32 33
33#include <asm/cacheflush.h> 34#include <asm/cacheflush.h>
34#include <asm/leds.h> 35#include <asm/leds.h>
@@ -135,6 +136,25 @@ EXPORT_SYMBOL(pm_power_off);
135void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; 136void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart;
136EXPORT_SYMBOL_GPL(arm_pm_restart); 137EXPORT_SYMBOL_GPL(arm_pm_restart);
137 138
139static void do_nothing(void *unused)
140{
141}
142
143/*
144 * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
145 * pm_idle and update to new pm_idle value. Required while changing pm_idle
146 * handler on SMP systems.
147 *
148 * Caller must have changed pm_idle to the new value before the call. Old
149 * pm_idle value will not be used by any CPU after the return of this function.
150 */
151void cpu_idle_wait(void)
152{
153 smp_mb();
154 /* kick all the CPUs so that they exit out of pm_idle */
155 smp_call_function(do_nothing, NULL, 1);
156}
157EXPORT_SYMBOL_GPL(cpu_idle_wait);
138 158
139/* 159/*
140 * This is our default idle handler. We need to disable 160 * This is our default idle handler. We need to disable
@@ -317,6 +337,8 @@ void flush_thread(void)
317 struct thread_info *thread = current_thread_info(); 337 struct thread_info *thread = current_thread_info();
318 struct task_struct *tsk = current; 338 struct task_struct *tsk = current;
319 339
340 flush_ptrace_hw_breakpoint(tsk);
341
320 memset(thread->used_cp, 0, sizeof(thread->used_cp)); 342 memset(thread->used_cp, 0, sizeof(thread->used_cp));
321 memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); 343 memset(&tsk->thread.debug, 0, sizeof(struct debug_info));
322 memset(&thread->fpstate, 0, sizeof(union fp_state)); 344 memset(&thread->fpstate, 0, sizeof(union fp_state));
@@ -345,9 +367,13 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
345 thread->cpu_context.sp = (unsigned long)childregs; 367 thread->cpu_context.sp = (unsigned long)childregs;
346 thread->cpu_context.pc = (unsigned long)ret_from_fork; 368 thread->cpu_context.pc = (unsigned long)ret_from_fork;
347 369
370 clear_ptrace_hw_breakpoint(p);
371
348 if (clone_flags & CLONE_SETTLS) 372 if (clone_flags & CLONE_SETTLS)
349 thread->tp_value = regs->ARM_r3; 373 thread->tp_value = regs->ARM_r3;
350 374
375 thread_notify(THREAD_NOTIFY_COPY, thread);
376
351 return 0; 377 return 0;
352} 378}
353 379
@@ -458,3 +484,26 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
458 unsigned long range_end = mm->brk + 0x02000000; 484 unsigned long range_end = mm->brk + 0x02000000;
459 return randomize_range(mm->brk, range_end, 0) ? : mm->brk; 485 return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
460} 486}
487
488#ifdef CONFIG_MMU
489/*
490 * The vectors page is always readable from user space for the
491 * atomic helpers and the signal restart code. Let's declare a mapping
492 * for it so it is visible through ptrace and /proc/<pid>/mem.
493 */
494
495int vectors_user_mapping(void)
496{
497 struct mm_struct *mm = current->mm;
498 return install_special_mapping(mm, 0xffff0000, PAGE_SIZE,
499 VM_READ | VM_EXEC |
500 VM_MAYREAD | VM_MAYEXEC |
501 VM_ALWAYSDUMP | VM_RESERVED,
502 NULL);
503}
504
505const char *arch_vma_name(struct vm_area_struct *vma)
506{
507 return (vma->vm_start == 0xffff0000) ? "[vectors]" : NULL;
508}
509#endif
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index f99d489822d5..97260060bf26 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -19,13 +19,14 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/signal.h> 20#include <linux/signal.h>
21#include <linux/uaccess.h> 21#include <linux/uaccess.h>
22#include <linux/perf_event.h>
23#include <linux/hw_breakpoint.h>
24#include <linux/regset.h>
22 25
23#include <asm/pgtable.h> 26#include <asm/pgtable.h>
24#include <asm/system.h> 27#include <asm/system.h>
25#include <asm/traps.h> 28#include <asm/traps.h>
26 29
27#include "ptrace.h"
28
29#define REG_PC 15 30#define REG_PC 15
30#define REG_PSR 16 31#define REG_PSR 16
31/* 32/*
@@ -182,389 +183,12 @@ put_user_reg(struct task_struct *task, int offset, long data)
182 return ret; 183 return ret;
183} 184}
184 185
185static inline int
186read_u32(struct task_struct *task, unsigned long addr, u32 *res)
187{
188 int ret;
189
190 ret = access_process_vm(task, addr, res, sizeof(*res), 0);
191
192 return ret == sizeof(*res) ? 0 : -EIO;
193}
194
195static inline int
196read_instr(struct task_struct *task, unsigned long addr, u32 *res)
197{
198 int ret;
199
200 if (addr & 1) {
201 u16 val;
202 ret = access_process_vm(task, addr & ~1, &val, sizeof(val), 0);
203 ret = ret == sizeof(val) ? 0 : -EIO;
204 *res = val;
205 } else {
206 u32 val;
207 ret = access_process_vm(task, addr & ~3, &val, sizeof(val), 0);
208 ret = ret == sizeof(val) ? 0 : -EIO;
209 *res = val;
210 }
211 return ret;
212}
213
214/*
215 * Get value of register `rn' (in the instruction)
216 */
217static unsigned long
218ptrace_getrn(struct task_struct *child, unsigned long insn)
219{
220 unsigned int reg = (insn >> 16) & 15;
221 unsigned long val;
222
223 val = get_user_reg(child, reg);
224 if (reg == 15)
225 val += 8;
226
227 return val;
228}
229
230/*
231 * Get value of operand 2 (in an ALU instruction)
232 */
233static unsigned long
234ptrace_getaluop2(struct task_struct *child, unsigned long insn)
235{
236 unsigned long val;
237 int shift;
238 int type;
239
240 if (insn & 1 << 25) {
241 val = insn & 255;
242 shift = (insn >> 8) & 15;
243 type = 3;
244 } else {
245 val = get_user_reg (child, insn & 15);
246
247 if (insn & (1 << 4))
248 shift = (int)get_user_reg (child, (insn >> 8) & 15);
249 else
250 shift = (insn >> 7) & 31;
251
252 type = (insn >> 5) & 3;
253 }
254
255 switch (type) {
256 case 0: val <<= shift; break;
257 case 1: val >>= shift; break;
258 case 2:
259 val = (((signed long)val) >> shift);
260 break;
261 case 3:
262 val = (val >> shift) | (val << (32 - shift));
263 break;
264 }
265 return val;
266}
267
268/*
269 * Get value of operand 2 (in a LDR instruction)
270 */
271static unsigned long
272ptrace_getldrop2(struct task_struct *child, unsigned long insn)
273{
274 unsigned long val;
275 int shift;
276 int type;
277
278 val = get_user_reg(child, insn & 15);
279 shift = (insn >> 7) & 31;
280 type = (insn >> 5) & 3;
281
282 switch (type) {
283 case 0: val <<= shift; break;
284 case 1: val >>= shift; break;
285 case 2:
286 val = (((signed long)val) >> shift);
287 break;
288 case 3:
289 val = (val >> shift) | (val << (32 - shift));
290 break;
291 }
292 return val;
293}
294
295#define OP_MASK 0x01e00000
296#define OP_AND 0x00000000
297#define OP_EOR 0x00200000
298#define OP_SUB 0x00400000
299#define OP_RSB 0x00600000
300#define OP_ADD 0x00800000
301#define OP_ADC 0x00a00000
302#define OP_SBC 0x00c00000
303#define OP_RSC 0x00e00000
304#define OP_ORR 0x01800000
305#define OP_MOV 0x01a00000
306#define OP_BIC 0x01c00000
307#define OP_MVN 0x01e00000
308
309static unsigned long
310get_branch_address(struct task_struct *child, unsigned long pc, unsigned long insn)
311{
312 u32 alt = 0;
313
314 switch (insn & 0x0e000000) {
315 case 0x00000000:
316 case 0x02000000: {
317 /*
318 * data processing
319 */
320 long aluop1, aluop2, ccbit;
321
322 if ((insn & 0x0fffffd0) == 0x012fff10) {
323 /*
324 * bx or blx
325 */
326 alt = get_user_reg(child, insn & 15);
327 break;
328 }
329
330
331 if ((insn & 0xf000) != 0xf000)
332 break;
333
334 aluop1 = ptrace_getrn(child, insn);
335 aluop2 = ptrace_getaluop2(child, insn);
336 ccbit = get_user_reg(child, REG_PSR) & PSR_C_BIT ? 1 : 0;
337
338 switch (insn & OP_MASK) {
339 case OP_AND: alt = aluop1 & aluop2; break;
340 case OP_EOR: alt = aluop1 ^ aluop2; break;
341 case OP_SUB: alt = aluop1 - aluop2; break;
342 case OP_RSB: alt = aluop2 - aluop1; break;
343 case OP_ADD: alt = aluop1 + aluop2; break;
344 case OP_ADC: alt = aluop1 + aluop2 + ccbit; break;
345 case OP_SBC: alt = aluop1 - aluop2 + ccbit; break;
346 case OP_RSC: alt = aluop2 - aluop1 + ccbit; break;
347 case OP_ORR: alt = aluop1 | aluop2; break;
348 case OP_MOV: alt = aluop2; break;
349 case OP_BIC: alt = aluop1 & ~aluop2; break;
350 case OP_MVN: alt = ~aluop2; break;
351 }
352 break;
353 }
354
355 case 0x04000000:
356 case 0x06000000:
357 /*
358 * ldr
359 */
360 if ((insn & 0x0010f000) == 0x0010f000) {
361 unsigned long base;
362
363 base = ptrace_getrn(child, insn);
364 if (insn & 1 << 24) {
365 long aluop2;
366
367 if (insn & 0x02000000)
368 aluop2 = ptrace_getldrop2(child, insn);
369 else
370 aluop2 = insn & 0xfff;
371
372 if (insn & 1 << 23)
373 base += aluop2;
374 else
375 base -= aluop2;
376 }
377 read_u32(child, base, &alt);
378 }
379 break;
380
381 case 0x08000000:
382 /*
383 * ldm
384 */
385 if ((insn & 0x00108000) == 0x00108000) {
386 unsigned long base;
387 unsigned int nr_regs;
388
389 if (insn & (1 << 23)) {
390 nr_regs = hweight16(insn & 65535) << 2;
391
392 if (!(insn & (1 << 24)))
393 nr_regs -= 4;
394 } else {
395 if (insn & (1 << 24))
396 nr_regs = -4;
397 else
398 nr_regs = 0;
399 }
400
401 base = ptrace_getrn(child, insn);
402
403 read_u32(child, base + nr_regs, &alt);
404 break;
405 }
406 break;
407
408 case 0x0a000000: {
409 /*
410 * bl or b
411 */
412 signed long displ;
413 /* It's a branch/branch link: instead of trying to
414 * figure out whether the branch will be taken or not,
415 * we'll put a breakpoint at both locations. This is
416 * simpler, more reliable, and probably not a whole lot
417 * slower than the alternative approach of emulating the
418 * branch.
419 */
420 displ = (insn & 0x00ffffff) << 8;
421 displ = (displ >> 6) + 8;
422 if (displ != 0 && displ != 4)
423 alt = pc + displ;
424 }
425 break;
426 }
427
428 return alt;
429}
430
431static int
432swap_insn(struct task_struct *task, unsigned long addr,
433 void *old_insn, void *new_insn, int size)
434{
435 int ret;
436
437 ret = access_process_vm(task, addr, old_insn, size, 0);
438 if (ret == size)
439 ret = access_process_vm(task, addr, new_insn, size, 1);
440 return ret;
441}
442
443static void
444add_breakpoint(struct task_struct *task, struct debug_info *dbg, unsigned long addr)
445{
446 int nr = dbg->nsaved;
447
448 if (nr < 2) {
449 u32 new_insn = BREAKINST_ARM;
450 int res;
451
452 res = swap_insn(task, addr, &dbg->bp[nr].insn, &new_insn, 4);
453
454 if (res == 4) {
455 dbg->bp[nr].address = addr;
456 dbg->nsaved += 1;
457 }
458 } else
459 printk(KERN_ERR "ptrace: too many breakpoints\n");
460}
461
462/*
463 * Clear one breakpoint in the user program. We copy what the hardware
464 * does and use bit 0 of the address to indicate whether this is a Thumb
465 * breakpoint or an ARM breakpoint.
466 */
467static void clear_breakpoint(struct task_struct *task, struct debug_entry *bp)
468{
469 unsigned long addr = bp->address;
470 union debug_insn old_insn;
471 int ret;
472
473 if (addr & 1) {
474 ret = swap_insn(task, addr & ~1, &old_insn.thumb,
475 &bp->insn.thumb, 2);
476
477 if (ret != 2 || old_insn.thumb != BREAKINST_THUMB)
478 printk(KERN_ERR "%s:%d: corrupted Thumb breakpoint at "
479 "0x%08lx (0x%04x)\n", task->comm,
480 task_pid_nr(task), addr, old_insn.thumb);
481 } else {
482 ret = swap_insn(task, addr & ~3, &old_insn.arm,
483 &bp->insn.arm, 4);
484
485 if (ret != 4 || old_insn.arm != BREAKINST_ARM)
486 printk(KERN_ERR "%s:%d: corrupted ARM breakpoint at "
487 "0x%08lx (0x%08x)\n", task->comm,
488 task_pid_nr(task), addr, old_insn.arm);
489 }
490}
491
492void ptrace_set_bpt(struct task_struct *child)
493{
494 struct pt_regs *regs;
495 unsigned long pc;
496 u32 insn;
497 int res;
498
499 regs = task_pt_regs(child);
500 pc = instruction_pointer(regs);
501
502 if (thumb_mode(regs)) {
503 printk(KERN_WARNING "ptrace: can't handle thumb mode\n");
504 return;
505 }
506
507 res = read_instr(child, pc, &insn);
508 if (!res) {
509 struct debug_info *dbg = &child->thread.debug;
510 unsigned long alt;
511
512 dbg->nsaved = 0;
513
514 alt = get_branch_address(child, pc, insn);
515 if (alt)
516 add_breakpoint(child, dbg, alt);
517
518 /*
519 * Note that we ignore the result of setting the above
520 * breakpoint since it may fail. When it does, this is
521 * not so much an error, but a forewarning that we may
522 * be receiving a prefetch abort shortly.
523 *
524 * If we don't set this breakpoint here, then we can
525 * lose control of the thread during single stepping.
526 */
527 if (!alt || predicate(insn) != PREDICATE_ALWAYS)
528 add_breakpoint(child, dbg, pc + 4);
529 }
530}
531
532/*
533 * Ensure no single-step breakpoint is pending. Returns non-zero
534 * value if child was being single-stepped.
535 */
536void ptrace_cancel_bpt(struct task_struct *child)
537{
538 int i, nsaved = child->thread.debug.nsaved;
539
540 child->thread.debug.nsaved = 0;
541
542 if (nsaved > 2) {
543 printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
544 nsaved = 2;
545 }
546
547 for (i = 0; i < nsaved; i++)
548 clear_breakpoint(child, &child->thread.debug.bp[i]);
549}
550
551void user_disable_single_step(struct task_struct *task)
552{
553 task->ptrace &= ~PT_SINGLESTEP;
554 ptrace_cancel_bpt(task);
555}
556
557void user_enable_single_step(struct task_struct *task)
558{
559 task->ptrace |= PT_SINGLESTEP;
560}
561
562/* 186/*
563 * Called by kernel/ptrace.c when detaching.. 187 * Called by kernel/ptrace.c when detaching..
564 */ 188 */
565void ptrace_disable(struct task_struct *child) 189void ptrace_disable(struct task_struct *child)
566{ 190{
567 user_disable_single_step(child); 191 /* Nothing to do. */
568} 192}
569 193
570/* 194/*
@@ -574,8 +198,6 @@ void ptrace_break(struct task_struct *tsk, struct pt_regs *regs)
574{ 198{
575 siginfo_t info; 199 siginfo_t info;
576 200
577 ptrace_cancel_bpt(tsk);
578
579 info.si_signo = SIGTRAP; 201 info.si_signo = SIGTRAP;
580 info.si_errno = 0; 202 info.si_errno = 0;
581 info.si_code = TRAP_BRKPT; 203 info.si_code = TRAP_BRKPT;
@@ -687,58 +309,6 @@ static int ptrace_write_user(struct task_struct *tsk, unsigned long off,
687 return put_user_reg(tsk, off >> 2, val); 309 return put_user_reg(tsk, off >> 2, val);
688} 310}
689 311
690/*
691 * Get all user integer registers.
692 */
693static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
694{
695 struct pt_regs *regs = task_pt_regs(tsk);
696
697 return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
698}
699
700/*
701 * Set all user integer registers.
702 */
703static int ptrace_setregs(struct task_struct *tsk, void __user *uregs)
704{
705 struct pt_regs newregs;
706 int ret;
707
708 ret = -EFAULT;
709 if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
710 struct pt_regs *regs = task_pt_regs(tsk);
711
712 ret = -EINVAL;
713 if (valid_user_regs(&newregs)) {
714 *regs = newregs;
715 ret = 0;
716 }
717 }
718
719 return ret;
720}
721
722/*
723 * Get the child FPU state.
724 */
725static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
726{
727 return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
728 sizeof(struct user_fp)) ? -EFAULT : 0;
729}
730
731/*
732 * Set the child FPU state.
733 */
734static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
735{
736 struct thread_info *thread = task_thread_info(tsk);
737 thread->used_cp[1] = thread->used_cp[2] = 1;
738 return copy_from_user(&thread->fpstate, ufp,
739 sizeof(struct user_fp)) ? -EFAULT : 0;
740}
741
742#ifdef CONFIG_IWMMXT 312#ifdef CONFIG_IWMMXT
743 313
744/* 314/*
@@ -797,63 +367,454 @@ static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp)
797} 367}
798#endif 368#endif
799 369
800#ifdef CONFIG_VFP 370#ifdef CONFIG_HAVE_HW_BREAKPOINT
801/* 371/*
802 * Get the child VFP state. 372 * Convert a virtual register number into an index for a thread_info
373 * breakpoint array. Breakpoints are identified using positive numbers
374 * whilst watchpoints are negative. The registers are laid out as pairs
375 * of (address, control), each pair mapping to a unique hw_breakpoint struct.
376 * Register 0 is reserved for describing resource information.
803 */ 377 */
804static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data) 378static int ptrace_hbp_num_to_idx(long num)
805{ 379{
806 struct thread_info *thread = task_thread_info(tsk); 380 if (num < 0)
807 union vfp_state *vfp = &thread->vfpstate; 381 num = (ARM_MAX_BRP << 1) - num;
808 struct user_vfp __user *ufp = data; 382 return (num - 1) >> 1;
383}
809 384
810 vfp_sync_hwstate(thread); 385/*
386 * Returns the virtual register number for the address of the
387 * breakpoint at index idx.
388 */
389static long ptrace_hbp_idx_to_num(int idx)
390{
391 long mid = ARM_MAX_BRP << 1;
392 long num = (idx << 1) + 1;
393 return num > mid ? mid - num : num;
394}
395
396/*
397 * Handle hitting a HW-breakpoint.
398 */
399static void ptrace_hbptriggered(struct perf_event *bp, int unused,
400 struct perf_sample_data *data,
401 struct pt_regs *regs)
402{
403 struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
404 long num;
405 int i;
406 siginfo_t info;
407
408 for (i = 0; i < ARM_MAX_HBP_SLOTS; ++i)
409 if (current->thread.debug.hbp[i] == bp)
410 break;
811 411
812 /* copy the floating point registers */ 412 num = (i == ARM_MAX_HBP_SLOTS) ? 0 : ptrace_hbp_idx_to_num(i);
813 if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
814 sizeof(vfp->hard.fpregs)))
815 return -EFAULT;
816 413
817 /* copy the status and control register */ 414 info.si_signo = SIGTRAP;
818 if (put_user(vfp->hard.fpscr, &ufp->fpscr)) 415 info.si_errno = (int)num;
819 return -EFAULT; 416 info.si_code = TRAP_HWBKPT;
417 info.si_addr = (void __user *)(bkpt->trigger);
820 418
419 force_sig_info(SIGTRAP, &info, current);
420}
421
422/*
423 * Set ptrace breakpoint pointers to zero for this task.
424 * This is required in order to prevent child processes from unregistering
425 * breakpoints held by their parent.
426 */
427void clear_ptrace_hw_breakpoint(struct task_struct *tsk)
428{
429 memset(tsk->thread.debug.hbp, 0, sizeof(tsk->thread.debug.hbp));
430}
431
432/*
433 * Unregister breakpoints from this task and reset the pointers in
434 * the thread_struct.
435 */
436void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
437{
438 int i;
439 struct thread_struct *t = &tsk->thread;
440
441 for (i = 0; i < ARM_MAX_HBP_SLOTS; i++) {
442 if (t->debug.hbp[i]) {
443 unregister_hw_breakpoint(t->debug.hbp[i]);
444 t->debug.hbp[i] = NULL;
445 }
446 }
447}
448
449static u32 ptrace_get_hbp_resource_info(void)
450{
451 u8 num_brps, num_wrps, debug_arch, wp_len;
452 u32 reg = 0;
453
454 num_brps = hw_breakpoint_slots(TYPE_INST);
455 num_wrps = hw_breakpoint_slots(TYPE_DATA);
456 debug_arch = arch_get_debug_arch();
457 wp_len = arch_get_max_wp_len();
458
459 reg |= debug_arch;
460 reg <<= 8;
461 reg |= wp_len;
462 reg <<= 8;
463 reg |= num_wrps;
464 reg <<= 8;
465 reg |= num_brps;
466
467 return reg;
468}
469
470static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type)
471{
472 struct perf_event_attr attr;
473
474 ptrace_breakpoint_init(&attr);
475
476 /* Initialise fields to sane defaults. */
477 attr.bp_addr = 0;
478 attr.bp_len = HW_BREAKPOINT_LEN_4;
479 attr.bp_type = type;
480 attr.disabled = 1;
481
482 return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, tsk);
483}
484
485static int ptrace_gethbpregs(struct task_struct *tsk, long num,
486 unsigned long __user *data)
487{
488 u32 reg;
489 int idx, ret = 0;
490 struct perf_event *bp;
491 struct arch_hw_breakpoint_ctrl arch_ctrl;
492
493 if (num == 0) {
494 reg = ptrace_get_hbp_resource_info();
495 } else {
496 idx = ptrace_hbp_num_to_idx(num);
497 if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
498 ret = -EINVAL;
499 goto out;
500 }
501
502 bp = tsk->thread.debug.hbp[idx];
503 if (!bp) {
504 reg = 0;
505 goto put;
506 }
507
508 arch_ctrl = counter_arch_bp(bp)->ctrl;
509
510 /*
511 * Fix up the len because we may have adjusted it
512 * to compensate for an unaligned address.
513 */
514 while (!(arch_ctrl.len & 0x1))
515 arch_ctrl.len >>= 1;
516
517 if (num & 0x1)
518 reg = bp->attr.bp_addr;
519 else
520 reg = encode_ctrl_reg(arch_ctrl);
521 }
522
523put:
524 if (put_user(reg, data))
525 ret = -EFAULT;
526
527out:
528 return ret;
529}
530
531static int ptrace_sethbpregs(struct task_struct *tsk, long num,
532 unsigned long __user *data)
533{
534 int idx, gen_len, gen_type, implied_type, ret = 0;
535 u32 user_val;
536 struct perf_event *bp;
537 struct arch_hw_breakpoint_ctrl ctrl;
538 struct perf_event_attr attr;
539
540 if (num == 0)
541 goto out;
542 else if (num < 0)
543 implied_type = HW_BREAKPOINT_RW;
544 else
545 implied_type = HW_BREAKPOINT_X;
546
547 idx = ptrace_hbp_num_to_idx(num);
548 if (idx < 0 || idx >= ARM_MAX_HBP_SLOTS) {
549 ret = -EINVAL;
550 goto out;
551 }
552
553 if (get_user(user_val, data)) {
554 ret = -EFAULT;
555 goto out;
556 }
557
558 bp = tsk->thread.debug.hbp[idx];
559 if (!bp) {
560 bp = ptrace_hbp_create(tsk, implied_type);
561 if (IS_ERR(bp)) {
562 ret = PTR_ERR(bp);
563 goto out;
564 }
565 tsk->thread.debug.hbp[idx] = bp;
566 }
567
568 attr = bp->attr;
569
570 if (num & 0x1) {
571 /* Address */
572 attr.bp_addr = user_val;
573 } else {
574 /* Control */
575 decode_ctrl_reg(user_val, &ctrl);
576 ret = arch_bp_generic_fields(ctrl, &gen_len, &gen_type);
577 if (ret)
578 goto out;
579
580 if ((gen_type & implied_type) != gen_type) {
581 ret = -EINVAL;
582 goto out;
583 }
584
585 attr.bp_len = gen_len;
586 attr.bp_type = gen_type;
587 attr.disabled = !ctrl.enabled;
588 }
589
590 ret = modify_user_hw_breakpoint(bp, &attr);
591out:
592 return ret;
593}
594#endif
595
596/* regset get/set implementations */
597
598static int gpr_get(struct task_struct *target,
599 const struct user_regset *regset,
600 unsigned int pos, unsigned int count,
601 void *kbuf, void __user *ubuf)
602{
603 struct pt_regs *regs = task_pt_regs(target);
604
605 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
606 regs,
607 0, sizeof(*regs));
608}
609
610static int gpr_set(struct task_struct *target,
611 const struct user_regset *regset,
612 unsigned int pos, unsigned int count,
613 const void *kbuf, const void __user *ubuf)
614{
615 int ret;
616 struct pt_regs newregs;
617
618 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
619 &newregs,
620 0, sizeof(newregs));
621 if (ret)
622 return ret;
623
624 if (!valid_user_regs(&newregs))
625 return -EINVAL;
626
627 *task_pt_regs(target) = newregs;
821 return 0; 628 return 0;
822} 629}
823 630
631static int fpa_get(struct task_struct *target,
632 const struct user_regset *regset,
633 unsigned int pos, unsigned int count,
634 void *kbuf, void __user *ubuf)
635{
636 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
637 &task_thread_info(target)->fpstate,
638 0, sizeof(struct user_fp));
639}
640
641static int fpa_set(struct task_struct *target,
642 const struct user_regset *regset,
643 unsigned int pos, unsigned int count,
644 const void *kbuf, const void __user *ubuf)
645{
646 struct thread_info *thread = task_thread_info(target);
647
648 thread->used_cp[1] = thread->used_cp[2] = 1;
649
650 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
651 &thread->fpstate,
652 0, sizeof(struct user_fp));
653}
654
655#ifdef CONFIG_VFP
824/* 656/*
825 * Set the child VFP state. 657 * VFP register get/set implementations.
658 *
659 * With respect to the kernel, struct user_fp is divided into three chunks:
660 * 16 or 32 real VFP registers (d0-d15 or d0-31)
661 * These are transferred to/from the real registers in the task's
662 * vfp_hard_struct. The number of registers depends on the kernel
663 * configuration.
664 *
665 * 16 or 0 fake VFP registers (d16-d31 or empty)
666 * i.e., the user_vfp structure has space for 32 registers even if
667 * the kernel doesn't have them all.
668 *
669 * vfp_get() reads this chunk as zero where applicable
670 * vfp_set() ignores this chunk
671 *
672 * 1 word for the FPSCR
673 *
674 * The bounds-checking logic built into user_regset_copyout and friends
675 * means that we can make a simple sequence of calls to map the relevant data
676 * to/from the specified slice of the user regset structure.
826 */ 677 */
827static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data) 678static int vfp_get(struct task_struct *target,
679 const struct user_regset *regset,
680 unsigned int pos, unsigned int count,
681 void *kbuf, void __user *ubuf)
828{ 682{
829 struct thread_info *thread = task_thread_info(tsk); 683 int ret;
830 union vfp_state *vfp = &thread->vfpstate; 684 struct thread_info *thread = task_thread_info(target);
831 struct user_vfp __user *ufp = data; 685 struct vfp_hard_struct const *vfp = &thread->vfpstate.hard;
686 const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
687 const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
832 688
833 vfp_sync_hwstate(thread); 689 vfp_sync_hwstate(thread);
834 690
835 /* copy the floating point registers */ 691 ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
836 if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs, 692 &vfp->fpregs,
837 sizeof(vfp->hard.fpregs))) 693 user_fpregs_offset,
838 return -EFAULT; 694 user_fpregs_offset + sizeof(vfp->fpregs));
695 if (ret)
696 return ret;
839 697
840 /* copy the status and control register */ 698 ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
841 if (get_user(vfp->hard.fpscr, &ufp->fpscr)) 699 user_fpregs_offset + sizeof(vfp->fpregs),
842 return -EFAULT; 700 user_fpscr_offset);
701 if (ret)
702 return ret;
843 703
704 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
705 &vfp->fpscr,
706 user_fpscr_offset,
707 user_fpscr_offset + sizeof(vfp->fpscr));
708}
709
710/*
711 * For vfp_set() a read-modify-write is done on the VFP registers,
712 * in order to avoid writing back a half-modified set of registers on
713 * failure.
714 */
715static int vfp_set(struct task_struct *target,
716 const struct user_regset *regset,
717 unsigned int pos, unsigned int count,
718 const void *kbuf, const void __user *ubuf)
719{
720 int ret;
721 struct thread_info *thread = task_thread_info(target);
722 struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
723 const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
724 const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
725
726 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
727 &new_vfp.fpregs,
728 user_fpregs_offset,
729 user_fpregs_offset + sizeof(new_vfp.fpregs));
730 if (ret)
731 return ret;
732
733 ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
734 user_fpregs_offset + sizeof(new_vfp.fpregs),
735 user_fpscr_offset);
736 if (ret)
737 return ret;
738
739 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
740 &new_vfp.fpscr,
741 user_fpscr_offset,
742 user_fpscr_offset + sizeof(new_vfp.fpscr));
743 if (ret)
744 return ret;
745
746 vfp_sync_hwstate(thread);
747 thread->vfpstate.hard = new_vfp;
844 vfp_flush_hwstate(thread); 748 vfp_flush_hwstate(thread);
845 749
846 return 0; 750 return 0;
847} 751}
752#endif /* CONFIG_VFP */
753
754enum arm_regset {
755 REGSET_GPR,
756 REGSET_FPR,
757#ifdef CONFIG_VFP
758 REGSET_VFP,
848#endif 759#endif
760};
849 761
850long arch_ptrace(struct task_struct *child, long request, long addr, long data) 762static const struct user_regset arm_regsets[] = {
763 [REGSET_GPR] = {
764 .core_note_type = NT_PRSTATUS,
765 .n = ELF_NGREG,
766 .size = sizeof(u32),
767 .align = sizeof(u32),
768 .get = gpr_get,
769 .set = gpr_set
770 },
771 [REGSET_FPR] = {
772 /*
773 * For the FPA regs in fpstate, the real fields are a mixture
774 * of sizes, so pretend that the registers are word-sized:
775 */
776 .core_note_type = NT_PRFPREG,
777 .n = sizeof(struct user_fp) / sizeof(u32),
778 .size = sizeof(u32),
779 .align = sizeof(u32),
780 .get = fpa_get,
781 .set = fpa_set
782 },
783#ifdef CONFIG_VFP
784 [REGSET_VFP] = {
785 /*
786 * Pretend that the VFP regs are word-sized, since the FPSCR is
787 * a single word dangling at the end of struct user_vfp:
788 */
789 .core_note_type = NT_ARM_VFP,
790 .n = ARM_VFPREGS_SIZE / sizeof(u32),
791 .size = sizeof(u32),
792 .align = sizeof(u32),
793 .get = vfp_get,
794 .set = vfp_set
795 },
796#endif /* CONFIG_VFP */
797};
798
799static const struct user_regset_view user_arm_view = {
800 .name = "arm", .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
801 .regsets = arm_regsets, .n = ARRAY_SIZE(arm_regsets)
802};
803
804const struct user_regset_view *task_user_regset_view(struct task_struct *task)
805{
806 return &user_arm_view;
807}
808
809long arch_ptrace(struct task_struct *child, long request,
810 unsigned long addr, unsigned long data)
851{ 811{
852 int ret; 812 int ret;
813 unsigned long __user *datap = (unsigned long __user *) data;
853 814
854 switch (request) { 815 switch (request) {
855 case PTRACE_PEEKUSR: 816 case PTRACE_PEEKUSR:
856 ret = ptrace_read_user(child, addr, (unsigned long __user *)data); 817 ret = ptrace_read_user(child, addr, datap);
857 break; 818 break;
858 819
859 case PTRACE_POKEUSR: 820 case PTRACE_POKEUSR:
@@ -861,34 +822,46 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
861 break; 822 break;
862 823
863 case PTRACE_GETREGS: 824 case PTRACE_GETREGS:
864 ret = ptrace_getregs(child, (void __user *)data); 825 ret = copy_regset_to_user(child,
826 &user_arm_view, REGSET_GPR,
827 0, sizeof(struct pt_regs),
828 datap);
865 break; 829 break;
866 830
867 case PTRACE_SETREGS: 831 case PTRACE_SETREGS:
868 ret = ptrace_setregs(child, (void __user *)data); 832 ret = copy_regset_from_user(child,
833 &user_arm_view, REGSET_GPR,
834 0, sizeof(struct pt_regs),
835 datap);
869 break; 836 break;
870 837
871 case PTRACE_GETFPREGS: 838 case PTRACE_GETFPREGS:
872 ret = ptrace_getfpregs(child, (void __user *)data); 839 ret = copy_regset_to_user(child,
840 &user_arm_view, REGSET_FPR,
841 0, sizeof(union fp_state),
842 datap);
873 break; 843 break;
874 844
875 case PTRACE_SETFPREGS: 845 case PTRACE_SETFPREGS:
876 ret = ptrace_setfpregs(child, (void __user *)data); 846 ret = copy_regset_from_user(child,
847 &user_arm_view, REGSET_FPR,
848 0, sizeof(union fp_state),
849 datap);
877 break; 850 break;
878 851
879#ifdef CONFIG_IWMMXT 852#ifdef CONFIG_IWMMXT
880 case PTRACE_GETWMMXREGS: 853 case PTRACE_GETWMMXREGS:
881 ret = ptrace_getwmmxregs(child, (void __user *)data); 854 ret = ptrace_getwmmxregs(child, datap);
882 break; 855 break;
883 856
884 case PTRACE_SETWMMXREGS: 857 case PTRACE_SETWMMXREGS:
885 ret = ptrace_setwmmxregs(child, (void __user *)data); 858 ret = ptrace_setwmmxregs(child, datap);
886 break; 859 break;
887#endif 860#endif
888 861
889 case PTRACE_GET_THREAD_AREA: 862 case PTRACE_GET_THREAD_AREA:
890 ret = put_user(task_thread_info(child)->tp_value, 863 ret = put_user(task_thread_info(child)->tp_value,
891 (unsigned long __user *) data); 864 datap);
892 break; 865 break;
893 866
894 case PTRACE_SET_SYSCALL: 867 case PTRACE_SET_SYSCALL:
@@ -898,21 +871,46 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
898 871
899#ifdef CONFIG_CRUNCH 872#ifdef CONFIG_CRUNCH
900 case PTRACE_GETCRUNCHREGS: 873 case PTRACE_GETCRUNCHREGS:
901 ret = ptrace_getcrunchregs(child, (void __user *)data); 874 ret = ptrace_getcrunchregs(child, datap);
902 break; 875 break;
903 876
904 case PTRACE_SETCRUNCHREGS: 877 case PTRACE_SETCRUNCHREGS:
905 ret = ptrace_setcrunchregs(child, (void __user *)data); 878 ret = ptrace_setcrunchregs(child, datap);
906 break; 879 break;
907#endif 880#endif
908 881
909#ifdef CONFIG_VFP 882#ifdef CONFIG_VFP
910 case PTRACE_GETVFPREGS: 883 case PTRACE_GETVFPREGS:
911 ret = ptrace_getvfpregs(child, (void __user *)data); 884 ret = copy_regset_to_user(child,
885 &user_arm_view, REGSET_VFP,
886 0, ARM_VFPREGS_SIZE,
887 datap);
912 break; 888 break;
913 889
914 case PTRACE_SETVFPREGS: 890 case PTRACE_SETVFPREGS:
915 ret = ptrace_setvfpregs(child, (void __user *)data); 891 ret = copy_regset_from_user(child,
892 &user_arm_view, REGSET_VFP,
893 0, ARM_VFPREGS_SIZE,
894 datap);
895 break;
896#endif
897
898#ifdef CONFIG_HAVE_HW_BREAKPOINT
899 case PTRACE_GETHBPREGS:
900 if (ptrace_get_breakpoints(child) < 0)
901 return -ESRCH;
902
903 ret = ptrace_gethbpregs(child, addr,
904 (unsigned long __user *)data);
905 ptrace_put_breakpoints(child);
906 break;
907 case PTRACE_SETHBPREGS:
908 if (ptrace_get_breakpoints(child) < 0)
909 return -ESRCH;
910
911 ret = ptrace_sethbpregs(child, addr,
912 (unsigned long __user *)data);
913 ptrace_put_breakpoints(child);
916 break; 914 break;
917#endif 915#endif
918 916
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
deleted file mode 100644
index 3926605b82ea..000000000000
--- a/arch/arm/kernel/ptrace.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * linux/arch/arm/kernel/ptrace.h
3 *
4 * Copyright (C) 2000-2003 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/ptrace.h>
11
12extern void ptrace_cancel_bpt(struct task_struct *);
13extern void ptrace_set_bpt(struct task_struct *);
14extern void ptrace_break(struct task_struct *, struct pt_regs *);
15
16/*
17 * Send SIGTRAP if we're single-stepping
18 */
19static inline void single_step_trap(struct task_struct *task)
20{
21 if (task->ptrace & PT_SINGLESTEP) {
22 ptrace_cancel_bpt(task);
23 send_sig(SIGTRAP, task, 1);
24 }
25}
26
27static inline void single_step_clear(struct task_struct *task)
28{
29 if (task->ptrace & PT_SINGLESTEP)
30 ptrace_cancel_bpt(task);
31}
32
33static inline void single_step_set(struct task_struct *task)
34{
35 if (task->ptrace & PT_SINGLESTEP)
36 ptrace_set_bpt(task);
37}
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index fd26f8d65151..9cf4cbf8f95b 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -59,6 +59,8 @@ relocate_new_kernel:
59 ldr r2,kexec_boot_atags 59 ldr r2,kexec_boot_atags
60 mov pc,lr 60 mov pc,lr
61 61
62 .align
63
62 .globl kexec_start_address 64 .globl kexec_start_address
63kexec_start_address: 65kexec_start_address:
64 .long 0x0 66 .long 0x0
diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
index df246da4ceca..0b13a72f855d 100644
--- a/arch/arm/kernel/return_address.c
+++ b/arch/arm/kernel/return_address.c
@@ -9,6 +9,7 @@
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 */ 10 */
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/ftrace.h>
12 13
13#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) 14#if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND)
14#include <linux/sched.h> 15#include <linux/sched.h>
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
new file mode 100644
index 000000000000..9a46370fe9da
--- /dev/null
+++ b/arch/arm/kernel/sched_clock.c
@@ -0,0 +1,74 @@
1/*
2 * sched_clock.c: support for extending counters to full 64-bit ns counter
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8#include <linux/clocksource.h>
9#include <linux/init.h>
10#include <linux/jiffies.h>
11#include <linux/kernel.h>
12#include <linux/sched.h>
13#include <linux/timer.h>
14
15#include <asm/sched_clock.h>
16
17static void sched_clock_poll(unsigned long wrap_ticks);
18static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
19static void (*sched_clock_update_fn)(void);
20
21static void sched_clock_poll(unsigned long wrap_ticks)
22{
23 mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
24 sched_clock_update_fn();
25}
26
27void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
28 unsigned int clock_bits, unsigned long rate)
29{
30 unsigned long r, w;
31 u64 res, wrap;
32 char r_unit;
33
34 sched_clock_update_fn = update;
35
36 /* calculate the mult/shift to convert counter ticks to ns. */
37 clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
38
39 r = rate;
40 if (r >= 4000000) {
41 r /= 1000000;
42 r_unit = 'M';
43 } else {
44 r /= 1000;
45 r_unit = 'k';
46 }
47
48 /* calculate how many ns until we wrap */
49 wrap = cyc_to_ns((1ULL << clock_bits) - 1, cd->mult, cd->shift);
50 do_div(wrap, NSEC_PER_MSEC);
51 w = wrap;
52
53 /* calculate the ns resolution of this counter */
54 res = cyc_to_ns(1ULL, cd->mult, cd->shift);
55 pr_info("sched_clock: %u bits at %lu%cHz, resolution %lluns, wraps every %lums\n",
56 clock_bits, r, r_unit, res, w);
57
58 /*
59 * Start the timer to keep sched_clock() properly updated and
60 * sets the initial epoch.
61 */
62 sched_clock_timer.data = msecs_to_jiffies(w - (w / 10));
63 update();
64
65 /*
66 * Ensure that sched_clock() starts off at 0ns
67 */
68 cd->epoch_ns = 0;
69}
70
71void __init sched_clock_postinit(void)
72{
73 sched_clock_poll(sched_clock_timer.data);
74}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index d5231ae7355a..acbb447ac6b5 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
20#include <linux/screen_info.h> 20#include <linux/screen_info.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/kexec.h> 22#include <linux/kexec.h>
23#include <linux/of_fdt.h>
23#include <linux/crash_dump.h> 24#include <linux/crash_dump.h>
24#include <linux/root_dev.h> 25#include <linux/root_dev.h>
25#include <linux/cpu.h> 26#include <linux/cpu.h>
@@ -36,11 +37,13 @@
36#include <asm/procinfo.h> 37#include <asm/procinfo.h>
37#include <asm/sections.h> 38#include <asm/sections.h>
38#include <asm/setup.h> 39#include <asm/setup.h>
40#include <asm/smp_plat.h>
39#include <asm/mach-types.h> 41#include <asm/mach-types.h>
40#include <asm/cacheflush.h> 42#include <asm/cacheflush.h>
41#include <asm/cachetype.h> 43#include <asm/cachetype.h>
42#include <asm/tlbflush.h> 44#include <asm/tlbflush.h>
43 45
46#include <asm/prom.h>
44#include <asm/mach/arch.h> 47#include <asm/mach/arch.h>
45#include <asm/mach/irq.h> 48#include <asm/mach/irq.h>
46#include <asm/mach/time.h> 49#include <asm/mach/time.h>
@@ -70,13 +73,14 @@ __setup("fpe=", fpe_setup);
70#endif 73#endif
71 74
72extern void paging_init(struct machine_desc *desc); 75extern void paging_init(struct machine_desc *desc);
76extern void sanity_check_meminfo(void);
73extern void reboot_setup(char *str); 77extern void reboot_setup(char *str);
74 78
75unsigned int processor_id; 79unsigned int processor_id;
76EXPORT_SYMBOL(processor_id); 80EXPORT_SYMBOL(processor_id);
77unsigned int __machine_arch_type; 81unsigned int __machine_arch_type __read_mostly;
78EXPORT_SYMBOL(__machine_arch_type); 82EXPORT_SYMBOL(__machine_arch_type);
79unsigned int cacheid; 83unsigned int cacheid __read_mostly;
80EXPORT_SYMBOL(cacheid); 84EXPORT_SYMBOL(cacheid);
81 85
82unsigned int __atags_pointer __initdata; 86unsigned int __atags_pointer __initdata;
@@ -90,24 +94,24 @@ EXPORT_SYMBOL(system_serial_low);
90unsigned int system_serial_high; 94unsigned int system_serial_high;
91EXPORT_SYMBOL(system_serial_high); 95EXPORT_SYMBOL(system_serial_high);
92 96
93unsigned int elf_hwcap; 97unsigned int elf_hwcap __read_mostly;
94EXPORT_SYMBOL(elf_hwcap); 98EXPORT_SYMBOL(elf_hwcap);
95 99
96 100
97#ifdef MULTI_CPU 101#ifdef MULTI_CPU
98struct processor processor; 102struct processor processor __read_mostly;
99#endif 103#endif
100#ifdef MULTI_TLB 104#ifdef MULTI_TLB
101struct cpu_tlb_fns cpu_tlb; 105struct cpu_tlb_fns cpu_tlb __read_mostly;
102#endif 106#endif
103#ifdef MULTI_USER 107#ifdef MULTI_USER
104struct cpu_user_fns cpu_user; 108struct cpu_user_fns cpu_user __read_mostly;
105#endif 109#endif
106#ifdef MULTI_CACHE 110#ifdef MULTI_CACHE
107struct cpu_cache_fns cpu_cache; 111struct cpu_cache_fns cpu_cache __read_mostly;
108#endif 112#endif
109#ifdef CONFIG_OUTER_CACHE 113#ifdef CONFIG_OUTER_CACHE
110struct outer_cache_fns outer_cache; 114struct outer_cache_fns outer_cache __read_mostly;
111EXPORT_SYMBOL(outer_cache); 115EXPORT_SYMBOL(outer_cache);
112#endif 116#endif
113 117
@@ -125,6 +129,7 @@ EXPORT_SYMBOL(elf_platform);
125static const char *cpu_name; 129static const char *cpu_name;
126static const char *machine_name; 130static const char *machine_name;
127static char __initdata cmd_line[COMMAND_LINE_SIZE]; 131static char __initdata cmd_line[COMMAND_LINE_SIZE];
132struct machine_desc *machine_desc __initdata;
128 133
129static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; 134static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
130static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; 135static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -224,8 +229,8 @@ int cpu_architecture(void)
224 * Register 0 and check for VMSAv7 or PMSAv7 */ 229 * Register 0 and check for VMSAv7 or PMSAv7 */
225 asm("mrc p15, 0, %0, c0, c1, 4" 230 asm("mrc p15, 0, %0, c0, c1, 4"
226 : "=r" (mmfr0)); 231 : "=r" (mmfr0));
227 if ((mmfr0 & 0x0000000f) == 0x00000003 || 232 if ((mmfr0 & 0x0000000f) >= 0x00000003 ||
228 (mmfr0 & 0x000000f0) == 0x00000030) 233 (mmfr0 & 0x000000f0) >= 0x00000030)
229 cpu_arch = CPU_ARCH_ARMv7; 234 cpu_arch = CPU_ARCH_ARMv7;
230 else if ((mmfr0 & 0x0000000f) == 0x00000002 || 235 else if ((mmfr0 & 0x0000000f) == 0x00000002 ||
231 (mmfr0 & 0x000000f0) == 0x00000020) 236 (mmfr0 & 0x000000f0) == 0x00000020)
@@ -238,6 +243,35 @@ int cpu_architecture(void)
238 return cpu_arch; 243 return cpu_arch;
239} 244}
240 245
246static int cpu_has_aliasing_icache(unsigned int arch)
247{
248 int aliasing_icache;
249 unsigned int id_reg, num_sets, line_size;
250
251 /* arch specifies the register format */
252 switch (arch) {
253 case CPU_ARCH_ARMv7:
254 asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
255 : /* No output operands */
256 : "r" (1));
257 isb();
258 asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
259 : "=r" (id_reg));
260 line_size = 4 << ((id_reg & 0x7) + 2);
261 num_sets = ((id_reg >> 13) & 0x7fff) + 1;
262 aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
263 break;
264 case CPU_ARCH_ARMv6:
265 aliasing_icache = read_cpuid_cachetype() & (1 << 11);
266 break;
267 default:
268 /* I-cache aliases will be handled by D-cache aliasing code */
269 aliasing_icache = 0;
270 }
271
272 return aliasing_icache;
273}
274
241static void __init cacheid_init(void) 275static void __init cacheid_init(void)
242{ 276{
243 unsigned int cachetype = read_cpuid_cachetype(); 277 unsigned int cachetype = read_cpuid_cachetype();
@@ -249,10 +283,15 @@ static void __init cacheid_init(void)
249 cacheid = CACHEID_VIPT_NONALIASING; 283 cacheid = CACHEID_VIPT_NONALIASING;
250 if ((cachetype & (3 << 14)) == 1 << 14) 284 if ((cachetype & (3 << 14)) == 1 << 14)
251 cacheid |= CACHEID_ASID_TAGGED; 285 cacheid |= CACHEID_ASID_TAGGED;
252 } else if (cachetype & (1 << 23)) 286 else if (cpu_has_aliasing_icache(CPU_ARCH_ARMv7))
287 cacheid |= CACHEID_VIPT_I_ALIASING;
288 } else if (cachetype & (1 << 23)) {
253 cacheid = CACHEID_VIPT_ALIASING; 289 cacheid = CACHEID_VIPT_ALIASING;
254 else 290 } else {
255 cacheid = CACHEID_VIPT_NONALIASING; 291 cacheid = CACHEID_VIPT_NONALIASING;
292 if (cpu_has_aliasing_icache(CPU_ARCH_ARMv6))
293 cacheid |= CACHEID_VIPT_I_ALIASING;
294 }
256 } else { 295 } else {
257 cacheid = CACHEID_VIVT; 296 cacheid = CACHEID_VIVT;
258 } 297 }
@@ -263,7 +302,7 @@ static void __init cacheid_init(void)
263 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", 302 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown",
264 cache_is_vivt() ? "VIVT" : 303 cache_is_vivt() ? "VIVT" :
265 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : 304 icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" :
266 cache_is_vipt_aliasing() ? "VIPT aliasing" : 305 icache_is_vipt_aliasing() ? "VIPT aliasing" :
267 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); 306 cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown");
268} 307}
269 308
@@ -272,7 +311,22 @@ static void __init cacheid_init(void)
272 * already provide the required functionality. 311 * already provide the required functionality.
273 */ 312 */
274extern struct proc_info_list *lookup_processor_type(unsigned int); 313extern struct proc_info_list *lookup_processor_type(unsigned int);
275extern struct machine_desc *lookup_machine_type(unsigned int); 314
315void __init early_print(const char *str, ...)
316{
317 extern void printascii(const char *);
318 char buf[256];
319 va_list ap;
320
321 va_start(ap, str);
322 vsnprintf(buf, sizeof(buf), str, ap);
323 va_end(ap);
324
325#ifdef CONFIG_DEBUG_LL
326 printascii(buf);
327#endif
328 printk("%s", buf);
329}
276 330
277static void __init feat_v6_fixup(void) 331static void __init feat_v6_fixup(void)
278{ 332{
@@ -388,32 +442,27 @@ void cpu_init(void)
388 : "r14"); 442 : "r14");
389} 443}
390 444
391static struct machine_desc * __init setup_machine(unsigned int nr) 445void __init dump_machine_table(void)
392{ 446{
393 struct machine_desc *list; 447 struct machine_desc *p;
394 448
395 /* 449 early_print("Available machine support:\n\nID (hex)\tNAME\n");
396 * locate machine in the list of supported machines. 450 for_each_machine_desc(p)
397 */ 451 early_print("%08x\t%s\n", p->nr, p->name);
398 list = lookup_machine_type(nr);
399 if (!list) {
400 printk("Machine configuration botched (nr %d), unable "
401 "to continue.\n", nr);
402 while (1);
403 }
404 452
405 printk("Machine: %s\n", list->name); 453 early_print("\nPlease check your kernel config and/or bootloader.\n");
406 454
407 return list; 455 while (true)
456 /* can't use cpu_relax() here as it may require MMU setup */;
408} 457}
409 458
410static int __init arm_add_memory(unsigned long start, unsigned long size) 459int __init arm_add_memory(phys_addr_t start, unsigned long size)
411{ 460{
412 struct membank *bank = &meminfo.bank[meminfo.nr_banks]; 461 struct membank *bank = &meminfo.bank[meminfo.nr_banks];
413 462
414 if (meminfo.nr_banks >= NR_BANKS) { 463 if (meminfo.nr_banks >= NR_BANKS) {
415 printk(KERN_CRIT "NR_BANKS too low, " 464 printk(KERN_CRIT "NR_BANKS too low, "
416 "ignoring memory at %#lx\n", start); 465 "ignoring memory at 0x%08llx\n", (long long)start);
417 return -EINVAL; 466 return -EINVAL;
418 } 467 }
419 468
@@ -443,7 +492,8 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
443static int __init early_mem(char *p) 492static int __init early_mem(char *p)
444{ 493{
445 static int usermem __initdata = 0; 494 static int usermem __initdata = 0;
446 unsigned long size, start; 495 unsigned long size;
496 phys_addr_t start;
447 char *endp; 497 char *endp;
448 498
449 /* 499 /*
@@ -482,25 +532,21 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
482#endif 532#endif
483} 533}
484 534
485static void __init 535static void __init request_standard_resources(struct machine_desc *mdesc)
486request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc)
487{ 536{
537 struct memblock_region *region;
488 struct resource *res; 538 struct resource *res;
489 int i;
490 539
491 kernel_code.start = virt_to_phys(_text); 540 kernel_code.start = virt_to_phys(_text);
492 kernel_code.end = virt_to_phys(_etext - 1); 541 kernel_code.end = virt_to_phys(_etext - 1);
493 kernel_data.start = virt_to_phys(_data); 542 kernel_data.start = virt_to_phys(_sdata);
494 kernel_data.end = virt_to_phys(_end - 1); 543 kernel_data.end = virt_to_phys(_end - 1);
495 544
496 for (i = 0; i < mi->nr_banks; i++) { 545 for_each_memblock(memory, region) {
497 if (mi->bank[i].size == 0)
498 continue;
499
500 res = alloc_bootmem_low(sizeof(*res)); 546 res = alloc_bootmem_low(sizeof(*res));
501 res->name = "System RAM"; 547 res->name = "System RAM";
502 res->start = mi->bank[i].start; 548 res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
503 res->end = mi->bank[i].start + mi->bank[i].size - 1; 549 res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
504 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 550 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
505 551
506 request_resource(&iomem_resource, res); 552 request_resource(&iomem_resource, res);
@@ -614,15 +660,22 @@ static int __init parse_tag_revision(const struct tag *tag)
614 660
615__tagtable(ATAG_REVISION, parse_tag_revision); 661__tagtable(ATAG_REVISION, parse_tag_revision);
616 662
617#ifndef CONFIG_CMDLINE_FORCE
618static int __init parse_tag_cmdline(const struct tag *tag) 663static int __init parse_tag_cmdline(const struct tag *tag)
619{ 664{
620 strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); 665#if defined(CONFIG_CMDLINE_EXTEND)
666 strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
667 strlcat(default_command_line, tag->u.cmdline.cmdline,
668 COMMAND_LINE_SIZE);
669#elif defined(CONFIG_CMDLINE_FORCE)
670 pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
671#else
672 strlcpy(default_command_line, tag->u.cmdline.cmdline,
673 COMMAND_LINE_SIZE);
674#endif
621 return 0; 675 return 0;
622} 676}
623 677
624__tagtable(ATAG_CMDLINE, parse_tag_cmdline); 678__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
625#endif /* CONFIG_CMDLINE_FORCE */
626 679
627/* 680/*
628 * Scan the tag table for this tag, and call its parse function. 681 * Scan the tag table for this tag, and call its parse function.
@@ -669,17 +722,15 @@ static struct init_tags {
669 { tag_size(tag_core), ATAG_CORE }, 722 { tag_size(tag_core), ATAG_CORE },
670 { 1, PAGE_SIZE, 0xff }, 723 { 1, PAGE_SIZE, 0xff },
671 { tag_size(tag_mem32), ATAG_MEM }, 724 { tag_size(tag_mem32), ATAG_MEM },
672 { MEM_SIZE, PHYS_OFFSET }, 725 { MEM_SIZE },
673 { 0, ATAG_NONE } 726 { 0, ATAG_NONE }
674}; 727};
675 728
676static void (*init_machine)(void) __initdata;
677
678static int __init customize_machine(void) 729static int __init customize_machine(void)
679{ 730{
680 /* customizes platform devices, or adds new ones */ 731 /* customizes platform devices, or adds new ones */
681 if (init_machine) 732 if (machine_desc->init_machine)
682 init_machine(); 733 machine_desc->init_machine();
683 return 0; 734 return 0;
684} 735}
685arch_initcall(customize_machine); 736arch_initcall(customize_machine);
@@ -733,30 +784,6 @@ static void __init reserve_crashkernel(void)
733static inline void reserve_crashkernel(void) {} 784static inline void reserve_crashkernel(void) {}
734#endif /* CONFIG_KEXEC */ 785#endif /* CONFIG_KEXEC */
735 786
736/*
737 * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
738 * is_kdump_kernel() to determine if we are booting after a panic. Hence
739 * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
740 */
741
742#ifdef CONFIG_CRASH_DUMP
743/*
744 * elfcorehdr= specifies the location of elf core header stored by the crashed
745 * kernel. This option will be passed by kexec loader to the capture kernel.
746 */
747static int __init setup_elfcorehdr(char *arg)
748{
749 char *end;
750
751 if (!arg)
752 return -EINVAL;
753
754 elfcorehdr_addr = memparse(arg, &end);
755 return end > arg ? 0 : -EINVAL;
756}
757early_param("elfcorehdr", setup_elfcorehdr);
758#endif /* CONFIG_CRASH_DUMP */
759
760static void __init squash_mem_tags(struct tag *tag) 787static void __init squash_mem_tags(struct tag *tag)
761{ 788{
762 for (; tag->hdr.size; tag = tag_next(tag)) 789 for (; tag->hdr.size; tag = tag_next(tag))
@@ -764,25 +791,51 @@ static void __init squash_mem_tags(struct tag *tag)
764 tag->hdr.tag = ATAG_NONE; 791 tag->hdr.tag = ATAG_NONE;
765} 792}
766 793
767void __init setup_arch(char **cmdline_p) 794static struct machine_desc * __init setup_machine_tags(unsigned int nr)
768{ 795{
769 struct tag *tags = (struct tag *)&init_tags; 796 struct tag *tags = (struct tag *)&init_tags;
770 struct machine_desc *mdesc; 797 struct machine_desc *mdesc = NULL, *p;
771 char *from = default_command_line; 798 char *from = default_command_line;
772 799
773 unwind_init(); 800 init_tags.mem.start = PHYS_OFFSET;
774 801
775 setup_processor(); 802 /*
776 mdesc = setup_machine(machine_arch_type); 803 * locate machine in the list of supported machines.
777 machine_name = mdesc->name; 804 */
805 for_each_machine_desc(p)
806 if (nr == p->nr) {
807 printk("Machine: %s\n", p->name);
808 mdesc = p;
809 break;
810 }
778 811
779 if (mdesc->soft_reboot) 812 if (!mdesc) {
780 reboot_setup("s"); 813 early_print("\nError: unrecognized/unsupported machine ID"
814 " (r1 = 0x%08x).\n\n", nr);
815 dump_machine_table(); /* does not return */
816 }
781 817
782 if (__atags_pointer) 818 if (__atags_pointer)
783 tags = phys_to_virt(__atags_pointer); 819 tags = phys_to_virt(__atags_pointer);
784 else if (mdesc->boot_params) 820 else if (mdesc->boot_params) {
785 tags = phys_to_virt(mdesc->boot_params); 821#ifdef CONFIG_MMU
822 /*
823 * We still are executing with a minimal MMU mapping created
824 * with the presumption that the machine default for this
825 * is located in the first MB of RAM. Anything else will
826 * fault and silently hang the kernel at this point.
827 */
828 if (mdesc->boot_params < PHYS_OFFSET ||
829 mdesc->boot_params >= PHYS_OFFSET + SZ_1M) {
830 printk(KERN_WARNING
831 "Default boot params at physical 0x%08lx out of reach\n",
832 mdesc->boot_params);
833 } else
834#endif
835 {
836 tags = phys_to_virt(mdesc->boot_params);
837 }
838 }
786 839
787#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) 840#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
788 /* 841 /*
@@ -792,8 +845,17 @@ void __init setup_arch(char **cmdline_p)
792 if (tags->hdr.tag != ATAG_CORE) 845 if (tags->hdr.tag != ATAG_CORE)
793 convert_to_tag_list(tags); 846 convert_to_tag_list(tags);
794#endif 847#endif
795 if (tags->hdr.tag != ATAG_CORE) 848
849 if (tags->hdr.tag != ATAG_CORE) {
850#if defined(CONFIG_OF)
851 /*
852 * If CONFIG_OF is set, then assume this is a reasonably
853 * modern system that should pass boot parameters
854 */
855 early_print("Warning: Neither atags nor dtb found\n");
856#endif
796 tags = (struct tag *)&init_tags; 857 tags = (struct tag *)&init_tags;
858 }
797 859
798 if (mdesc->fixup) 860 if (mdesc->fixup)
799 mdesc->fixup(mdesc, tags, &from, &meminfo); 861 mdesc->fixup(mdesc, tags, &from, &meminfo);
@@ -805,40 +867,60 @@ void __init setup_arch(char **cmdline_p)
805 parse_tags(tags); 867 parse_tags(tags);
806 } 868 }
807 869
870 /* parse_early_param needs a boot_command_line */
871 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
872
873 return mdesc;
874}
875
876
877void __init setup_arch(char **cmdline_p)
878{
879 struct machine_desc *mdesc;
880
881 unwind_init();
882
883 setup_processor();
884 mdesc = setup_machine_fdt(__atags_pointer);
885 if (!mdesc)
886 mdesc = setup_machine_tags(machine_arch_type);
887 machine_desc = mdesc;
888 machine_name = mdesc->name;
889
890 if (mdesc->soft_reboot)
891 reboot_setup("s");
892
808 init_mm.start_code = (unsigned long) _text; 893 init_mm.start_code = (unsigned long) _text;
809 init_mm.end_code = (unsigned long) _etext; 894 init_mm.end_code = (unsigned long) _etext;
810 init_mm.end_data = (unsigned long) _edata; 895 init_mm.end_data = (unsigned long) _edata;
811 init_mm.brk = (unsigned long) _end; 896 init_mm.brk = (unsigned long) _end;
812 897
813 /* parse_early_param needs a boot_command_line */
814 strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
815
816 /* populate cmd_line too for later use, preserving boot_command_line */ 898 /* populate cmd_line too for later use, preserving boot_command_line */
817 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE); 899 strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
818 *cmdline_p = cmd_line; 900 *cmdline_p = cmd_line;
819 901
820 parse_early_param(); 902 parse_early_param();
821 903
904 sanity_check_meminfo();
822 arm_memblock_init(&meminfo, mdesc); 905 arm_memblock_init(&meminfo, mdesc);
823 906
824 paging_init(mdesc); 907 paging_init(mdesc);
825 request_standard_resources(&meminfo, mdesc); 908 request_standard_resources(mdesc);
909
910 unflatten_device_tree();
826 911
827#ifdef CONFIG_SMP 912#ifdef CONFIG_SMP
828 smp_init_cpus(); 913 if (is_smp())
914 smp_init_cpus();
829#endif 915#endif
830 reserve_crashkernel(); 916 reserve_crashkernel();
831 917
832 cpu_init(); 918 cpu_init();
833 tcm_init(); 919 tcm_init();
834 920
835 /* 921#ifdef CONFIG_MULTI_IRQ_HANDLER
836 * Set up various architecture-specific pointers 922 handle_arch_irq = mdesc->handle_irq;
837 */ 923#endif
838 arch_nr_irqs = mdesc->nr_irqs;
839 init_arch_irq = mdesc->init_irq;
840 system_timer = mdesc->timer;
841 init_machine = mdesc->init_machine;
842 924
843#ifdef CONFIG_VT 925#ifdef CONFIG_VT
844#if defined(CONFIG_VGA_CONSOLE) 926#if defined(CONFIG_VGA_CONSOLE)
@@ -848,6 +930,9 @@ void __init setup_arch(char **cmdline_p)
848#endif 930#endif
849#endif 931#endif
850 early_trap_init(); 932 early_trap_init();
933
934 if (mdesc->init_early)
935 mdesc->init_early();
851} 936}
852 937
853 938
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 907d5a620bca..0340224cf73c 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -20,7 +20,6 @@
20#include <asm/unistd.h> 20#include <asm/unistd.h>
21#include <asm/vfp.h> 21#include <asm/vfp.h>
22 22
23#include "ptrace.h"
24#include "signal.h" 23#include "signal.h"
25 24
26#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 25#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -348,8 +347,6 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
348 if (restore_sigframe(regs, frame)) 347 if (restore_sigframe(regs, frame))
349 goto badframe; 348 goto badframe;
350 349
351 single_step_trap(current);
352
353 return regs->ARM_r0; 350 return regs->ARM_r0;
354 351
355badframe: 352badframe:
@@ -383,8 +380,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
383 if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) 380 if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT)
384 goto badframe; 381 goto badframe;
385 382
386 single_step_trap(current);
387
388 return regs->ARM_r0; 383 return regs->ARM_r0;
389 384
390badframe: 385badframe:
@@ -474,7 +469,9 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
474 unsigned long handler = (unsigned long)ka->sa.sa_handler; 469 unsigned long handler = (unsigned long)ka->sa.sa_handler;
475 unsigned long retcode; 470 unsigned long retcode;
476 int thumb = 0; 471 int thumb = 0;
477 unsigned long cpsr = regs->ARM_cpsr & ~PSR_f; 472 unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
473
474 cpsr |= PSR_ENDSTATE;
478 475
479 /* 476 /*
480 * Maybe we need to deliver a 32-bit signal to a 26-bit task. 477 * Maybe we need to deliver a 32-bit signal to a 26-bit task.
@@ -600,19 +597,13 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
600 return err; 597 return err;
601} 598}
602 599
603static inline void setup_syscall_restart(struct pt_regs *regs)
604{
605 regs->ARM_r0 = regs->ARM_ORIG_r0;
606 regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
607}
608
609/* 600/*
610 * OK, we're invoking a handler 601 * OK, we're invoking a handler
611 */ 602 */
612static int 603static int
613handle_signal(unsigned long sig, struct k_sigaction *ka, 604handle_signal(unsigned long sig, struct k_sigaction *ka,
614 siginfo_t *info, sigset_t *oldset, 605 siginfo_t *info, sigset_t *oldset,
615 struct pt_regs * regs, int syscall) 606 struct pt_regs * regs)
616{ 607{
617 struct thread_info *thread = current_thread_info(); 608 struct thread_info *thread = current_thread_info();
618 struct task_struct *tsk = current; 609 struct task_struct *tsk = current;
@@ -620,26 +611,6 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
620 int ret; 611 int ret;
621 612
622 /* 613 /*
623 * If we were from a system call, check for system call restarting...
624 */
625 if (syscall) {
626 switch (regs->ARM_r0) {
627 case -ERESTART_RESTARTBLOCK:
628 case -ERESTARTNOHAND:
629 regs->ARM_r0 = -EINTR;
630 break;
631 case -ERESTARTSYS:
632 if (!(ka->sa.sa_flags & SA_RESTART)) {
633 regs->ARM_r0 = -EINTR;
634 break;
635 }
636 /* fallthrough */
637 case -ERESTARTNOINTR:
638 setup_syscall_restart(regs);
639 }
640 }
641
642 /*
643 * translate the signal 614 * translate the signal
644 */ 615 */
645 if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap) 616 if (usig < 32 && thread->exec_domain && thread->exec_domain->signal_invmap)
@@ -688,6 +659,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
688 */ 659 */
689static void do_signal(struct pt_regs *regs, int syscall) 660static void do_signal(struct pt_regs *regs, int syscall)
690{ 661{
662 unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
691 struct k_sigaction ka; 663 struct k_sigaction ka;
692 siginfo_t info; 664 siginfo_t info;
693 int signr; 665 int signr;
@@ -701,20 +673,61 @@ static void do_signal(struct pt_regs *regs, int syscall)
701 if (!user_mode(regs)) 673 if (!user_mode(regs))
702 return; 674 return;
703 675
676 /*
677 * If we were from a system call, check for system call restarting...
678 */
679 if (syscall) {
680 continue_addr = regs->ARM_pc;
681 restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4);
682 retval = regs->ARM_r0;
683
684 /*
685 * Prepare for system call restart. We do this here so that a
686 * debugger will see the already changed PSW.
687 */
688 switch (retval) {
689 case -ERESTARTNOHAND:
690 case -ERESTARTSYS:
691 case -ERESTARTNOINTR:
692 regs->ARM_r0 = regs->ARM_ORIG_r0;
693 regs->ARM_pc = restart_addr;
694 break;
695 case -ERESTART_RESTARTBLOCK:
696 regs->ARM_r0 = -EINTR;
697 break;
698 }
699 }
700
704 if (try_to_freeze()) 701 if (try_to_freeze())
705 goto no_signal; 702 goto no_signal;
706 703
707 single_step_clear(current); 704 /*
708 705 * Get the signal to deliver. When running under ptrace, at this
706 * point the debugger may change all our registers ...
707 */
709 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 708 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
710 if (signr > 0) { 709 if (signr > 0) {
711 sigset_t *oldset; 710 sigset_t *oldset;
712 711
712 /*
713 * Depending on the signal settings we may need to revert the
714 * decision to restart the system call. But skip this if a
715 * debugger has chosen to restart at a different PC.
716 */
717 if (regs->ARM_pc == restart_addr) {
718 if (retval == -ERESTARTNOHAND
719 || (retval == -ERESTARTSYS
720 && !(ka.sa.sa_flags & SA_RESTART))) {
721 regs->ARM_r0 = -EINTR;
722 regs->ARM_pc = continue_addr;
723 }
724 }
725
713 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 726 if (test_thread_flag(TIF_RESTORE_SIGMASK))
714 oldset = &current->saved_sigmask; 727 oldset = &current->saved_sigmask;
715 else 728 else
716 oldset = &current->blocked; 729 oldset = &current->blocked;
717 if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { 730 if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
718 /* 731 /*
719 * A signal was successfully delivered; the saved 732 * A signal was successfully delivered; the saved
720 * sigmask will have been stored in the signal frame, 733 * sigmask will have been stored in the signal frame,
@@ -724,16 +737,18 @@ static void do_signal(struct pt_regs *regs, int syscall)
724 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 737 if (test_thread_flag(TIF_RESTORE_SIGMASK))
725 clear_thread_flag(TIF_RESTORE_SIGMASK); 738 clear_thread_flag(TIF_RESTORE_SIGMASK);
726 } 739 }
727 single_step_set(current);
728 return; 740 return;
729 } 741 }
730 742
731 no_signal: 743 no_signal:
732 /*
733 * No signal to deliver to the process - restart the syscall.
734 */
735 if (syscall) { 744 if (syscall) {
736 if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { 745 /*
746 * Handle restarting a different system call. As above,
747 * if a debugger has chosen to restart at a different PC,
748 * ignore the restart.
749 */
750 if (retval == -ERESTART_RESTARTBLOCK
751 && regs->ARM_pc == continue_addr) {
737 if (thumb_mode(regs)) { 752 if (thumb_mode(regs)) {
738 regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; 753 regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
739 regs->ARM_pc -= 2; 754 regs->ARM_pc -= 2;
@@ -756,11 +771,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
756#endif 771#endif
757 } 772 }
758 } 773 }
759 if (regs->ARM_r0 == -ERESTARTNOHAND ||
760 regs->ARM_r0 == -ERESTARTSYS ||
761 regs->ARM_r0 == -ERESTARTNOINTR) {
762 setup_syscall_restart(regs);
763 }
764 774
765 /* If there's no signal to deliver, we just put the saved sigmask 775 /* If there's no signal to deliver, we just put the saved sigmask
766 * back. 776 * back.
@@ -770,7 +780,6 @@ static void do_signal(struct pt_regs *regs, int syscall)
770 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 780 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
771 } 781 }
772 } 782 }
773 single_step_set(current);
774} 783}
775 784
776asmlinkage void 785asmlinkage void
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
new file mode 100644
index 000000000000..6398ead9d1c0
--- /dev/null
+++ b/arch/arm/kernel/sleep.S
@@ -0,0 +1,142 @@
1#include <linux/linkage.h>
2#include <linux/threads.h>
3#include <asm/asm-offsets.h>
4#include <asm/assembler.h>
5#include <asm/glue-cache.h>
6#include <asm/glue-proc.h>
7#include <asm/system.h>
8 .text
9
10/*
11 * Save CPU state for a suspend
12 * r1 = v:p offset
13 * r3 = virtual return function
14 * Note: sp is decremented to allocate space for CPU state on stack
15 * r0-r3,r9,r10,lr corrupted
16 */
17ENTRY(cpu_suspend)
18 mov r9, lr
19#ifdef MULTI_CPU
20 ldr r10, =processor
21 mov r2, sp @ current virtual SP
22 ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state
23 ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function
24 sub sp, sp, r0 @ allocate CPU state on stack
25 mov r0, sp @ save pointer
26 add ip, ip, r1 @ convert resume fn to phys
27 stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn
28 ldr r3, =sleep_save_sp
29 add r2, sp, r1 @ convert SP to phys
30#ifdef CONFIG_SMP
31 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
32 ALT_UP(mov lr, #0)
33 and lr, lr, #15
34 str r2, [r3, lr, lsl #2] @ save phys SP
35#else
36 str r2, [r3] @ save phys SP
37#endif
38 mov lr, pc
39 ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state
40#else
41 mov r2, sp @ current virtual SP
42 ldr r0, =cpu_suspend_size
43 sub sp, sp, r0 @ allocate CPU state on stack
44 mov r0, sp @ save pointer
45 stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn
46 ldr r3, =sleep_save_sp
47 add r2, sp, r1 @ convert SP to phys
48#ifdef CONFIG_SMP
49 ALT_SMP(mrc p15, 0, lr, c0, c0, 5)
50 ALT_UP(mov lr, #0)
51 and lr, lr, #15
52 str r2, [r3, lr, lsl #2] @ save phys SP
53#else
54 str r2, [r3] @ save phys SP
55#endif
56 bl cpu_do_suspend
57#endif
58
59 @ flush data cache
60#ifdef MULTI_CACHE
61 ldr r10, =cpu_cache
62 mov lr, r9
63 ldr pc, [r10, #CACHE_FLUSH_KERN_ALL]
64#else
65 mov lr, r9
66 b __cpuc_flush_kern_all
67#endif
68ENDPROC(cpu_suspend)
69 .ltorg
70
71/*
72 * r0 = control register value
73 * r1 = v:p offset (preserved by cpu_do_resume)
74 * r2 = phys page table base
75 * r3 = L1 section flags
76 */
77ENTRY(cpu_resume_mmu)
78 adr r4, cpu_resume_turn_mmu_on
79 mov r4, r4, lsr #20
80 orr r3, r3, r4, lsl #20
81 ldr r5, [r2, r4, lsl #2] @ save old mapping
82 str r3, [r2, r4, lsl #2] @ setup 1:1 mapping for mmu code
83 sub r2, r2, r1
84 ldr r3, =cpu_resume_after_mmu
85 bic r1, r0, #CR_C @ ensure D-cache is disabled
86 b cpu_resume_turn_mmu_on
87ENDPROC(cpu_resume_mmu)
88 .ltorg
89 .align 5
90cpu_resume_turn_mmu_on:
91 mcr p15, 0, r1, c1, c0, 0 @ turn on MMU, I-cache, etc
92 mrc p15, 0, r1, c0, c0, 0 @ read id reg
93 mov r1, r1
94 mov r1, r1
95 mov pc, r3 @ jump to virtual address
96ENDPROC(cpu_resume_turn_mmu_on)
97cpu_resume_after_mmu:
98 str r5, [r2, r4, lsl #2] @ restore old mapping
99 mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache
100 mov pc, lr
101ENDPROC(cpu_resume_after_mmu)
102
103/*
104 * Note: Yes, part of the following code is located into the .data section.
105 * This is to allow sleep_save_sp to be accessed with a relative load
106 * while we can't rely on any MMU translation. We could have put
107 * sleep_save_sp in the .text section as well, but some setups might
108 * insist on it to be truly read-only.
109 */
110 .data
111 .align
112ENTRY(cpu_resume)
113#ifdef CONFIG_SMP
114 adr r0, sleep_save_sp
115 ALT_SMP(mrc p15, 0, r1, c0, c0, 5)
116 ALT_UP(mov r1, #0)
117 and r1, r1, #15
118 ldr r0, [r0, r1, lsl #2] @ stack phys addr
119#else
120 ldr r0, sleep_save_sp @ stack phys addr
121#endif
122 setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
123#ifdef MULTI_CPU
124 @ load v:p, stack, return fn, resume fn
125 ARM( ldmia r0!, {r1, sp, lr, pc} )
126THUMB( ldmia r0!, {r1, r2, r3, r4} )
127THUMB( mov sp, r2 )
128THUMB( mov lr, r3 )
129THUMB( bx r4 )
130#else
131 @ load v:p, stack, return fn
132 ARM( ldmia r0!, {r1, sp, lr} )
133THUMB( ldmia r0!, {r1, r2, lr} )
134THUMB( mov sp, r2 )
135 b cpu_do_resume
136#endif
137ENDPROC(cpu_resume)
138
139sleep_save_sp:
140 .rept CONFIG_NR_CPUS
141 .long 0 @ preserve stack phys ptr here
142 .endr
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index b72fbf3d043c..5a574296ace0 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -16,6 +16,7 @@
16#include <linux/cache.h> 16#include <linux/cache.h>
17#include <linux/profile.h> 17#include <linux/profile.h>
18#include <linux/errno.h> 18#include <linux/errno.h>
19#include <linux/ftrace.h>
19#include <linux/mm.h> 20#include <linux/mm.h>
20#include <linux/err.h> 21#include <linux/err.h>
21#include <linux/cpu.h> 22#include <linux/cpu.h>
@@ -24,6 +25,7 @@
24#include <linux/irq.h> 25#include <linux/irq.h>
25#include <linux/percpu.h> 26#include <linux/percpu.h>
26#include <linux/clockchips.h> 27#include <linux/clockchips.h>
28#include <linux/completion.h>
27 29
28#include <asm/atomic.h> 30#include <asm/atomic.h>
29#include <asm/cacheflush.h> 31#include <asm/cacheflush.h>
@@ -33,10 +35,10 @@
33#include <asm/pgtable.h> 35#include <asm/pgtable.h>
34#include <asm/pgalloc.h> 36#include <asm/pgalloc.h>
35#include <asm/processor.h> 37#include <asm/processor.h>
38#include <asm/sections.h>
36#include <asm/tlbflush.h> 39#include <asm/tlbflush.h>
37#include <asm/ptrace.h> 40#include <asm/ptrace.h>
38#include <asm/localtimer.h> 41#include <asm/localtimer.h>
39#include <asm/smp_plat.h>
40 42
41#include <litmus/preempt.h> 43#include <litmus/preempt.h>
42 44
@@ -47,22 +49,8 @@
47 */ 49 */
48struct secondary_data secondary_data; 50struct secondary_data secondary_data;
49 51
50/*
51 * structures for inter-processor calls
52 * - A collection of single bit ipi messages.
53 */
54struct ipi_data {
55 spinlock_t lock;
56 unsigned long ipi_count;
57 unsigned long bits;
58};
59
60static DEFINE_PER_CPU(struct ipi_data, ipi_data) = {
61 .lock = SPIN_LOCK_UNLOCKED,
62};
63
64enum ipi_msg_type { 52enum ipi_msg_type {
65 IPI_TIMER, 53 IPI_TIMER = 2,
66 IPI_RESCHEDULE, 54 IPI_RESCHEDULE,
67 IPI_CALL_FUNC, 55 IPI_CALL_FUNC,
68 IPI_CALL_FUNC_SINGLE, 56 IPI_CALL_FUNC_SINGLE,
@@ -74,7 +62,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
74 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu); 62 struct cpuinfo_arm *ci = &per_cpu(cpu_data, cpu);
75 struct task_struct *idle = ci->idle; 63 struct task_struct *idle = ci->idle;
76 pgd_t *pgd; 64 pgd_t *pgd;
77 pmd_t *pmd;
78 int ret; 65 int ret;
79 66
80 /* 67 /*
@@ -103,11 +90,16 @@ int __cpuinit __cpu_up(unsigned int cpu)
103 * a 1:1 mapping for the physical address of the kernel. 90 * a 1:1 mapping for the physical address of the kernel.
104 */ 91 */
105 pgd = pgd_alloc(&init_mm); 92 pgd = pgd_alloc(&init_mm);
106 pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET); 93 if (!pgd)
107 *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) | 94 return -ENOMEM;
108 PMD_TYPE_SECT | PMD_SECT_AP_WRITE); 95
109 flush_pmd_entry(pmd); 96 if (PHYS_OFFSET != PAGE_OFFSET) {
110 outer_clean_range(__pa(pmd), __pa(pmd + 1)); 97#ifndef CONFIG_HOTPLUG_CPU
98 identity_mapping_add(pgd, __pa(__init_begin), __pa(__init_end));
99#endif
100 identity_mapping_add(pgd, __pa(_stext), __pa(_etext));
101 identity_mapping_add(pgd, __pa(_sdata), __pa(_edata));
102 }
111 103
112 /* 104 /*
113 * We need to tell the secondary core where to find 105 * We need to tell the secondary core where to find
@@ -115,6 +107,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
115 */ 107 */
116 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; 108 secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
117 secondary_data.pgdir = virt_to_phys(pgd); 109 secondary_data.pgdir = virt_to_phys(pgd);
110 secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
118 __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); 111 __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
119 outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); 112 outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
120 113
@@ -138,29 +131,33 @@ int __cpuinit __cpu_up(unsigned int cpu)
138 barrier(); 131 barrier();
139 } 132 }
140 133
141 if (!cpu_online(cpu)) 134 if (!cpu_online(cpu)) {
135 pr_crit("CPU%u: failed to come online\n", cpu);
142 ret = -EIO; 136 ret = -EIO;
137 }
138 } else {
139 pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
143 } 140 }
144 141
145 secondary_data.stack = NULL; 142 secondary_data.stack = NULL;
146 secondary_data.pgdir = 0; 143 secondary_data.pgdir = 0;
147 144
148 *pmd = __pmd(0); 145 if (PHYS_OFFSET != PAGE_OFFSET) {
149 clean_pmd_entry(pmd); 146#ifndef CONFIG_HOTPLUG_CPU
150 pgd_free(&init_mm, pgd); 147 identity_mapping_del(pgd, __pa(__init_begin), __pa(__init_end));
151 148#endif
152 if (ret) { 149 identity_mapping_del(pgd, __pa(_stext), __pa(_etext));
153 printk(KERN_CRIT "CPU%u: processor failed to boot\n", cpu); 150 identity_mapping_del(pgd, __pa(_sdata), __pa(_edata));
154
155 /*
156 * FIXME: We need to clean up the new idle thread. --rmk
157 */
158 } 151 }
159 152
153 pgd_free(&init_mm, pgd);
154
160 return ret; 155 return ret;
161} 156}
162 157
163#ifdef CONFIG_HOTPLUG_CPU 158#ifdef CONFIG_HOTPLUG_CPU
159static void percpu_timer_stop(void);
160
164/* 161/*
165 * __cpu_disable runs on the processor to be shutdown. 162 * __cpu_disable runs on the processor to be shutdown.
166 */ 163 */
@@ -188,7 +185,7 @@ int __cpu_disable(void)
188 /* 185 /*
189 * Stop the local timer for this CPU. 186 * Stop the local timer for this CPU.
190 */ 187 */
191 local_timer_stop(); 188 percpu_timer_stop();
192 189
193 /* 190 /*
194 * Flush user cache and TLB mappings, and then remove this CPU 191 * Flush user cache and TLB mappings, and then remove this CPU
@@ -207,12 +204,20 @@ int __cpu_disable(void)
207 return 0; 204 return 0;
208} 205}
209 206
207static DECLARE_COMPLETION(cpu_died);
208
210/* 209/*
211 * called on the thread which is asking for a CPU to be shutdown - 210 * called on the thread which is asking for a CPU to be shutdown -
212 * waits until shutdown has completed, or it is timed out. 211 * waits until shutdown has completed, or it is timed out.
213 */ 212 */
214void __cpu_die(unsigned int cpu) 213void __cpu_die(unsigned int cpu)
215{ 214{
215 if (!wait_for_completion_timeout(&cpu_died, msecs_to_jiffies(5000))) {
216 pr_err("CPU%u: cpu didn't die\n", cpu);
217 return;
218 }
219 printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
220
216 if (!platform_cpu_kill(cpu)) 221 if (!platform_cpu_kill(cpu))
217 printk("CPU%u: unable to kill\n", cpu); 222 printk("CPU%u: unable to kill\n", cpu);
218} 223}
@@ -229,12 +234,17 @@ void __ref cpu_die(void)
229{ 234{
230 unsigned int cpu = smp_processor_id(); 235 unsigned int cpu = smp_processor_id();
231 236
232 local_irq_disable();
233 idle_task_exit(); 237 idle_task_exit();
234 238
239 local_irq_disable();
240 mb();
241
242 /* Tell __cpu_die() that this CPU is now safe to dispose of */
243 complete(&cpu_died);
244
235 /* 245 /*
236 * actual CPU shutdown procedure is at least platform (if not 246 * actual CPU shutdown procedure is at least platform (if not
237 * CPU) specific 247 * CPU) specific.
238 */ 248 */
239 platform_cpu_die(cpu); 249 platform_cpu_die(cpu);
240 250
@@ -244,6 +254,7 @@ void __ref cpu_die(void)
244 * to be repeated to undo the effects of taking the CPU offline. 254 * to be repeated to undo the effects of taking the CPU offline.
245 */ 255 */
246 __asm__("mov sp, %0\n" 256 __asm__("mov sp, %0\n"
257 " mov fp, #0\n"
247 " b secondary_start_kernel" 258 " b secondary_start_kernel"
248 : 259 :
249 : "r" (task_stack_page(current) + THREAD_SIZE - 8)); 260 : "r" (task_stack_page(current) + THREAD_SIZE - 8));
@@ -251,6 +262,17 @@ void __ref cpu_die(void)
251#endif /* CONFIG_HOTPLUG_CPU */ 262#endif /* CONFIG_HOTPLUG_CPU */
252 263
253/* 264/*
265 * Called by both boot and secondaries to move global data into
266 * per-processor storage.
267 */
268static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
269{
270 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
271
272 cpu_info->loops_per_jiffy = loops_per_jiffy;
273}
274
275/*
254 * This is the secondary CPU boot entry. We're using this CPUs 276 * This is the secondary CPU boot entry. We're using this CPUs
255 * idle thread stack, but a set of temporary page tables. 277 * idle thread stack, but a set of temporary page tables.
256 */ 278 */
@@ -265,7 +287,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
265 * All kernel threads share the same mm context; grab a 287 * All kernel threads share the same mm context; grab a
266 * reference and switch to it. 288 * reference and switch to it.
267 */ 289 */
268 atomic_inc(&mm->mm_users);
269 atomic_inc(&mm->mm_count); 290 atomic_inc(&mm->mm_count);
270 current->active_mm = mm; 291 current->active_mm = mm;
271 cpumask_set_cpu(cpu, mm_cpumask(mm)); 292 cpumask_set_cpu(cpu, mm_cpumask(mm));
@@ -275,6 +296,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
275 296
276 cpu_init(); 297 cpu_init();
277 preempt_disable(); 298 preempt_disable();
299 trace_hardirqs_off();
278 300
279 /* 301 /*
280 * Give the platform a chance to do its own initialisation. 302 * Give the platform a chance to do its own initialisation.
@@ -298,9 +320,13 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
298 smp_store_cpu_info(cpu); 320 smp_store_cpu_info(cpu);
299 321
300 /* 322 /*
301 * OK, now it's safe to let the boot CPU continue 323 * OK, now it's safe to let the boot CPU continue. Wait for
324 * the CPU migration code to notice that the CPU is online
325 * before we continue.
302 */ 326 */
303 set_cpu_online(cpu, true); 327 set_cpu_online(cpu, true);
328 while (!cpu_active(cpu))
329 cpu_relax();
304 330
305 /* 331 /*
306 * OK, it's off to the idle thread for us 332 * OK, it's off to the idle thread for us
@@ -308,17 +334,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
308 cpu_idle(); 334 cpu_idle();
309} 335}
310 336
311/*
312 * Called by both boot and secondaries to move global data into
313 * per-processor storage.
314 */
315void __cpuinit smp_store_cpu_info(unsigned int cpuid)
316{
317 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
318
319 cpu_info->loops_per_jiffy = loops_per_jiffy;
320}
321
322void __init smp_cpus_done(unsigned int max_cpus) 337void __init smp_cpus_done(unsigned int max_cpus)
323{ 338{
324 int cpu; 339 int cpu;
@@ -341,61 +356,87 @@ void __init smp_prepare_boot_cpu(void)
341 per_cpu(cpu_data, cpu).idle = current; 356 per_cpu(cpu_data, cpu).idle = current;
342} 357}
343 358
344static void send_ipi_message(const struct cpumask *mask, enum ipi_msg_type msg) 359void __init smp_prepare_cpus(unsigned int max_cpus)
345{ 360{
346 unsigned long flags; 361 unsigned int ncores = num_possible_cpus();
347 unsigned int cpu;
348 362
349 local_irq_save(flags); 363 smp_store_cpu_info(smp_processor_id());
350 364
351 for_each_cpu(cpu, mask) { 365 /*
352 struct ipi_data *ipi = &per_cpu(ipi_data, cpu); 366 * are we trying to boot more cores than exist?
367 */
368 if (max_cpus > ncores)
369 max_cpus = ncores;
353 370
354 spin_lock(&ipi->lock); 371 if (max_cpus > 1) {
355 ipi->bits |= 1 << msg; 372 /*
356 spin_unlock(&ipi->lock); 373 * Enable the local timer or broadcast device for the
374 * boot CPU, but only if we have more than one CPU.
375 */
376 percpu_timer_setup();
377
378 /*
379 * Initialise the SCU if there are more than one CPU
380 * and let them know where to start.
381 */
382 platform_smp_prepare_cpus(max_cpus);
357 } 383 }
384}
358 385
359 /* 386static void (*smp_cross_call)(const struct cpumask *, unsigned int);
360 * Call the platform specific cross-CPU call function.
361 */
362 smp_cross_call(mask);
363 387
364 local_irq_restore(flags); 388void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
389{
390 smp_cross_call = fn;
365} 391}
366 392
367void arch_send_call_function_ipi_mask(const struct cpumask *mask) 393void arch_send_call_function_ipi_mask(const struct cpumask *mask)
368{ 394{
369 send_ipi_message(mask, IPI_CALL_FUNC); 395 smp_cross_call(mask, IPI_CALL_FUNC);
370} 396}
371 397
372void arch_send_call_function_single_ipi(int cpu) 398void arch_send_call_function_single_ipi(int cpu)
373{ 399{
374 send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE); 400 smp_cross_call(cpumask_of(cpu), IPI_CALL_FUNC_SINGLE);
375} 401}
376 402
377void show_ipi_list(struct seq_file *p) 403static const char *ipi_types[NR_IPI] = {
404#define S(x,s) [x - IPI_TIMER] = s
405 S(IPI_TIMER, "Timer broadcast interrupts"),
406 S(IPI_RESCHEDULE, "Rescheduling interrupts"),
407 S(IPI_CALL_FUNC, "Function call interrupts"),
408 S(IPI_CALL_FUNC_SINGLE, "Single function call interrupts"),
409 S(IPI_CPU_STOP, "CPU stop interrupts"),
410};
411
412void show_ipi_list(struct seq_file *p, int prec)
378{ 413{
379 unsigned int cpu; 414 unsigned int cpu, i;
380 415
381 seq_puts(p, "IPI:"); 416 for (i = 0; i < NR_IPI; i++) {
417 seq_printf(p, "%*s%u: ", prec - 1, "IPI", i);
382 418
383 for_each_present_cpu(cpu) 419 for_each_present_cpu(cpu)
384 seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count); 420 seq_printf(p, "%10u ",
421 __get_irq_stat(cpu, ipi_irqs[i]));
385 422
386 seq_putc(p, '\n'); 423 seq_printf(p, " %s\n", ipi_types[i]);
424 }
387} 425}
388 426
389void show_local_irqs(struct seq_file *p) 427u64 smp_irq_stat_cpu(unsigned int cpu)
390{ 428{
391 unsigned int cpu; 429 u64 sum = 0;
430 int i;
392 431
393 seq_printf(p, "LOC: "); 432 for (i = 0; i < NR_IPI; i++)
433 sum += __get_irq_stat(cpu, ipi_irqs[i]);
394 434
395 for_each_present_cpu(cpu) 435#ifdef CONFIG_LOCAL_TIMERS
396 seq_printf(p, "%10u ", irq_stat[cpu].local_timer_irqs); 436 sum += __get_irq_stat(cpu, local_timer_irqs);
437#endif
397 438
398 seq_putc(p, '\n'); 439 return sum;
399} 440}
400 441
401/* 442/*
@@ -412,36 +453,47 @@ static void ipi_timer(void)
412} 453}
413 454
414#ifdef CONFIG_LOCAL_TIMERS 455#ifdef CONFIG_LOCAL_TIMERS
415asmlinkage void __exception do_local_timer(struct pt_regs *regs) 456asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
416{ 457{
417 struct pt_regs *old_regs = set_irq_regs(regs); 458 struct pt_regs *old_regs = set_irq_regs(regs);
418 int cpu = smp_processor_id(); 459 int cpu = smp_processor_id();
419 460
420 if (local_timer_ack()) { 461 if (local_timer_ack()) {
421 irq_stat[cpu].local_timer_irqs++; 462 __inc_irq_stat(cpu, local_timer_irqs);
422 ipi_timer(); 463 ipi_timer();
423 } 464 }
424 465
425 set_irq_regs(old_regs); 466 set_irq_regs(old_regs);
426} 467}
468
469void show_local_irqs(struct seq_file *p, int prec)
470{
471 unsigned int cpu;
472
473 seq_printf(p, "%*s: ", prec, "LOC");
474
475 for_each_present_cpu(cpu)
476 seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
477
478 seq_printf(p, " Local timer interrupts\n");
479}
427#endif 480#endif
428 481
429#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST 482#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
430static void smp_timer_broadcast(const struct cpumask *mask) 483static void smp_timer_broadcast(const struct cpumask *mask)
431{ 484{
432 send_ipi_message(mask, IPI_TIMER); 485 smp_cross_call(mask, IPI_TIMER);
433} 486}
434#else 487#else
435#define smp_timer_broadcast NULL 488#define smp_timer_broadcast NULL
436#endif 489#endif
437 490
438#ifndef CONFIG_LOCAL_TIMERS
439static void broadcast_timer_set_mode(enum clock_event_mode mode, 491static void broadcast_timer_set_mode(enum clock_event_mode mode,
440 struct clock_event_device *evt) 492 struct clock_event_device *evt)
441{ 493{
442} 494}
443 495
444static void local_timer_setup(struct clock_event_device *evt) 496static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
445{ 497{
446 evt->name = "dummy_timer"; 498 evt->name = "dummy_timer";
447 evt->features = CLOCK_EVT_FEAT_ONESHOT | 499 evt->features = CLOCK_EVT_FEAT_ONESHOT |
@@ -453,7 +505,6 @@ static void local_timer_setup(struct clock_event_device *evt)
453 505
454 clockevents_register_device(evt); 506 clockevents_register_device(evt);
455} 507}
456#endif
457 508
458void __cpuinit percpu_timer_setup(void) 509void __cpuinit percpu_timer_setup(void)
459{ 510{
@@ -463,8 +514,24 @@ void __cpuinit percpu_timer_setup(void)
463 evt->cpumask = cpumask_of(cpu); 514 evt->cpumask = cpumask_of(cpu);
464 evt->broadcast = smp_timer_broadcast; 515 evt->broadcast = smp_timer_broadcast;
465 516
466 local_timer_setup(evt); 517 if (local_timer_setup(evt))
518 broadcast_timer_setup(evt);
519}
520
521#ifdef CONFIG_HOTPLUG_CPU
522/*
523 * The generic clock events code purposely does not stop the local timer
524 * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
525 * manually here.
526 */
527static void percpu_timer_stop(void)
528{
529 unsigned int cpu = smp_processor_id();
530 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
531
532 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
467} 533}
534#endif
468 535
469static DEFINE_SPINLOCK(stop_lock); 536static DEFINE_SPINLOCK(stop_lock);
470 537
@@ -492,217 +559,75 @@ static void ipi_cpu_stop(unsigned int cpu)
492 559
493/* 560/*
494 * Main handler for inter-processor interrupts 561 * Main handler for inter-processor interrupts
495 *
496 * For ARM, the ipimask now only identifies a single
497 * category of IPI (Bit 1 IPIs have been replaced by a
498 * different mechanism):
499 *
500 * Bit 0 - Inter-processor function call
501 */ 562 */
502asmlinkage void __exception do_IPI(struct pt_regs *regs) 563asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
503{ 564{
504 unsigned int cpu = smp_processor_id(); 565 unsigned int cpu = smp_processor_id();
505 struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
506 struct pt_regs *old_regs = set_irq_regs(regs); 566 struct pt_regs *old_regs = set_irq_regs(regs);
507 567
508 ipi->ipi_count++; 568 if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI)
509 569 __inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]);
510 for (;;) {
511 unsigned long msgs;
512
513 spin_lock(&ipi->lock);
514 msgs = ipi->bits;
515 ipi->bits = 0;
516 spin_unlock(&ipi->lock);
517
518 if (!msgs)
519 break;
520
521 do {
522 unsigned nextmsg;
523
524 nextmsg = msgs & -msgs;
525 msgs &= ~nextmsg;
526 nextmsg = ffz(~nextmsg);
527
528 switch (nextmsg) {
529 case IPI_TIMER:
530 ipi_timer();
531 break;
532
533 case IPI_RESCHEDULE:
534 /*
535 * nothing more to do - eveything is
536 * done on the interrupt return path
537 */
538 /* LITMUS^RT: take action based on scheduler state */
539 sched_state_ipi();
540 break;
541
542 case IPI_CALL_FUNC:
543 generic_smp_call_function_interrupt();
544 break;
545
546 case IPI_CALL_FUNC_SINGLE:
547 generic_smp_call_function_single_interrupt();
548 break;
549 570
550 case IPI_CPU_STOP: 571 switch (ipinr) {
551 ipi_cpu_stop(cpu); 572 case IPI_TIMER:
552 break; 573 ipi_timer();
553 574 break;
554 default: 575
555 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n", 576 case IPI_RESCHEDULE:
556 cpu, nextmsg); 577 /* LITMUS^RT: take action based on scheduler state */
557 break; 578 sched_state_ipi();
558 } 579 scheduler_ipi();
559 } while (msgs); 580 break;
581
582 case IPI_CALL_FUNC:
583 generic_smp_call_function_interrupt();
584 break;
585
586 case IPI_CALL_FUNC_SINGLE:
587 generic_smp_call_function_single_interrupt();
588 break;
589
590 case IPI_CPU_STOP:
591 ipi_cpu_stop(cpu);
592 break;
593
594 default:
595 printk(KERN_CRIT "CPU%u: Unknown IPI message 0x%x\n",
596 cpu, ipinr);
597 break;
560 } 598 }
561
562 set_irq_regs(old_regs); 599 set_irq_regs(old_regs);
563} 600}
564 601
565void smp_send_reschedule(int cpu) 602void smp_send_reschedule(int cpu)
566{ 603{
567 send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE); 604 smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE);
568} 605}
569 606
570void smp_send_stop(void) 607void smp_send_stop(void)
571{ 608{
572 cpumask_t mask = cpu_online_map; 609 unsigned long timeout;
573 cpu_clear(smp_processor_id(), mask);
574 send_ipi_message(&mask, IPI_CPU_STOP);
575}
576 610
577/* 611 if (num_online_cpus() > 1) {
578 * not supported here 612 cpumask_t mask = cpu_online_map;
579 */ 613 cpu_clear(smp_processor_id(), mask);
580int setup_profiling_timer(unsigned int multiplier)
581{
582 return -EINVAL;
583}
584 614
585static void 615 smp_cross_call(&mask, IPI_CPU_STOP);
586on_each_cpu_mask(void (*func)(void *), void *info, int wait, 616 }
587 const struct cpumask *mask)
588{
589 preempt_disable();
590 617
591 smp_call_function_many(mask, func, info, wait); 618 /* Wait up to one second for other CPUs to stop */
592 if (cpumask_test_cpu(smp_processor_id(), mask)) 619 timeout = USEC_PER_SEC;
593 func(info); 620 while (num_online_cpus() > 1 && timeout--)
621 udelay(1);
594 622
595 preempt_enable(); 623 if (num_online_cpus() > 1)
624 pr_warning("SMP: failed to stop secondary CPUs\n");
596} 625}
597 626
598/**********************************************************************/
599
600/* 627/*
601 * TLB operations 628 * not supported here
602 */ 629 */
603struct tlb_args { 630int setup_profiling_timer(unsigned int multiplier)
604 struct vm_area_struct *ta_vma;
605 unsigned long ta_start;
606 unsigned long ta_end;
607};
608
609static inline void ipi_flush_tlb_all(void *ignored)
610{
611 local_flush_tlb_all();
612}
613
614static inline void ipi_flush_tlb_mm(void *arg)
615{
616 struct mm_struct *mm = (struct mm_struct *)arg;
617
618 local_flush_tlb_mm(mm);
619}
620
621static inline void ipi_flush_tlb_page(void *arg)
622{
623 struct tlb_args *ta = (struct tlb_args *)arg;
624
625 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
626}
627
628static inline void ipi_flush_tlb_kernel_page(void *arg)
629{
630 struct tlb_args *ta = (struct tlb_args *)arg;
631
632 local_flush_tlb_kernel_page(ta->ta_start);
633}
634
635static inline void ipi_flush_tlb_range(void *arg)
636{
637 struct tlb_args *ta = (struct tlb_args *)arg;
638
639 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
640}
641
642static inline void ipi_flush_tlb_kernel_range(void *arg)
643{
644 struct tlb_args *ta = (struct tlb_args *)arg;
645
646 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
647}
648
649void flush_tlb_all(void)
650{
651 if (tlb_ops_need_broadcast())
652 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
653 else
654 local_flush_tlb_all();
655}
656
657void flush_tlb_mm(struct mm_struct *mm)
658{
659 if (tlb_ops_need_broadcast())
660 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
661 else
662 local_flush_tlb_mm(mm);
663}
664
665void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
666{
667 if (tlb_ops_need_broadcast()) {
668 struct tlb_args ta;
669 ta.ta_vma = vma;
670 ta.ta_start = uaddr;
671 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
672 } else
673 local_flush_tlb_page(vma, uaddr);
674}
675
676void flush_tlb_kernel_page(unsigned long kaddr)
677{
678 if (tlb_ops_need_broadcast()) {
679 struct tlb_args ta;
680 ta.ta_start = kaddr;
681 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
682 } else
683 local_flush_tlb_kernel_page(kaddr);
684}
685
686void flush_tlb_range(struct vm_area_struct *vma,
687 unsigned long start, unsigned long end)
688{
689 if (tlb_ops_need_broadcast()) {
690 struct tlb_args ta;
691 ta.ta_vma = vma;
692 ta.ta_start = start;
693 ta.ta_end = end;
694 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
695 } else
696 local_flush_tlb_range(vma, start, end);
697}
698
699void flush_tlb_kernel_range(unsigned long start, unsigned long end)
700{ 631{
701 if (tlb_ops_need_broadcast()) { 632 return -EINVAL;
702 struct tlb_args ta;
703 ta.ta_start = start;
704 ta.ta_end = end;
705 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
706 } else
707 local_flush_tlb_kernel_range(start, end);
708} 633}
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c
index 9ab4149bd983..a1e757c3439b 100644
--- a/arch/arm/kernel/smp_scu.c
+++ b/arch/arm/kernel/smp_scu.c
@@ -50,3 +50,26 @@ void __init scu_enable(void __iomem *scu_base)
50 */ 50 */
51 flush_cache_all(); 51 flush_cache_all();
52} 52}
53
54/*
55 * Set the executing CPUs power mode as defined. This will be in
56 * preparation for it executing a WFI instruction.
57 *
58 * This function must be called with preemption disabled, and as it
59 * has the side effect of disabling coherency, caches must have been
60 * flushed. Interrupts must also have been disabled.
61 */
62int scu_power_mode(void __iomem *scu_base, unsigned int mode)
63{
64 unsigned int val;
65 int cpu = smp_processor_id();
66
67 if (mode > 3 || mode == 1 || cpu > 3)
68 return -EINVAL;
69
70 val = __raw_readb(scu_base + SCU_CPU_STATUS + cpu) & ~0x03;
71 val |= mode;
72 __raw_writeb(val, scu_base + SCU_CPU_STATUS + cpu);
73
74 return 0;
75}
diff --git a/arch/arm/kernel/smp_tlb.c b/arch/arm/kernel/smp_tlb.c
new file mode 100644
index 000000000000..7dcb35285be7
--- /dev/null
+++ b/arch/arm/kernel/smp_tlb.c
@@ -0,0 +1,139 @@
1/*
2 * linux/arch/arm/kernel/smp_tlb.c
3 *
4 * Copyright (C) 2002 ARM Limited, All Rights Reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/preempt.h>
11#include <linux/smp.h>
12
13#include <asm/smp_plat.h>
14#include <asm/tlbflush.h>
15
16static void on_each_cpu_mask(void (*func)(void *), void *info, int wait,
17 const struct cpumask *mask)
18{
19 preempt_disable();
20
21 smp_call_function_many(mask, func, info, wait);
22 if (cpumask_test_cpu(smp_processor_id(), mask))
23 func(info);
24
25 preempt_enable();
26}
27
28/**********************************************************************/
29
30/*
31 * TLB operations
32 */
33struct tlb_args {
34 struct vm_area_struct *ta_vma;
35 unsigned long ta_start;
36 unsigned long ta_end;
37};
38
39static inline void ipi_flush_tlb_all(void *ignored)
40{
41 local_flush_tlb_all();
42}
43
44static inline void ipi_flush_tlb_mm(void *arg)
45{
46 struct mm_struct *mm = (struct mm_struct *)arg;
47
48 local_flush_tlb_mm(mm);
49}
50
51static inline void ipi_flush_tlb_page(void *arg)
52{
53 struct tlb_args *ta = (struct tlb_args *)arg;
54
55 local_flush_tlb_page(ta->ta_vma, ta->ta_start);
56}
57
58static inline void ipi_flush_tlb_kernel_page(void *arg)
59{
60 struct tlb_args *ta = (struct tlb_args *)arg;
61
62 local_flush_tlb_kernel_page(ta->ta_start);
63}
64
65static inline void ipi_flush_tlb_range(void *arg)
66{
67 struct tlb_args *ta = (struct tlb_args *)arg;
68
69 local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end);
70}
71
72static inline void ipi_flush_tlb_kernel_range(void *arg)
73{
74 struct tlb_args *ta = (struct tlb_args *)arg;
75
76 local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end);
77}
78
79void flush_tlb_all(void)
80{
81 if (tlb_ops_need_broadcast())
82 on_each_cpu(ipi_flush_tlb_all, NULL, 1);
83 else
84 local_flush_tlb_all();
85}
86
87void flush_tlb_mm(struct mm_struct *mm)
88{
89 if (tlb_ops_need_broadcast())
90 on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, mm_cpumask(mm));
91 else
92 local_flush_tlb_mm(mm);
93}
94
95void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
96{
97 if (tlb_ops_need_broadcast()) {
98 struct tlb_args ta;
99 ta.ta_vma = vma;
100 ta.ta_start = uaddr;
101 on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, mm_cpumask(vma->vm_mm));
102 } else
103 local_flush_tlb_page(vma, uaddr);
104}
105
106void flush_tlb_kernel_page(unsigned long kaddr)
107{
108 if (tlb_ops_need_broadcast()) {
109 struct tlb_args ta;
110 ta.ta_start = kaddr;
111 on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1);
112 } else
113 local_flush_tlb_kernel_page(kaddr);
114}
115
116void flush_tlb_range(struct vm_area_struct *vma,
117 unsigned long start, unsigned long end)
118{
119 if (tlb_ops_need_broadcast()) {
120 struct tlb_args ta;
121 ta.ta_vma = vma;
122 ta.ta_start = start;
123 ta.ta_end = end;
124 on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, mm_cpumask(vma->vm_mm));
125 } else
126 local_flush_tlb_range(vma, start, end);
127}
128
129void flush_tlb_kernel_range(unsigned long start, unsigned long end)
130{
131 if (tlb_ops_need_broadcast()) {
132 struct tlb_args ta;
133 ta.ta_start = start;
134 ta.ta_end = end;
135 on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1);
136 } else
137 local_flush_tlb_kernel_range(start, end);
138}
139
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 35882fbf37f9..2c277d40cee6 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -36,6 +36,7 @@ static void twd_set_mode(enum clock_event_mode mode,
36 /* timer load already set up */ 36 /* timer load already set up */
37 ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE 37 ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
38 | TWD_TIMER_CONTROL_PERIODIC; 38 | TWD_TIMER_CONTROL_PERIODIC;
39 __raw_writel(twd_timer_rate / HZ, twd_base + TWD_TIMER_LOAD);
39 break; 40 break;
40 case CLOCK_EVT_MODE_ONESHOT: 41 case CLOCK_EVT_MODE_ONESHOT:
41 /* period set, and timer enabled in 'next_event' hook */ 42 /* period set, and timer enabled in 'next_event' hook */
@@ -81,7 +82,7 @@ int twd_timer_ack(void)
81 82
82static void __cpuinit twd_calibrate_rate(void) 83static void __cpuinit twd_calibrate_rate(void)
83{ 84{
84 unsigned long load, count; 85 unsigned long count;
85 u64 waitjiffies; 86 u64 waitjiffies;
86 87
87 /* 88 /*
@@ -114,12 +115,8 @@ static void __cpuinit twd_calibrate_rate(void)
114 twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); 115 twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
115 116
116 printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, 117 printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
117 (twd_timer_rate / 100000) % 100); 118 (twd_timer_rate / 10000) % 100);
118 } 119 }
119
120 load = twd_timer_rate / HZ;
121
122 __raw_writel(load, twd_base + TWD_TIMER_LOAD);
123} 120}
124 121
125/* 122/*
@@ -127,8 +124,6 @@ static void __cpuinit twd_calibrate_rate(void)
127 */ 124 */
128void __cpuinit twd_timer_setup(struct clock_event_device *clk) 125void __cpuinit twd_timer_setup(struct clock_event_device *clk)
129{ 126{
130 unsigned long flags;
131
132 twd_calibrate_rate(); 127 twd_calibrate_rate();
133 128
134 clk->name = "local_timer"; 129 clk->name = "local_timer";
@@ -143,20 +138,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
143 clk->min_delta_ns = clockevent_delta2ns(0xf, clk); 138 clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
144 139
145 /* Make sure our local interrupt controller has this enabled */ 140 /* Make sure our local interrupt controller has this enabled */
146 local_irq_save(flags); 141 gic_enable_ppi(clk->irq);
147 irq_to_desc(clk->irq)->status |= IRQ_NOPROBE;
148 get_irq_chip(clk->irq)->unmask(clk->irq);
149 local_irq_restore(flags);
150 142
151 clockevents_register_device(clk); 143 clockevents_register_device(clk);
152} 144}
153
154#ifdef CONFIG_HOTPLUG_CPU
155/*
156 * take a local timer down
157 */
158void twd_timer_stop(void)
159{
160 __raw_writel(0, twd_base + TWD_TIMER_CONTROL);
161}
162#endif
diff --git a/arch/arm/kernel/stacktrace.c b/arch/arm/kernel/stacktrace.c
index 20b7411e47fd..381d23a497c1 100644
--- a/arch/arm/kernel/stacktrace.c
+++ b/arch/arm/kernel/stacktrace.c
@@ -28,7 +28,7 @@ int notrace unwind_frame(struct stackframe *frame)
28 28
29 /* only go to a higher address on the stack */ 29 /* only go to a higher address on the stack */
30 low = frame->sp; 30 low = frame->sp;
31 high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; 31 high = ALIGN(low, THREAD_SIZE);
32 32
33 /* check current frame pointer is within bounds */ 33 /* check current frame pointer is within bounds */
34 if (fp < (low + 12) || fp + 4 >= high) 34 if (fp < (low + 12) || fp + 4 >= high)
@@ -94,10 +94,13 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
94 if (tsk != current) { 94 if (tsk != current) {
95#ifdef CONFIG_SMP 95#ifdef CONFIG_SMP
96 /* 96 /*
97 * What guarantees do we have here that 'tsk' 97 * What guarantees do we have here that 'tsk' is not
98 * is not running on another CPU? 98 * running on another CPU? For now, ignore it as we
99 * can't guarantee we won't explode.
99 */ 100 */
100 BUG(); 101 if (trace->nr_entries < trace->max_entries)
102 trace->entries[trace->nr_entries++] = ULONG_MAX;
103 return;
101#else 104#else
102 data.no_sched_functions = 1; 105 data.no_sched_functions = 1;
103 frame.fp = thread_saved_fp(tsk); 106 frame.fp = thread_saved_fp(tsk);
diff --git a/arch/arm/kernel/swp_emulate.c b/arch/arm/kernel/swp_emulate.c
new file mode 100644
index 000000000000..40ee7e5045e4
--- /dev/null
+++ b/arch/arm/kernel/swp_emulate.c
@@ -0,0 +1,267 @@
1/*
2 * linux/arch/arm/kernel/swp_emulate.c
3 *
4 * Copyright (C) 2009 ARM Limited
5 * __user_* functions adapted from include/asm/uaccess.h
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * Implements emulation of the SWP/SWPB instructions using load-exclusive and
12 * store-exclusive for processors that have them disabled (or future ones that
13 * might not implement them).
14 *
15 * Syntax of SWP{B} instruction: SWP{B}<c> <Rt>, <Rt2>, [<Rn>]
16 * Where: Rt = destination
17 * Rt2 = source
18 * Rn = address
19 */
20
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/proc_fs.h>
24#include <linux/sched.h>
25#include <linux/syscalls.h>
26#include <linux/perf_event.h>
27
28#include <asm/traps.h>
29#include <asm/uaccess.h>
30
31/*
32 * Error-checking SWP macros implemented using ldrex{b}/strex{b}
33 */
34#define __user_swpX_asm(data, addr, res, temp, B) \
35 __asm__ __volatile__( \
36 " mov %2, %1\n" \
37 "0: ldrex"B" %1, [%3]\n" \
38 "1: strex"B" %0, %2, [%3]\n" \
39 " cmp %0, #0\n" \
40 " movne %0, %4\n" \
41 "2:\n" \
42 " .section .fixup,\"ax\"\n" \
43 " .align 2\n" \
44 "3: mov %0, %5\n" \
45 " b 2b\n" \
46 " .previous\n" \
47 " .section __ex_table,\"a\"\n" \
48 " .align 3\n" \
49 " .long 0b, 3b\n" \
50 " .long 1b, 3b\n" \
51 " .previous" \
52 : "=&r" (res), "+r" (data), "=&r" (temp) \
53 : "r" (addr), "i" (-EAGAIN), "i" (-EFAULT) \
54 : "cc", "memory")
55
56#define __user_swp_asm(data, addr, res, temp) \
57 __user_swpX_asm(data, addr, res, temp, "")
58#define __user_swpb_asm(data, addr, res, temp) \
59 __user_swpX_asm(data, addr, res, temp, "b")
60
61/*
62 * Macros/defines for extracting register numbers from instruction.
63 */
64#define EXTRACT_REG_NUM(instruction, offset) \
65 (((instruction) & (0xf << (offset))) >> (offset))
66#define RN_OFFSET 16
67#define RT_OFFSET 12
68#define RT2_OFFSET 0
69/*
70 * Bit 22 of the instruction encoding distinguishes between
71 * the SWP and SWPB variants (bit set means SWPB).
72 */
73#define TYPE_SWPB (1 << 22)
74
75static unsigned long swpcounter;
76static unsigned long swpbcounter;
77static unsigned long abtcounter;
78static pid_t previous_pid;
79
80#ifdef CONFIG_PROC_FS
81static int proc_read_status(char *page, char **start, off_t off, int count,
82 int *eof, void *data)
83{
84 char *p = page;
85 int len;
86
87 p += sprintf(p, "Emulated SWP:\t\t%lu\n", swpcounter);
88 p += sprintf(p, "Emulated SWPB:\t\t%lu\n", swpbcounter);
89 p += sprintf(p, "Aborted SWP{B}:\t\t%lu\n", abtcounter);
90 if (previous_pid != 0)
91 p += sprintf(p, "Last process:\t\t%d\n", previous_pid);
92
93 len = (p - page) - off;
94 if (len < 0)
95 len = 0;
96
97 *eof = (len <= count) ? 1 : 0;
98 *start = page + off;
99
100 return len;
101}
102#endif
103
104/*
105 * Set up process info to signal segmentation fault - called on access error.
106 */
107static void set_segfault(struct pt_regs *regs, unsigned long addr)
108{
109 siginfo_t info;
110
111 if (find_vma(current->mm, addr) == NULL)
112 info.si_code = SEGV_MAPERR;
113 else
114 info.si_code = SEGV_ACCERR;
115
116 info.si_signo = SIGSEGV;
117 info.si_errno = 0;
118 info.si_addr = (void *) instruction_pointer(regs);
119
120 pr_debug("SWP{B} emulation: access caused memory abort!\n");
121 arm_notify_die("Illegal memory access", regs, &info, 0, 0);
122
123 abtcounter++;
124}
125
126static int emulate_swpX(unsigned int address, unsigned int *data,
127 unsigned int type)
128{
129 unsigned int res = 0;
130
131 if ((type != TYPE_SWPB) && (address & 0x3)) {
132 /* SWP to unaligned address not permitted */
133 pr_debug("SWP instruction on unaligned pointer!\n");
134 return -EFAULT;
135 }
136
137 while (1) {
138 unsigned long temp;
139
140 /*
141 * Barrier required between accessing protected resource and
142 * releasing a lock for it. Legacy code might not have done
143 * this, and we cannot determine that this is not the case
144 * being emulated, so insert always.
145 */
146 smp_mb();
147
148 if (type == TYPE_SWPB)
149 __user_swpb_asm(*data, address, res, temp);
150 else
151 __user_swp_asm(*data, address, res, temp);
152
153 if (likely(res != -EAGAIN) || signal_pending(current))
154 break;
155
156 cond_resched();
157 }
158
159 if (res == 0) {
160 /*
161 * Barrier also required between acquiring a lock for a
162 * protected resource and accessing the resource. Inserted for
163 * same reason as above.
164 */
165 smp_mb();
166
167 if (type == TYPE_SWPB)
168 swpbcounter++;
169 else
170 swpcounter++;
171 }
172
173 return res;
174}
175
176/*
177 * swp_handler logs the id of calling process, dissects the instruction, sanity
178 * checks the memory location, calls emulate_swpX for the actual operation and
179 * deals with fixup/error handling before returning
180 */
181static int swp_handler(struct pt_regs *regs, unsigned int instr)
182{
183 unsigned int address, destreg, data, type;
184 unsigned int res = 0;
185
186 perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, 0, regs, regs->ARM_pc);
187
188 if (current->pid != previous_pid) {
189 pr_debug("\"%s\" (%ld) uses deprecated SWP{B} instruction\n",
190 current->comm, (unsigned long)current->pid);
191 previous_pid = current->pid;
192 }
193
194 address = regs->uregs[EXTRACT_REG_NUM(instr, RN_OFFSET)];
195 data = regs->uregs[EXTRACT_REG_NUM(instr, RT2_OFFSET)];
196 destreg = EXTRACT_REG_NUM(instr, RT_OFFSET);
197
198 type = instr & TYPE_SWPB;
199
200 pr_debug("addr in r%d->0x%08x, dest is r%d, source in r%d->0x%08x)\n",
201 EXTRACT_REG_NUM(instr, RN_OFFSET), address,
202 destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
203
204 /* Check access in reasonable access range for both SWP and SWPB */
205 if (!access_ok(VERIFY_WRITE, (address & ~3), 4)) {
206 pr_debug("SWP{B} emulation: access to %p not allowed!\n",
207 (void *)address);
208 res = -EFAULT;
209 } else {
210 res = emulate_swpX(address, &data, type);
211 }
212
213 if (res == 0) {
214 /*
215 * On successful emulation, revert the adjustment to the PC
216 * made in kernel/traps.c in order to resume execution at the
217 * instruction following the SWP{B}.
218 */
219 regs->ARM_pc += 4;
220 regs->uregs[destreg] = data;
221 } else if (res == -EFAULT) {
222 /*
223 * Memory errors do not mean emulation failed.
224 * Set up signal info to return SEGV, then return OK
225 */
226 set_segfault(regs, address);
227 }
228
229 return 0;
230}
231
232/*
233 * Only emulate SWP/SWPB executed in ARM state/User mode.
234 * The kernel must be SWP free and SWP{B} does not exist in Thumb/ThumbEE.
235 */
236static struct undef_hook swp_hook = {
237 .instr_mask = 0x0fb00ff0,
238 .instr_val = 0x01000090,
239 .cpsr_mask = MODE_MASK | PSR_T_BIT | PSR_J_BIT,
240 .cpsr_val = USR_MODE,
241 .fn = swp_handler
242};
243
244/*
245 * Register handler and create status file in /proc/cpu
246 * Invoked as late_initcall, since not needed before init spawned.
247 */
248static int __init swp_emulation_init(void)
249{
250#ifdef CONFIG_PROC_FS
251 struct proc_dir_entry *res;
252
253 res = create_proc_entry("cpu/swp_emulation", S_IRUGO, NULL);
254
255 if (!res)
256 return -ENOMEM;
257
258 res->read_proc = proc_read_status;
259#endif /* CONFIG_PROC_FS */
260
261 printk(KERN_NOTICE "Registering SWP/SWPB emulation handler\n");
262 register_undef_hook(&swp_hook);
263
264 return 0;
265}
266
267late_initcall(swp_emulation_init);
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
index 4ad8da15ef2b..af0aaebf4de6 100644
--- a/arch/arm/kernel/sys_oabi-compat.c
+++ b/arch/arm/kernel/sys_oabi-compat.c
@@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int semid,
311 long err; 311 long err;
312 int i; 312 int i;
313 313
314 if (nsops < 1) 314 if (nsops < 1 || nsops > SEMOPM)
315 return -EINVAL; 315 return -EINVAL;
316 sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); 316 sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
317 if (!sops) 317 if (!sops)
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c
index 26685c2f7a49..f5cf660eefcc 100644
--- a/arch/arm/kernel/tcm.c
+++ b/arch/arm/kernel/tcm.c
@@ -15,7 +15,7 @@
15#include <linux/string.h> /* memcpy */ 15#include <linux/string.h> /* memcpy */
16#include <asm/cputype.h> 16#include <asm/cputype.h>
17#include <asm/mach/map.h> 17#include <asm/mach/map.h>
18#include <mach/memory.h> 18#include <asm/memory.h>
19#include "tcm.h" 19#include "tcm.h"
20 20
21static struct gen_pool *tcm_pool; 21static struct gen_pool *tcm_pool;
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index 38c261f9951c..cb634c3e28e9 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -21,7 +21,7 @@
21#include <linux/timex.h> 21#include <linux/timex.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/profile.h> 23#include <linux/profile.h>
24#include <linux/sysdev.h> 24#include <linux/syscore_ops.h>
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <linux/irq.h> 26#include <linux/irq.h>
27 27
@@ -29,13 +29,15 @@
29 29
30#include <asm/leds.h> 30#include <asm/leds.h>
31#include <asm/thread_info.h> 31#include <asm/thread_info.h>
32#include <asm/sched_clock.h>
32#include <asm/stacktrace.h> 33#include <asm/stacktrace.h>
34#include <asm/mach/arch.h>
33#include <asm/mach/time.h> 35#include <asm/mach/time.h>
34 36
35/* 37/*
36 * Our system timer. 38 * Our system timer.
37 */ 39 */
38struct sys_timer *system_timer; 40static struct sys_timer *system_timer;
39 41
40#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) 42#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
41/* this needs a better home */ 43/* this needs a better home */
@@ -105,9 +107,7 @@ void timer_tick(void)
105{ 107{
106 profile_tick(CPU_PROFILING); 108 profile_tick(CPU_PROFILING);
107 do_leds(); 109 do_leds();
108 write_seqlock(&xtime_lock); 110 xtime_update(1);
109 do_timer(1);
110 write_sequnlock(&xtime_lock);
111#ifndef CONFIG_SMP 111#ifndef CONFIG_SMP
112 update_process_times(user_mode(get_irq_regs())); 112 update_process_times(user_mode(get_irq_regs()));
113#endif 113#endif
@@ -115,51 +115,44 @@ void timer_tick(void)
115#endif 115#endif
116 116
117#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) 117#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
118static int timer_suspend(struct sys_device *dev, pm_message_t state) 118static int timer_suspend(void)
119{ 119{
120 struct sys_timer *timer = container_of(dev, struct sys_timer, dev); 120 if (system_timer->suspend)
121 121 system_timer->suspend();
122 if (timer->suspend != NULL)
123 timer->suspend();
124 122
125 return 0; 123 return 0;
126} 124}
127 125
128static int timer_resume(struct sys_device *dev) 126static void timer_resume(void)
129{ 127{
130 struct sys_timer *timer = container_of(dev, struct sys_timer, dev); 128 if (system_timer->resume)
131 129 system_timer->resume();
132 if (timer->resume != NULL)
133 timer->resume();
134
135 return 0;
136} 130}
137#else 131#else
138#define timer_suspend NULL 132#define timer_suspend NULL
139#define timer_resume NULL 133#define timer_resume NULL
140#endif 134#endif
141 135
142static struct sysdev_class timer_sysclass = { 136static struct syscore_ops timer_syscore_ops = {
143 .name = "timer",
144 .suspend = timer_suspend, 137 .suspend = timer_suspend,
145 .resume = timer_resume, 138 .resume = timer_resume,
146}; 139};
147 140
148static int __init timer_init_sysfs(void) 141static int __init timer_init_syscore_ops(void)
149{ 142{
150 int ret = sysdev_class_register(&timer_sysclass); 143 register_syscore_ops(&timer_syscore_ops);
151 if (ret == 0) {
152 system_timer->dev.cls = &timer_sysclass;
153 ret = sysdev_register(&system_timer->dev);
154 }
155 144
156 return ret; 145 return 0;
157} 146}
158 147
159device_initcall(timer_init_sysfs); 148device_initcall(timer_init_syscore_ops);
160 149
161void __init time_init(void) 150void __init time_init(void)
162{ 151{
152 system_timer = machine_desc->timer;
163 system_timer->init(); 153 system_timer->init();
154#ifdef CONFIG_HAVE_SCHED_CLOCK
155 sched_clock_postinit();
156#endif
164} 157}
165 158
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index cda78d59aa31..6807cb1e76dd 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -23,6 +23,7 @@
23#include <linux/kexec.h> 23#include <linux/kexec.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/sched.h>
26 27
27#include <asm/atomic.h> 28#include <asm/atomic.h>
28#include <asm/cacheflush.h> 29#include <asm/cacheflush.h>
@@ -32,11 +33,12 @@
32#include <asm/unwind.h> 33#include <asm/unwind.h>
33#include <asm/tls.h> 34#include <asm/tls.h>
34 35
35#include "ptrace.h"
36#include "signal.h" 36#include "signal.h"
37 37
38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 38static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
39 39
40void *vectors_page;
41
40#ifdef CONFIG_DEBUG_USER 42#ifdef CONFIG_DEBUG_USER
41unsigned int user_debug; 43unsigned int user_debug;
42 44
@@ -53,10 +55,7 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
53void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame) 55void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
54{ 56{
55#ifdef CONFIG_KALLSYMS 57#ifdef CONFIG_KALLSYMS
56 char sym1[KSYM_SYMBOL_LEN], sym2[KSYM_SYMBOL_LEN]; 58 printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
57 sprint_symbol(sym1, where);
58 sprint_symbol(sym2, from);
59 printk("[<%08lx>] (%s) from [<%08lx>] (%s)\n", where, sym1, from, sym2);
60#else 59#else
61 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); 60 printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
62#endif 61#endif
@@ -140,7 +139,7 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
140 fs = get_fs(); 139 fs = get_fs();
141 set_fs(KERNEL_DS); 140 set_fs(KERNEL_DS);
142 141
143 for (i = -4; i < 1; i++) { 142 for (i = -4; i < 1 + !!thumb; i++) {
144 unsigned int val, bad; 143 unsigned int val, bad;
145 144
146 if (thumb) 145 if (thumb)
@@ -235,7 +234,6 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
235 234
236 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n", 235 printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP "\n",
237 str, err, ++die_counter); 236 str, err, ++die_counter);
238 sysfs_printk_last_file();
239 237
240 /* trap and error numbers are mostly meaningless on ARM */ 238 /* trap and error numbers are mostly meaningless on ARM */
241 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV); 239 ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, SIGSEGV);
@@ -257,7 +255,7 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
257 return ret; 255 return ret;
258} 256}
259 257
260DEFINE_SPINLOCK(die_lock); 258static DEFINE_SPINLOCK(die_lock);
261 259
262/* 260/*
263 * This function is protected against re-entrancy. 261 * This function is protected against re-entrancy.
@@ -411,8 +409,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
411 struct thread_info *thread = current_thread_info(); 409 struct thread_info *thread = current_thread_info();
412 siginfo_t info; 410 siginfo_t info;
413 411
414 if (current->personality != PER_LINUX && 412 if ((current->personality & PER_MASK) != PER_LINUX &&
415 current->personality != PER_LINUX_32BIT &&
416 thread->exec_domain->handler) { 413 thread->exec_domain->handler) {
417 thread->exec_domain->handler(n, regs); 414 thread->exec_domain->handler(n, regs);
418 return regs->ARM_r0; 415 return regs->ARM_r0;
@@ -566,7 +563,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
566 if (!pmd_present(*pmd)) 563 if (!pmd_present(*pmd))
567 goto bad_access; 564 goto bad_access;
568 pte = pte_offset_map_lock(mm, pmd, addr, &ptl); 565 pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
569 if (!pte_present(*pte) || !pte_dirty(*pte)) { 566 if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) {
570 pte_unmap_unlock(pte, ptl); 567 pte_unmap_unlock(pte, ptl);
571 goto bad_access; 568 goto bad_access;
572 } 569 }
@@ -711,19 +708,19 @@ void __readwrite_bug(const char *fn)
711} 708}
712EXPORT_SYMBOL(__readwrite_bug); 709EXPORT_SYMBOL(__readwrite_bug);
713 710
714void __pte_error(const char *file, int line, unsigned long val) 711void __pte_error(const char *file, int line, pte_t pte)
715{ 712{
716 printk("%s:%d: bad pte %08lx.\n", file, line, val); 713 printk("%s:%d: bad pte %08llx.\n", file, line, (long long)pte_val(pte));
717} 714}
718 715
719void __pmd_error(const char *file, int line, unsigned long val) 716void __pmd_error(const char *file, int line, pmd_t pmd)
720{ 717{
721 printk("%s:%d: bad pmd %08lx.\n", file, line, val); 718 printk("%s:%d: bad pmd %08llx.\n", file, line, (long long)pmd_val(pmd));
722} 719}
723 720
724void __pgd_error(const char *file, int line, unsigned long val) 721void __pgd_error(const char *file, int line, pgd_t pgd)
725{ 722{
726 printk("%s:%d: bad pgd %08lx.\n", file, line, val); 723 printk("%s:%d: bad pgd %08llx.\n", file, line, (long long)pgd_val(pgd));
727} 724}
728 725
729asmlinkage void __div0(void) 726asmlinkage void __div0(void)
@@ -759,7 +756,11 @@ static void __init kuser_get_tls_init(unsigned long vectors)
759 756
760void __init early_trap_init(void) 757void __init early_trap_init(void)
761{ 758{
759#if defined(CONFIG_CPU_USE_DOMAINS)
762 unsigned long vectors = CONFIG_VECTORS_BASE; 760 unsigned long vectors = CONFIG_VECTORS_BASE;
761#else
762 unsigned long vectors = (unsigned long)vectors_page;
763#endif
763 extern char __stubs_start[], __stubs_end[]; 764 extern char __stubs_start[], __stubs_end[];
764 extern char __vectors_start[], __vectors_end[]; 765 extern char __vectors_start[], __vectors_end[];
765 extern char __kuser_helper_start[], __kuser_helper_end[]; 766 extern char __kuser_helper_start[], __kuser_helper_end[];
@@ -783,10 +784,10 @@ void __init early_trap_init(void)
783 * Copy signal return handlers into the vector page, and 784 * Copy signal return handlers into the vector page, and
784 * set sigreturn to be a pointer to these. 785 * set sigreturn to be a pointer to these.
785 */ 786 */
786 memcpy((void *)KERN_SIGRETURN_CODE, sigreturn_codes, 787 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
787 sizeof(sigreturn_codes)); 788 sigreturn_codes, sizeof(sigreturn_codes));
788 memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, 789 memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
789 sizeof(syscall_restart_code)); 790 syscall_restart_code, sizeof(syscall_restart_code));
790 791
791 flush_icache_range(vectors, vectors + PAGE_SIZE); 792 flush_icache_range(vectors, vectors + PAGE_SIZE);
792 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 793 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index dd81a918c106..d2cb0b3c9872 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -146,6 +146,8 @@ static struct unwind_idx *unwind_find_idx(unsigned long addr)
146 addr < table->end_addr) { 146 addr < table->end_addr) {
147 idx = search_index(addr, table->start, 147 idx = search_index(addr, table->start,
148 table->stop - 1); 148 table->stop - 1);
149 /* Move-to-front to exploit common traces */
150 list_move(&table->list, &unwind_tables);
149 break; 151 break;
150 } 152 }
151 } 153 }
@@ -277,7 +279,7 @@ int unwind_frame(struct stackframe *frame)
277 279
278 /* only go to a higher address on the stack */ 280 /* only go to a higher address on the stack */
279 low = frame->sp; 281 low = frame->sp;
280 high = ALIGN(low, THREAD_SIZE) + THREAD_SIZE; 282 high = ALIGN(low, THREAD_SIZE);
281 283
282 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__, 284 pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
283 frame->pc, frame->lr, frame->sp); 285 frame->pc, frame->lr, frame->sp);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index b16c07914b55..e5287f21badc 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -8,6 +8,25 @@
8#include <asm/memory.h> 8#include <asm/memory.h>
9#include <asm/page.h> 9#include <asm/page.h>
10 10
11#define PROC_INFO \
12 VMLINUX_SYMBOL(__proc_info_begin) = .; \
13 *(.proc.info.init) \
14 VMLINUX_SYMBOL(__proc_info_end) = .;
15
16#ifdef CONFIG_HOTPLUG_CPU
17#define ARM_CPU_DISCARD(x)
18#define ARM_CPU_KEEP(x) x
19#else
20#define ARM_CPU_DISCARD(x) x
21#define ARM_CPU_KEEP(x)
22#endif
23
24#if defined(CONFIG_SMP_ON_UP) && !defined(CONFIG_DEBUG_SPINLOCK)
25#define ARM_EXIT_KEEP(x) x
26#else
27#define ARM_EXIT_KEEP(x)
28#endif
29
11OUTPUT_ARCH(arm) 30OUTPUT_ARCH(arm)
12ENTRY(stext) 31ENTRY(stext)
13 32
@@ -30,16 +49,24 @@ SECTIONS
30 _sinittext = .; 49 _sinittext = .;
31 HEAD_TEXT 50 HEAD_TEXT
32 INIT_TEXT 51 INIT_TEXT
52 ARM_EXIT_KEEP(EXIT_TEXT)
33 _einittext = .; 53 _einittext = .;
34 __proc_info_begin = .; 54 ARM_CPU_DISCARD(PROC_INFO)
35 *(.proc.info.init)
36 __proc_info_end = .;
37 __arch_info_begin = .; 55 __arch_info_begin = .;
38 *(.arch.info.init) 56 *(.arch.info.init)
39 __arch_info_end = .; 57 __arch_info_end = .;
40 __tagtable_begin = .; 58 __tagtable_begin = .;
41 *(.taglist.init) 59 *(.taglist.init)
42 __tagtable_end = .; 60 __tagtable_end = .;
61#ifdef CONFIG_SMP_ON_UP
62 __smpalt_begin = .;
63 *(.alt.smp.init)
64 __smpalt_end = .;
65#endif
66
67 __pv_table_begin = .;
68 *(.pv_table)
69 __pv_table_end = .;
43 70
44 INIT_SETUP(16) 71 INIT_SETUP(16)
45 72
@@ -51,10 +78,11 @@ SECTIONS
51#ifndef CONFIG_XIP_KERNEL 78#ifndef CONFIG_XIP_KERNEL
52 __init_begin = _stext; 79 __init_begin = _stext;
53 INIT_DATA 80 INIT_DATA
81 ARM_EXIT_KEEP(EXIT_DATA)
54#endif 82#endif
55 } 83 }
56 84
57 PERCPU(PAGE_SIZE) 85 PERCPU_SECTION(32)
58 86
59#ifndef CONFIG_XIP_KERNEL 87#ifndef CONFIG_XIP_KERNEL
60 . = ALIGN(PAGE_SIZE); 88 . = ALIGN(PAGE_SIZE);
@@ -68,10 +96,8 @@ SECTIONS
68 /DISCARD/ : { 96 /DISCARD/ : {
69 *(.ARM.exidx.exit.text) 97 *(.ARM.exidx.exit.text)
70 *(.ARM.extab.exit.text) 98 *(.ARM.extab.exit.text)
71#ifndef CONFIG_HOTPLUG_CPU 99 ARM_CPU_DISCARD(*(.ARM.exidx.cpuexit.text))
72 *(.ARM.exidx.cpuexit.text) 100 ARM_CPU_DISCARD(*(.ARM.extab.cpuexit.text))
73 *(.ARM.extab.cpuexit.text)
74#endif
75#ifndef CONFIG_HOTPLUG 101#ifndef CONFIG_HOTPLUG
76 *(.ARM.exidx.devexit.text) 102 *(.ARM.exidx.devexit.text)
77 *(.ARM.extab.devexit.text) 103 *(.ARM.extab.devexit.text)
@@ -87,6 +113,7 @@ SECTIONS
87 __exception_text_start = .; 113 __exception_text_start = .;
88 *(.exception.text) 114 *(.exception.text)
89 __exception_text_end = .; 115 __exception_text_end = .;
116 IRQENTRY_TEXT
90 TEXT_TEXT 117 TEXT_TEXT
91 SCHED_TEXT 118 SCHED_TEXT
92 LOCK_TEXT 119 LOCK_TEXT
@@ -99,13 +126,13 @@ SECTIONS
99 *(.rodata.*) 126 *(.rodata.*)
100 *(.glue_7) 127 *(.glue_7)
101 *(.glue_7t) 128 *(.glue_7t)
129 . = ALIGN(4);
102 *(.got) /* Global offset table */ 130 *(.got) /* Global offset table */
131 ARM_CPU_KEEP(PROC_INFO)
103 } 132 }
104 133
105 RO_DATA(PAGE_SIZE) 134 RO_DATA(PAGE_SIZE)
106 135
107 _etext = .; /* End of text and rodata section */
108
109#ifdef CONFIG_ARM_UNWIND 136#ifdef CONFIG_ARM_UNWIND
110 /* 137 /*
111 * Stack unwinding tables 138 * Stack unwinding tables
@@ -123,6 +150,8 @@ SECTIONS
123 } 150 }
124#endif 151#endif
125 152
153 _etext = .; /* End of text and rodata section */
154
126#ifdef CONFIG_XIP_KERNEL 155#ifdef CONFIG_XIP_KERNEL
127 __data_loc = ALIGN(4); /* location in binary */ 156 __data_loc = ALIGN(4); /* location in binary */
128 . = PAGE_OFFSET + TEXT_OFFSET; 157 . = PAGE_OFFSET + TEXT_OFFSET;
@@ -145,12 +174,14 @@ SECTIONS
145 . = ALIGN(PAGE_SIZE); 174 . = ALIGN(PAGE_SIZE);
146 __init_begin = .; 175 __init_begin = .;
147 INIT_DATA 176 INIT_DATA
177 ARM_EXIT_KEEP(EXIT_DATA)
148 . = ALIGN(PAGE_SIZE); 178 . = ALIGN(PAGE_SIZE);
149 __init_end = .; 179 __init_end = .;
150#endif 180#endif
151 181
152 NOSAVE_DATA 182 NOSAVE_DATA
153 CACHELINE_ALIGNED_DATA(32) 183 CACHELINE_ALIGNED_DATA(32)
184 READ_MOSTLY_DATA(32)
154 185
155 /* 186 /*
156 * The exception fixup table (might need resorting at runtime) 187 * The exception fixup table (might need resorting at runtime)
@@ -229,6 +260,8 @@ SECTIONS
229 } 260 }
230#endif 261#endif
231 262
263 NOTES
264
232 BSS_SECTION(0, 0, 0) 265 BSS_SECTION(0, 0, 0)
233 _end = .; 266 _end = .;
234 267
@@ -237,6 +270,12 @@ SECTIONS
237 270
238 /* Default discards */ 271 /* Default discards */
239 DISCARDS 272 DISCARDS
273
274#ifndef CONFIG_SMP_ON_UP
275 /DISCARD/ : {
276 *(.alt.smp.init)
277 }
278#endif
240} 279}
241 280
242/* 281/*