aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:40:02 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:40:02 -0500
commit7556afa0e0e436cad4f560ee83e5fbd5dac9359a (patch)
treec1500918b4b7c8b760feab1c8eeb8a815d2135ca /arch/avr32/kernel
parente07dd2ad305f6b29b47d713600aa8b722ef2a9f7 (diff)
parentd6c49a7a78fc841418bbd58bda504076f80ec51d (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen/avr32-2.6: [AVR32] extint: Set initial irq type to low level [AVR32] extint: change set_irq_type() handling [AVR32] NMI debugging [AVR32] constify function pointer tables [AVR32] ATNGW100: Update defconfig [AVR32] ATSTK1002: Update defconfig [AVR32] Kconfig: Choose daughterboard instead of CPU [AVR32] Add support for ATSTK1003 and ATSTK1004 [AVR32] Clean up external DAC setup code [AVR32] ATSTK1000: Move gpio-leds setup to setup.c [AVR32] Add support for AT32AP7001 and AT32AP7002 [AVR32] Provide more CPU information in /proc/cpuinfo and dmesg [AVR32] Oprofile support [AVR32] Include instrumentation menu Disable VGA text console for AVR32 architecture [AVR32] Enable debugging only when needed ptrace: Call arch_ptrace_attach() when request=PTRACE_TRACEME [AVR32] Remove redundant try_to_freeze() call from do_signal() [AVR32] Drop GFP_COMP for DMA memory allocations
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r--arch/avr32/kernel/Makefile3
-rw-r--r--arch/avr32/kernel/cpu.c96
-rw-r--r--arch/avr32/kernel/irq.c11
-rw-r--r--arch/avr32/kernel/kprobes.c5
-rw-r--r--arch/avr32/kernel/nmi_debug.c82
-rw-r--r--arch/avr32/kernel/ocd.c163
-rw-r--r--arch/avr32/kernel/process.c5
-rw-r--r--arch/avr32/kernel/ptrace.c5
-rw-r--r--arch/avr32/kernel/signal.c7
-rw-r--r--arch/avr32/kernel/traps.c21
10 files changed, 352 insertions, 46 deletions
diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile
index 2d6d48f35f69..e4b6d122b033 100644
--- a/arch/avr32/kernel/Makefile
+++ b/arch/avr32/kernel/Makefile
@@ -6,9 +6,10 @@ extra-y := head.o vmlinux.lds
6 6
7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o 7obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o
8obj-y += syscall_table.o syscall-stubs.o irq.o 8obj-y += syscall_table.o syscall-stubs.o irq.o
9obj-y += setup.o traps.o semaphore.o ptrace.o 9obj-y += setup.o traps.o semaphore.o ocd.o ptrace.o
10obj-y += signal.o sys_avr32.o process.o time.o 10obj-y += signal.o sys_avr32.o process.o time.o
11obj-y += init_task.o switch_to.o cpu.o 11obj-y += init_task.o switch_to.o cpu.o
12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o 12obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o
13obj-$(CONFIG_KPROBES) += kprobes.o 13obj-$(CONFIG_KPROBES) += kprobes.o
14obj-$(CONFIG_STACKTRACE) += stacktrace.o 14obj-$(CONFIG_STACKTRACE) += stacktrace.o
15obj-$(CONFIG_NMI_DEBUGGING) += nmi_debug.o
diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c
index 2714cf6452b5..b8409caeb23d 100644
--- a/arch/avr32/kernel/cpu.c
+++ b/arch/avr32/kernel/cpu.c
@@ -13,6 +13,7 @@
13#include <linux/percpu.h> 13#include <linux/percpu.h>
14#include <linux/param.h> 14#include <linux/param.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/clk.h>
16 17
17#include <asm/setup.h> 18#include <asm/setup.h>
18#include <asm/sysreg.h> 19#include <asm/sysreg.h>
@@ -187,9 +188,20 @@ static int __init topology_init(void)
187 188
188subsys_initcall(topology_init); 189subsys_initcall(topology_init);
189 190
191struct chip_id_map {
192 u16 mid;
193 u16 pn;
194 const char *name;
195};
196
197static const struct chip_id_map chip_names[] = {
198 { .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" },
199};
200#define NR_CHIP_NAMES ARRAY_SIZE(chip_names)
201
190static const char *cpu_names[] = { 202static const char *cpu_names[] = {
191 "Morgan", 203 "Morgan",
192 "AP7000", 204 "AP7",
193}; 205};
194#define NR_CPU_NAMES ARRAY_SIZE(cpu_names) 206#define NR_CPU_NAMES ARRAY_SIZE(cpu_names)
195 207
@@ -206,12 +218,32 @@ static const char *mmu_types[] = {
206 "MPU" 218 "MPU"
207}; 219};
208 220
221static const char *cpu_feature_flags[] = {
222 "rmw", "dsp", "simd", "ocd", "perfctr", "java", "fpu",
223};
224
225static const char *get_chip_name(struct avr32_cpuinfo *cpu)
226{
227 unsigned int i;
228 unsigned int mid = avr32_get_manufacturer_id(cpu);
229 unsigned int pn = avr32_get_product_number(cpu);
230
231 for (i = 0; i < NR_CHIP_NAMES; i++) {
232 if (chip_names[i].mid == mid && chip_names[i].pn == pn)
233 return chip_names[i].name;
234 }
235
236 return "(unknown)";
237}
238
209void __init setup_processor(void) 239void __init setup_processor(void)
210{ 240{
211 unsigned long config0, config1; 241 unsigned long config0, config1;
212 unsigned long features; 242 unsigned long features;
213 unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; 243 unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type;
244 unsigned device_id;
214 unsigned tmp; 245 unsigned tmp;
246 unsigned i;
215 247
216 config0 = sysreg_read(CONFIG0); 248 config0 = sysreg_read(CONFIG0);
217 config1 = sysreg_read(CONFIG1); 249 config1 = sysreg_read(CONFIG1);
@@ -221,11 +253,14 @@ void __init setup_processor(void)
221 arch_rev = SYSREG_BFEXT(AR, config0); 253 arch_rev = SYSREG_BFEXT(AR, config0);
222 mmu_type = SYSREG_BFEXT(MMUT, config0); 254 mmu_type = SYSREG_BFEXT(MMUT, config0);
223 255
256 device_id = ocd_read(DID);
257
224 boot_cpu_data.arch_type = arch_id; 258 boot_cpu_data.arch_type = arch_id;
225 boot_cpu_data.cpu_type = cpu_id; 259 boot_cpu_data.cpu_type = cpu_id;
226 boot_cpu_data.arch_revision = arch_rev; 260 boot_cpu_data.arch_revision = arch_rev;
227 boot_cpu_data.cpu_revision = cpu_rev; 261 boot_cpu_data.cpu_revision = cpu_rev;
228 boot_cpu_data.tlb_config = mmu_type; 262 boot_cpu_data.tlb_config = mmu_type;
263 boot_cpu_data.device_id = device_id;
229 264
230 tmp = SYSREG_BFEXT(ILSZ, config1); 265 tmp = SYSREG_BFEXT(ILSZ, config1);
231 if (tmp) { 266 if (tmp) {
@@ -247,41 +282,34 @@ void __init setup_processor(void)
247 return; 282 return;
248 } 283 }
249 284
250 printk ("CPU: %s [%02x] revision %d (%s revision %d)\n", 285 printk ("CPU: %s chip revision %c\n", get_chip_name(&boot_cpu_data),
286 avr32_get_chip_revision(&boot_cpu_data) + 'A');
287 printk ("CPU: %s [%02x] core revision %d (%s arch revision %d)\n",
251 cpu_names[cpu_id], cpu_id, cpu_rev, 288 cpu_names[cpu_id], cpu_id, cpu_rev,
252 arch_names[arch_id], arch_rev); 289 arch_names[arch_id], arch_rev);
253 printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); 290 printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]);
254 291
255 printk ("CPU: features:"); 292 printk ("CPU: features:");
256 features = 0; 293 features = 0;
257 if (config0 & SYSREG_BIT(CONFIG0_R)) { 294 if (config0 & SYSREG_BIT(CONFIG0_R))
258 features |= AVR32_FEATURE_RMW; 295 features |= AVR32_FEATURE_RMW;
259 printk(" rmw"); 296 if (config0 & SYSREG_BIT(CONFIG0_D))
260 }
261 if (config0 & SYSREG_BIT(CONFIG0_D)) {
262 features |= AVR32_FEATURE_DSP; 297 features |= AVR32_FEATURE_DSP;
263 printk(" dsp"); 298 if (config0 & SYSREG_BIT(CONFIG0_S))
264 }
265 if (config0 & SYSREG_BIT(CONFIG0_S)) {
266 features |= AVR32_FEATURE_SIMD; 299 features |= AVR32_FEATURE_SIMD;
267 printk(" simd"); 300 if (config0 & SYSREG_BIT(CONFIG0_O))
268 }
269 if (config0 & SYSREG_BIT(CONFIG0_O)) {
270 features |= AVR32_FEATURE_OCD; 301 features |= AVR32_FEATURE_OCD;
271 printk(" ocd"); 302 if (config0 & SYSREG_BIT(CONFIG0_P))
272 }
273 if (config0 & SYSREG_BIT(CONFIG0_P)) {
274 features |= AVR32_FEATURE_PCTR; 303 features |= AVR32_FEATURE_PCTR;
275 printk(" perfctr"); 304 if (config0 & SYSREG_BIT(CONFIG0_J))
276 }
277 if (config0 & SYSREG_BIT(CONFIG0_J)) {
278 features |= AVR32_FEATURE_JAVA; 305 features |= AVR32_FEATURE_JAVA;
279 printk(" java"); 306 if (config0 & SYSREG_BIT(CONFIG0_F))
280 }
281 if (config0 & SYSREG_BIT(CONFIG0_F)) {
282 features |= AVR32_FEATURE_FPU; 307 features |= AVR32_FEATURE_FPU;
283 printk(" fpu"); 308
284 } 309 for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++)
310 if (features & (1 << i))
311 printk(" %s", cpu_feature_flags[i]);
312
285 printk("\n"); 313 printk("\n");
286 boot_cpu_data.features = features; 314 boot_cpu_data.features = features;
287} 315}
@@ -291,6 +319,8 @@ static int c_show(struct seq_file *m, void *v)
291{ 319{
292 unsigned int icache_size, dcache_size; 320 unsigned int icache_size, dcache_size;
293 unsigned int cpu = smp_processor_id(); 321 unsigned int cpu = smp_processor_id();
322 unsigned int freq;
323 unsigned int i;
294 324
295 icache_size = boot_cpu_data.icache.ways * 325 icache_size = boot_cpu_data.icache.ways *
296 boot_cpu_data.icache.sets * 326 boot_cpu_data.icache.sets *
@@ -301,15 +331,21 @@ static int c_show(struct seq_file *m, void *v)
301 331
302 seq_printf(m, "processor\t: %d\n", cpu); 332 seq_printf(m, "processor\t: %d\n", cpu);
303 333
334 seq_printf(m, "chip type\t: %s revision %c\n",
335 get_chip_name(&boot_cpu_data),
336 avr32_get_chip_revision(&boot_cpu_data) + 'A');
304 if (boot_cpu_data.arch_type < NR_ARCH_NAMES) 337 if (boot_cpu_data.arch_type < NR_ARCH_NAMES)
305 seq_printf(m, "cpu family\t: %s revision %d\n", 338 seq_printf(m, "cpu arch\t: %s revision %d\n",
306 arch_names[boot_cpu_data.arch_type], 339 arch_names[boot_cpu_data.arch_type],
307 boot_cpu_data.arch_revision); 340 boot_cpu_data.arch_revision);
308 if (boot_cpu_data.cpu_type < NR_CPU_NAMES) 341 if (boot_cpu_data.cpu_type < NR_CPU_NAMES)
309 seq_printf(m, "cpu type\t: %s revision %d\n", 342 seq_printf(m, "cpu core\t: %s revision %d\n",
310 cpu_names[boot_cpu_data.cpu_type], 343 cpu_names[boot_cpu_data.cpu_type],
311 boot_cpu_data.cpu_revision); 344 boot_cpu_data.cpu_revision);
312 345
346 freq = (clk_get_rate(boot_cpu_data.clk) + 500) / 1000;
347 seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, freq % 1000);
348
313 seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", 349 seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n",
314 icache_size >> 10, 350 icache_size >> 10,
315 boot_cpu_data.icache.ways, 351 boot_cpu_data.icache.ways,
@@ -320,7 +356,13 @@ static int c_show(struct seq_file *m, void *v)
320 boot_cpu_data.dcache.ways, 356 boot_cpu_data.dcache.ways,
321 boot_cpu_data.dcache.sets, 357 boot_cpu_data.dcache.sets,
322 boot_cpu_data.dcache.linesz); 358 boot_cpu_data.dcache.linesz);
323 seq_printf(m, "bogomips\t: %lu.%02lu\n", 359
360 seq_printf(m, "features\t:");
361 for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++)
362 if (boot_cpu_data.features & (1 << i))
363 seq_printf(m, " %s", cpu_feature_flags[i]);
364
365 seq_printf(m, "\nbogomips\t: %lu.%02lu\n",
324 boot_cpu_data.loops_per_jiffy / (500000/HZ), 366 boot_cpu_data.loops_per_jiffy / (500000/HZ),
325 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); 367 (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100);
326 368
@@ -343,7 +385,7 @@ static void c_stop(struct seq_file *m, void *v)
343 385
344} 386}
345 387
346struct seq_operations cpuinfo_op = { 388const struct seq_operations cpuinfo_op = {
347 .start = c_start, 389 .start = c_start,
348 .next = c_next, 390 .next = c_next,
349 .stop = c_stop, 391 .stop = c_stop,
diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c
index 61f2de266f62..a8e767d836aa 100644
--- a/arch/avr32/kernel/irq.c
+++ b/arch/avr32/kernel/irq.c
@@ -25,6 +25,17 @@ void ack_bad_irq(unsigned int irq)
25 printk("unexpected IRQ %u\n", irq); 25 printk("unexpected IRQ %u\n", irq);
26} 26}
27 27
28/* May be overridden by platform code */
29int __weak nmi_enable(void)
30{
31 return -ENOSYS;
32}
33
34void __weak nmi_disable(void)
35{
36
37}
38
28#ifdef CONFIG_PROC_FS 39#ifdef CONFIG_PROC_FS
29int show_interrupts(struct seq_file *p, void *v) 40int show_interrupts(struct seq_file *p, void *v)
30{ 41{
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 799ba89b07a8..f820e9f25520 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -48,6 +48,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
48void __kprobes arch_arm_kprobe(struct kprobe *p) 48void __kprobes arch_arm_kprobe(struct kprobe *p)
49{ 49{
50 pr_debug("arming kprobe at %p\n", p->addr); 50 pr_debug("arming kprobe at %p\n", p->addr);
51 ocd_enable(NULL);
51 *p->addr = BREAKPOINT_INSTRUCTION; 52 *p->addr = BREAKPOINT_INSTRUCTION;
52 flush_icache_range((unsigned long)p->addr, 53 flush_icache_range((unsigned long)p->addr,
53 (unsigned long)p->addr + sizeof(kprobe_opcode_t)); 54 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
@@ -56,6 +57,7 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
56void __kprobes arch_disarm_kprobe(struct kprobe *p) 57void __kprobes arch_disarm_kprobe(struct kprobe *p)
57{ 58{
58 pr_debug("disarming kprobe at %p\n", p->addr); 59 pr_debug("disarming kprobe at %p\n", p->addr);
60 ocd_disable(NULL);
59 *p->addr = p->opcode; 61 *p->addr = p->opcode;
60 flush_icache_range((unsigned long)p->addr, 62 flush_icache_range((unsigned long)p->addr,
61 (unsigned long)p->addr + sizeof(kprobe_opcode_t)); 63 (unsigned long)p->addr + sizeof(kprobe_opcode_t));
@@ -260,9 +262,6 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
260 262
261int __init arch_init_kprobes(void) 263int __init arch_init_kprobes(void)
262{ 264{
263 printk("KPROBES: Enabling monitor mode (MM|DBE)...\n");
264 ocd_write(DC, (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT));
265
266 /* TODO: Register kretprobe trampoline */ 265 /* TODO: Register kretprobe trampoline */
267 return 0; 266 return 0;
268} 267}
diff --git a/arch/avr32/kernel/nmi_debug.c b/arch/avr32/kernel/nmi_debug.c
new file mode 100644
index 000000000000..3414b8566c29
--- /dev/null
+++ b/arch/avr32/kernel/nmi_debug.c
@@ -0,0 +1,82 @@
1/*
2 * Copyright (C) 2007 Atmel Corporation
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/delay.h>
9#include <linux/kdebug.h>
10#include <linux/notifier.h>
11#include <linux/sched.h>
12
13#include <asm/irq.h>
14
15enum nmi_action {
16 NMI_SHOW_STATE = 1 << 0,
17 NMI_SHOW_REGS = 1 << 1,
18 NMI_DIE = 1 << 2,
19 NMI_DEBOUNCE = 1 << 3,
20};
21
22static unsigned long nmi_actions;
23
24static int nmi_debug_notify(struct notifier_block *self,
25 unsigned long val, void *data)
26{
27 struct die_args *args = data;
28
29 if (likely(val != DIE_NMI))
30 return NOTIFY_DONE;
31
32 if (nmi_actions & NMI_SHOW_STATE)
33 show_state();
34 if (nmi_actions & NMI_SHOW_REGS)
35 show_regs(args->regs);
36 if (nmi_actions & NMI_DEBOUNCE)
37 mdelay(10);
38 if (nmi_actions & NMI_DIE)
39 return NOTIFY_BAD;
40
41 return NOTIFY_OK;
42}
43
44static struct notifier_block nmi_debug_nb = {
45 .notifier_call = nmi_debug_notify,
46};
47
48static int __init nmi_debug_setup(char *str)
49{
50 char *p, *sep;
51
52 register_die_notifier(&nmi_debug_nb);
53 if (nmi_enable()) {
54 printk(KERN_WARNING "Unable to enable NMI.\n");
55 return 0;
56 }
57
58 if (*str != '=')
59 return 0;
60
61 for (p = str + 1; *p; p = sep + 1) {
62 sep = strchr(p, ',');
63 if (sep)
64 *sep = 0;
65 if (strcmp(p, "state") == 0)
66 nmi_actions |= NMI_SHOW_STATE;
67 else if (strcmp(p, "regs") == 0)
68 nmi_actions |= NMI_SHOW_REGS;
69 else if (strcmp(p, "debounce") == 0)
70 nmi_actions |= NMI_DEBOUNCE;
71 else if (strcmp(p, "die") == 0)
72 nmi_actions |= NMI_DIE;
73 else
74 printk(KERN_WARNING "NMI: Unrecognized action `%s'\n",
75 p);
76 if (!sep)
77 break;
78 }
79
80 return 0;
81}
82__setup("nmi_debug", nmi_debug_setup);
diff --git a/arch/avr32/kernel/ocd.c b/arch/avr32/kernel/ocd.c
new file mode 100644
index 000000000000..c4f023294d75
--- /dev/null
+++ b/arch/avr32/kernel/ocd.c
@@ -0,0 +1,163 @@
1/*
2 * Copyright (C) 2007 Atmel Corporation
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/init.h>
9#include <linux/sched.h>
10#include <linux/spinlock.h>
11
12#include <asm/ocd.h>
13
14static long ocd_count;
15static spinlock_t ocd_lock;
16
17/**
18 * ocd_enable - enable on-chip debugging
19 * @child: task to be debugged
20 *
21 * If @child is non-NULL, ocd_enable() first checks if debugging has
22 * already been enabled for @child, and if it has, does nothing.
23 *
24 * If @child is NULL (e.g. when debugging the kernel), or debugging
25 * has not already been enabled for it, ocd_enable() increments the
26 * reference count and enables the debugging hardware.
27 */
28void ocd_enable(struct task_struct *child)
29{
30 u32 dc;
31
32 if (child)
33 pr_debug("ocd_enable: child=%s [%u]\n",
34 child->comm, child->pid);
35 else
36 pr_debug("ocd_enable (no child)\n");
37
38 if (!child || !test_and_set_tsk_thread_flag(child, TIF_DEBUG)) {
39 spin_lock(&ocd_lock);
40 ocd_count++;
41 dc = ocd_read(DC);
42 dc |= (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT);
43 ocd_write(DC, dc);
44 spin_unlock(&ocd_lock);
45 }
46}
47
48/**
49 * ocd_disable - disable on-chip debugging
50 * @child: task that was being debugged, but isn't anymore
51 *
52 * If @child is non-NULL, ocd_disable() checks if debugging is enabled
53 * for @child, and if it isn't, does nothing.
54 *
55 * If @child is NULL (e.g. when debugging the kernel), or debugging is
56 * enabled, ocd_disable() decrements the reference count, and if it
57 * reaches zero, disables the debugging hardware.
58 */
59void ocd_disable(struct task_struct *child)
60{
61 u32 dc;
62
63 if (!child)
64 pr_debug("ocd_disable (no child)\n");
65 else if (test_tsk_thread_flag(child, TIF_DEBUG))
66 pr_debug("ocd_disable: child=%s [%u]\n",
67 child->comm, child->pid);
68
69 if (!child || test_and_clear_tsk_thread_flag(child, TIF_DEBUG)) {
70 spin_lock(&ocd_lock);
71 ocd_count--;
72
73 WARN_ON(ocd_count < 0);
74
75 if (ocd_count <= 0) {
76 dc = ocd_read(DC);
77 dc &= ~((1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT));
78 ocd_write(DC, dc);
79 }
80 spin_unlock(&ocd_lock);
81 }
82}
83
84#ifdef CONFIG_DEBUG_FS
85#include <linux/debugfs.h>
86#include <linux/module.h>
87
88static struct dentry *ocd_debugfs_root;
89static struct dentry *ocd_debugfs_DC;
90static struct dentry *ocd_debugfs_DS;
91static struct dentry *ocd_debugfs_count;
92
93static u64 ocd_DC_get(void *data)
94{
95 return ocd_read(DC);
96}
97static void ocd_DC_set(void *data, u64 val)
98{
99 ocd_write(DC, val);
100}
101DEFINE_SIMPLE_ATTRIBUTE(fops_DC, ocd_DC_get, ocd_DC_set, "0x%08llx\n");
102
103static u64 ocd_DS_get(void *data)
104{
105 return ocd_read(DS);
106}
107DEFINE_SIMPLE_ATTRIBUTE(fops_DS, ocd_DS_get, NULL, "0x%08llx\n");
108
109static u64 ocd_count_get(void *data)
110{
111 return ocd_count;
112}
113DEFINE_SIMPLE_ATTRIBUTE(fops_count, ocd_count_get, NULL, "%lld\n");
114
115static void ocd_debugfs_init(void)
116{
117 struct dentry *root;
118
119 root = debugfs_create_dir("ocd", NULL);
120 if (IS_ERR(root) || !root)
121 goto err_root;
122 ocd_debugfs_root = root;
123
124 ocd_debugfs_DC = debugfs_create_file("DC", S_IRUSR | S_IWUSR,
125 root, NULL, &fops_DC);
126 if (!ocd_debugfs_DC)
127 goto err_DC;
128
129 ocd_debugfs_DS = debugfs_create_file("DS", S_IRUSR, root,
130 NULL, &fops_DS);
131 if (!ocd_debugfs_DS)
132 goto err_DS;
133
134 ocd_debugfs_count = debugfs_create_file("count", S_IRUSR, root,
135 NULL, &fops_count);
136 if (!ocd_debugfs_count)
137 goto err_count;
138
139 return;
140
141err_count:
142 debugfs_remove(ocd_debugfs_DS);
143err_DS:
144 debugfs_remove(ocd_debugfs_DC);
145err_DC:
146 debugfs_remove(ocd_debugfs_root);
147err_root:
148 printk(KERN_WARNING "OCD: Failed to create debugfs entries\n");
149}
150#else
151static inline void ocd_debugfs_init(void)
152{
153
154}
155#endif
156
157static int __init ocd_init(void)
158{
159 spin_lock_init(&ocd_lock);
160 ocd_debugfs_init();
161 return 0;
162}
163arch_initcall(ocd_init);
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c
index 9d6dac8af7a2..eaaa69bbdc38 100644
--- a/arch/avr32/kernel/process.c
+++ b/arch/avr32/kernel/process.c
@@ -103,7 +103,7 @@ EXPORT_SYMBOL(kernel_thread);
103 */ 103 */
104void exit_thread(void) 104void exit_thread(void)
105{ 105{
106 /* nothing to do */ 106 ocd_disable(current);
107} 107}
108 108
109void flush_thread(void) 109void flush_thread(void)
@@ -345,6 +345,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
345 p->thread.cpu_context.ksp = (unsigned long)childregs; 345 p->thread.cpu_context.ksp = (unsigned long)childregs;
346 p->thread.cpu_context.pc = (unsigned long)ret_from_fork; 346 p->thread.cpu_context.pc = (unsigned long)ret_from_fork;
347 347
348 if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG))
349 ocd_enable(p);
350
348 return 0; 351 return 0;
349} 352}
350 353
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 002369e44093..1fed38fcf594 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -58,6 +58,7 @@ void ptrace_disable(struct task_struct *child)
58{ 58{
59 clear_tsk_thread_flag(child, TIF_SINGLE_STEP); 59 clear_tsk_thread_flag(child, TIF_SINGLE_STEP);
60 clear_tsk_thread_flag(child, TIF_BREAKPOINT); 60 clear_tsk_thread_flag(child, TIF_BREAKPOINT);
61 ocd_disable(child);
61} 62}
62 63
63/* 64/*
@@ -144,10 +145,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
144{ 145{
145 int ret; 146 int ret;
146 147
147 pr_debug("ptrace: Enabling monitor mode...\n");
148 ocd_write(DC, ocd_read(DC) | (1 << OCD_DC_MM_BIT)
149 | (1 << OCD_DC_DBE_BIT));
150
151 switch (request) { 148 switch (request) {
152 /* Read the word at location addr in the child process */ 149 /* Read the word at location addr in the child process */
153 case PTRACE_PEEKTEXT: 150 case PTRACE_PEEKTEXT:
diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c
index 0ec14854a200..5616a00c10ba 100644
--- a/arch/avr32/kernel/signal.c
+++ b/arch/avr32/kernel/signal.c
@@ -270,19 +270,12 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
270 if (!user_mode(regs)) 270 if (!user_mode(regs))
271 return 0; 271 return 0;
272 272
273 if (try_to_freeze()) {
274 signr = 0;
275 if (!signal_pending(current))
276 goto no_signal;
277 }
278
279 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 273 if (test_thread_flag(TIF_RESTORE_SIGMASK))
280 oldset = &current->saved_sigmask; 274 oldset = &current->saved_sigmask;
281 else if (!oldset) 275 else if (!oldset)
282 oldset = &current->blocked; 276 oldset = &current->blocked;
283 277
284 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 278 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
285no_signal:
286 if (syscall) { 279 if (syscall) {
287 switch (regs->r12) { 280 switch (regs->r12) {
288 case -ERESTART_RESTARTBLOCK: 281 case -ERESTART_RESTARTBLOCK:
diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c
index 870c075e6314..cf6f686d9b0b 100644
--- a/arch/avr32/kernel/traps.c
+++ b/arch/avr32/kernel/traps.c
@@ -9,6 +9,7 @@
9#include <linux/bug.h> 9#include <linux/bug.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/kallsyms.h> 11#include <linux/kallsyms.h>
12#include <linux/kdebug.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/notifier.h> 14#include <linux/notifier.h>
14#include <linux/sched.h> 15#include <linux/sched.h>
@@ -107,9 +108,23 @@ void _exception(long signr, struct pt_regs *regs, int code,
107 108
108asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) 109asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
109{ 110{
110 printk(KERN_ALERT "Got Non-Maskable Interrupt, dumping regs\n"); 111 int ret;
111 show_regs_log_lvl(regs, KERN_ALERT); 112
112 show_stack_log_lvl(current, regs->sp, regs, KERN_ALERT); 113 nmi_enter();
114
115 ret = notify_die(DIE_NMI, "NMI", regs, 0, ecr, SIGINT);
116 switch (ret) {
117 case NOTIFY_OK:
118 case NOTIFY_STOP:
119 return;
120 case NOTIFY_BAD:
121 die("Fatal Non-Maskable Interrupt", regs, SIGINT);
122 default:
123 break;
124 }
125
126 printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
127 nmi_disable();
113} 128}
114 129
115asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) 130asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)