diff options
author | Hans-Christian Noren Egtvedt | 2017-02-26 12:56:39 +0100 |
---|---|---|
committer | Hans-Christian Noren Egtvedt | 2017-05-01 09:27:15 +0200 |
commit | 26202873bb51fafdaa51be3e8de7aab9beb49f70 (patch) | |
tree | c3ba9451f8fa93e6bd6347318375a7348ecb522f /arch/avr32/kernel | |
parent | a351e9b9fc24e982ec2f0e76379a49826036da12 (diff) |
avr32: remove support for AVR32 architecture
This patch drops support for AVR32 architecture from the Linux kernel.
The AVR32 architecture is not keeping up with the development of the
kernel, and since it shares so much of the drivers with Atmel ARM SoC,
it is starting to hinder these drivers to develop swiftly.
Also, all AVR32 AP7 SoC processors are end of lifed from Atmel (now
Microchip).
Finally, the GCC toolchain is stuck at version 4.2.x, and has not
received any patches since the last release from Atmel;
4.2.4-atmel.1.1.3.avr32linux.1. When building kernel v4.10, this
toolchain is no longer able to properly link the network stack.
Haavard and I have came to the conclusion that we feel keeping AVR32 on
life support offers more obstacles for Atmel ARMs, than it gives joy to
AVR32 users. I also suspect there are very few AVR32 users left today,
if anybody at all.
Signed-off-by: Hans-Christian Noren Egtvedt <egtvedt@samfundet.no>
Signed-off-by: HÃ¥vard Skinnemoen <hskinnemoen@gmail.com>
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
Acked-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Diffstat (limited to 'arch/avr32/kernel')
-rw-r--r-- | arch/avr32/kernel/.gitignore | 1 | ||||
-rw-r--r-- | arch/avr32/kernel/Makefile | 15 | ||||
-rw-r--r-- | arch/avr32/kernel/asm-offsets.c | 24 | ||||
-rw-r--r-- | arch/avr32/kernel/avr32_ksyms.c | 70 | ||||
-rw-r--r-- | arch/avr32/kernel/cpu.c | 410 | ||||
-rw-r--r-- | arch/avr32/kernel/entry-avr32b.S | 877 | ||||
-rw-r--r-- | arch/avr32/kernel/head.S | 22 | ||||
-rw-r--r-- | arch/avr32/kernel/irq.c | 28 | ||||
-rw-r--r-- | arch/avr32/kernel/kprobes.c | 267 | ||||
-rw-r--r-- | arch/avr32/kernel/module.c | 291 | ||||
-rw-r--r-- | arch/avr32/kernel/nmi_debug.c | 83 | ||||
-rw-r--r-- | arch/avr32/kernel/ocd.c | 167 | ||||
-rw-r--r-- | arch/avr32/kernel/process.c | 358 | ||||
-rw-r--r-- | arch/avr32/kernel/ptrace.c | 357 | ||||
-rw-r--r-- | arch/avr32/kernel/setup.c | 609 | ||||
-rw-r--r-- | arch/avr32/kernel/signal.c | 288 | ||||
-rw-r--r-- | arch/avr32/kernel/stacktrace.c | 56 | ||||
-rw-r--r-- | arch/avr32/kernel/switch_to.S | 35 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall-stubs.S | 153 | ||||
-rw-r--r-- | arch/avr32/kernel/syscall_table.S | 347 | ||||
-rw-r--r-- | arch/avr32/kernel/time.c | 161 | ||||
-rw-r--r-- | arch/avr32/kernel/traps.c | 262 | ||||
-rw-r--r-- | arch/avr32/kernel/vmlinux.lds.S | 89 |
23 files changed, 0 insertions, 4970 deletions
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/arch/avr32/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmlinux.lds diff --git a/arch/avr32/kernel/Makefile b/arch/avr32/kernel/Makefile deleted file mode 100644 index 119a2e41defe..000000000000 --- a/arch/avr32/kernel/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# -# Makefile for the Linux/AVR32 kernel. -# - -extra-y := head.o vmlinux.lds - -obj-$(CONFIG_SUBARCH_AVR32B) += entry-avr32b.o -obj-y += syscall_table.o syscall-stubs.o irq.o -obj-y += setup.o traps.o ocd.o ptrace.o -obj-y += signal.o process.o time.o -obj-y += switch_to.o cpu.o -obj-$(CONFIG_MODULES) += module.o avr32_ksyms.o -obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_STACKTRACE) += stacktrace.o -obj-$(CONFIG_NMI_DEBUGGING) += nmi_debug.o diff --git a/arch/avr32/kernel/asm-offsets.c b/arch/avr32/kernel/asm-offsets.c deleted file mode 100644 index 2c9764fe3532..000000000000 --- a/arch/avr32/kernel/asm-offsets.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Generate definitions needed by assembly language modules. - * This code generates raw asm output which is post-processed - * to extract and format the required data. - */ - -#include <linux/mm.h> -#include <linux/sched.h> -#include <linux/thread_info.h> -#include <linux/kbuild.h> - -void foo(void) -{ - OFFSET(TI_task, thread_info, task); - OFFSET(TI_flags, thread_info, flags); - OFFSET(TI_cpu, thread_info, cpu); - OFFSET(TI_preempt_count, thread_info, preempt_count); - OFFSET(TI_rar_saved, thread_info, rar_saved); - OFFSET(TI_rsr_saved, thread_info, rsr_saved); - BLANK(); - OFFSET(TSK_active_mm, task_struct, active_mm); - BLANK(); - OFFSET(MM_pgd, mm_struct, pgd); -} diff --git a/arch/avr32/kernel/avr32_ksyms.c b/arch/avr32/kernel/avr32_ksyms.c deleted file mode 100644 index 0d05fd095468..000000000000 --- a/arch/avr32/kernel/avr32_ksyms.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Export AVR32-specific functions for loadable modules. - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/module.h> - -#include <asm/checksum.h> -#include <linux/uaccess.h> - -/* - * GCC functions - */ -extern unsigned long long __avr32_lsl64(unsigned long long u, unsigned long b); -extern unsigned long long __avr32_lsr64(unsigned long long u, unsigned long b); -extern unsigned long long __avr32_asr64(unsigned long long u, unsigned long b); -EXPORT_SYMBOL(__avr32_lsl64); -EXPORT_SYMBOL(__avr32_lsr64); -EXPORT_SYMBOL(__avr32_asr64); - -/* - * String functions - */ -EXPORT_SYMBOL(memset); -EXPORT_SYMBOL(memcpy); - -EXPORT_SYMBOL(clear_page); -EXPORT_SYMBOL(copy_page); - -/* - * Userspace access stuff. - */ -EXPORT_SYMBOL(___copy_from_user); -EXPORT_SYMBOL(copy_to_user); -EXPORT_SYMBOL(__copy_user); -EXPORT_SYMBOL(strncpy_from_user); -EXPORT_SYMBOL(__strncpy_from_user); -EXPORT_SYMBOL(clear_user); -EXPORT_SYMBOL(__clear_user); -EXPORT_SYMBOL(strnlen_user); - -EXPORT_SYMBOL(csum_partial); -EXPORT_SYMBOL(csum_partial_copy_generic); - -/* Delay loops (lib/delay.S) */ -EXPORT_SYMBOL(__ndelay); -EXPORT_SYMBOL(__udelay); -EXPORT_SYMBOL(__const_udelay); - -/* Bit operations (lib/findbit.S) */ -EXPORT_SYMBOL(find_first_zero_bit); -EXPORT_SYMBOL(find_next_zero_bit); -EXPORT_SYMBOL(find_first_bit); -EXPORT_SYMBOL(find_next_bit); -EXPORT_SYMBOL(find_next_bit_le); -EXPORT_SYMBOL(find_next_zero_bit_le); - -/* I/O primitives (lib/io-*.S) */ -EXPORT_SYMBOL(__raw_readsb); -EXPORT_SYMBOL(__raw_readsw); -EXPORT_SYMBOL(__raw_readsl); -EXPORT_SYMBOL(__raw_writesb); -EXPORT_SYMBOL(__raw_writesw); -EXPORT_SYMBOL(__raw_writesl); diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c deleted file mode 100644 index 0341ae27c9ec..000000000000 --- a/arch/avr32/kernel/cpu.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/device.h> -#include <linux/seq_file.h> -#include <linux/cpu.h> -#include <linux/module.h> -#include <linux/percpu.h> -#include <linux/param.h> -#include <linux/errno.h> -#include <linux/clk.h> - -#include <asm/setup.h> -#include <asm/sysreg.h> - -static DEFINE_PER_CPU(struct cpu, cpu_devices); - -#ifdef CONFIG_PERFORMANCE_COUNTERS - -/* - * XXX: If/when a SMP-capable implementation of AVR32 will ever be - * made, we must make sure that the code executes on the correct CPU. - */ -static ssize_t show_pc0event(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f); -} -static ssize_t store_pc0event(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val > 0x3f) - return -EINVAL; - val = (val << 12) | (sysreg_read(PCCR) & 0xfffc0fff); - sysreg_write(PCCR, val); - return count; -} -static ssize_t show_pc0count(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pcnt0; - - pcnt0 = sysreg_read(PCNT0); - return sprintf(buf, "%lu\n", pcnt0); -} -static ssize_t store_pc0count(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCNT0, val); - - return count; -} - -static ssize_t show_pc1event(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f); -} -static ssize_t store_pc1event(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val > 0x3f) - return -EINVAL; - val = (val << 18) | (sysreg_read(PCCR) & 0xff03ffff); - sysreg_write(PCCR, val); - return count; -} -static ssize_t show_pc1count(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pcnt1; - - pcnt1 = sysreg_read(PCNT1); - return sprintf(buf, "%lu\n", pcnt1); -} -static ssize_t store_pc1count(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCNT1, val); - - return count; -} - -static ssize_t show_pccycles(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccnt; - - pccnt = sysreg_read(PCCNT); - return sprintf(buf, "%lu\n", pccnt); -} -static ssize_t store_pccycles(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - sysreg_write(PCCNT, val); - - return count; -} - -static ssize_t show_pcenable(struct device *dev, - struct device_attribute *attr, char *buf) -{ - unsigned long pccr; - - pccr = sysreg_read(PCCR); - return sprintf(buf, "%c\n", (pccr & 1)?'1':'0'); -} -static ssize_t store_pcenable(struct device *dev, - struct device_attribute *attr, const char *buf, - size_t count) -{ - unsigned long pccr, val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) - return ret; - if (val) - val = 1; - - pccr = sysreg_read(PCCR); - pccr = (pccr & ~1UL) | val; - sysreg_write(PCCR, pccr); - - return count; -} - -static DEVICE_ATTR(pc0event, 0600, show_pc0event, store_pc0event); -static DEVICE_ATTR(pc0count, 0600, show_pc0count, store_pc0count); -static DEVICE_ATTR(pc1event, 0600, show_pc1event, store_pc1event); -static DEVICE_ATTR(pc1count, 0600, show_pc1count, store_pc1count); -static DEVICE_ATTR(pccycles, 0600, show_pccycles, store_pccycles); -static DEVICE_ATTR(pcenable, 0600, show_pcenable, store_pcenable); - -#endif /* CONFIG_PERFORMANCE_COUNTERS */ - -static int __init topology_init(void) -{ - int cpu; - - for_each_possible_cpu(cpu) { - struct cpu *c = &per_cpu(cpu_devices, cpu); - - register_cpu(c, cpu); - -#ifdef CONFIG_PERFORMANCE_COUNTERS - device_create_file(&c->dev, &dev_attr_pc0event); - device_create_file(&c->dev, &dev_attr_pc0count); - device_create_file(&c->dev, &dev_attr_pc1event); - device_create_file(&c->dev, &dev_attr_pc1count); - device_create_file(&c->dev, &dev_attr_pccycles); - device_create_file(&c->dev, &dev_attr_pcenable); -#endif - } - - return 0; -} - -subsys_initcall(topology_init); - -struct chip_id_map { - u16 mid; - u16 pn; - const char *name; -}; - -static const struct chip_id_map chip_names[] = { - { .mid = 0x1f, .pn = 0x1e82, .name = "AT32AP700x" }, -}; -#define NR_CHIP_NAMES ARRAY_SIZE(chip_names) - -static const char *cpu_names[] = { - "Morgan", - "AP7", -}; -#define NR_CPU_NAMES ARRAY_SIZE(cpu_names) - -static const char *arch_names[] = { - "AVR32A", - "AVR32B", -}; -#define NR_ARCH_NAMES ARRAY_SIZE(arch_names) - -static const char *mmu_types[] = { - "No MMU", - "ITLB and DTLB", - "Shared TLB", - "MPU" -}; - -static const char *cpu_feature_flags[] = { - "rmw", "dsp", "simd", "ocd", "perfctr", "java", "fpu", -}; - -static const char *get_chip_name(struct avr32_cpuinfo *cpu) -{ - unsigned int i; - unsigned int mid = avr32_get_manufacturer_id(cpu); - unsigned int pn = avr32_get_product_number(cpu); - - for (i = 0; i < NR_CHIP_NAMES; i++) { - if (chip_names[i].mid == mid && chip_names[i].pn == pn) - return chip_names[i].name; - } - - return "(unknown)"; -} - -void __init setup_processor(void) -{ - unsigned long config0, config1; - unsigned long features; - unsigned cpu_id, cpu_rev, arch_id, arch_rev, mmu_type; - unsigned device_id; - unsigned tmp; - unsigned i; - - config0 = sysreg_read(CONFIG0); - config1 = sysreg_read(CONFIG1); - cpu_id = SYSREG_BFEXT(PROCESSORID, config0); - cpu_rev = SYSREG_BFEXT(PROCESSORREVISION, config0); - arch_id = SYSREG_BFEXT(AT, config0); - arch_rev = SYSREG_BFEXT(AR, config0); - mmu_type = SYSREG_BFEXT(MMUT, config0); - - device_id = ocd_read(DID); - - boot_cpu_data.arch_type = arch_id; - boot_cpu_data.cpu_type = cpu_id; - boot_cpu_data.arch_revision = arch_rev; - boot_cpu_data.cpu_revision = cpu_rev; - boot_cpu_data.tlb_config = mmu_type; - boot_cpu_data.device_id = device_id; - - tmp = SYSREG_BFEXT(ILSZ, config1); - if (tmp) { - boot_cpu_data.icache.ways = 1 << SYSREG_BFEXT(IASS, config1); - boot_cpu_data.icache.sets = 1 << SYSREG_BFEXT(ISET, config1); - boot_cpu_data.icache.linesz = 1 << (tmp + 1); - } - tmp = SYSREG_BFEXT(DLSZ, config1); - if (tmp) { - boot_cpu_data.dcache.ways = 1 << SYSREG_BFEXT(DASS, config1); - boot_cpu_data.dcache.sets = 1 << SYSREG_BFEXT(DSET, config1); - boot_cpu_data.dcache.linesz = 1 << (tmp + 1); - } - - if ((cpu_id >= NR_CPU_NAMES) || (arch_id >= NR_ARCH_NAMES)) { - printk ("Unknown CPU configuration (ID %02x, arch %02x), " - "continuing anyway...\n", - cpu_id, arch_id); - return; - } - - printk ("CPU: %s chip revision %c\n", get_chip_name(&boot_cpu_data), - avr32_get_chip_revision(&boot_cpu_data) + 'A'); - printk ("CPU: %s [%02x] core revision %d (%s arch revision %d)\n", - cpu_names[cpu_id], cpu_id, cpu_rev, - arch_names[arch_id], arch_rev); - printk ("CPU: MMU configuration: %s\n", mmu_types[mmu_type]); - - printk ("CPU: features:"); - features = 0; - if (config0 & SYSREG_BIT(CONFIG0_R)) - features |= AVR32_FEATURE_RMW; - if (config0 & SYSREG_BIT(CONFIG0_D)) - features |= AVR32_FEATURE_DSP; - if (config0 & SYSREG_BIT(CONFIG0_S)) - features |= AVR32_FEATURE_SIMD; - if (config0 & SYSREG_BIT(CONFIG0_O)) - features |= AVR32_FEATURE_OCD; - if (config0 & SYSREG_BIT(CONFIG0_P)) - features |= AVR32_FEATURE_PCTR; - if (config0 & SYSREG_BIT(CONFIG0_J)) - features |= AVR32_FEATURE_JAVA; - if (config0 & SYSREG_BIT(CONFIG0_F)) - features |= AVR32_FEATURE_FPU; - - for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) - if (features & (1 << i)) - printk(" %s", cpu_feature_flags[i]); - - printk("\n"); - boot_cpu_data.features = features; -} - -#ifdef CONFIG_PROC_FS -static int c_show(struct seq_file *m, void *v) -{ - unsigned int icache_size, dcache_size; - unsigned int cpu = smp_processor_id(); - unsigned int freq; - unsigned int i; - - icache_size = boot_cpu_data.icache.ways * - boot_cpu_data.icache.sets * - boot_cpu_data.icache.linesz; - dcache_size = boot_cpu_data.dcache.ways * - boot_cpu_data.dcache.sets * - boot_cpu_data.dcache.linesz; - - seq_printf(m, "processor\t: %d\n", cpu); - - seq_printf(m, "chip type\t: %s revision %c\n", - get_chip_name(&boot_cpu_data), - avr32_get_chip_revision(&boot_cpu_data) + 'A'); - if (boot_cpu_data.arch_type < NR_ARCH_NAMES) - seq_printf(m, "cpu arch\t: %s revision %d\n", - arch_names[boot_cpu_data.arch_type], - boot_cpu_data.arch_revision); - if (boot_cpu_data.cpu_type < NR_CPU_NAMES) - seq_printf(m, "cpu core\t: %s revision %d\n", - cpu_names[boot_cpu_data.cpu_type], - boot_cpu_data.cpu_revision); - - freq = (clk_get_rate(boot_cpu_data.clk) + 500) / 1000; - seq_printf(m, "cpu MHz\t\t: %u.%03u\n", freq / 1000, freq % 1000); - - seq_printf(m, "i-cache\t\t: %dK (%u ways x %u sets x %u)\n", - icache_size >> 10, - boot_cpu_data.icache.ways, - boot_cpu_data.icache.sets, - boot_cpu_data.icache.linesz); - seq_printf(m, "d-cache\t\t: %dK (%u ways x %u sets x %u)\n", - dcache_size >> 10, - boot_cpu_data.dcache.ways, - boot_cpu_data.dcache.sets, - boot_cpu_data.dcache.linesz); - - seq_printf(m, "features\t:"); - for (i = 0; i < ARRAY_SIZE(cpu_feature_flags); i++) - if (boot_cpu_data.features & (1 << i)) - seq_printf(m, " %s", cpu_feature_flags[i]); - - seq_printf(m, "\nbogomips\t: %lu.%02lu\n", - boot_cpu_data.loops_per_jiffy / (500000/HZ), - (boot_cpu_data.loops_per_jiffy / (5000/HZ)) % 100); - - return 0; -} - -static void *c_start(struct seq_file *m, loff_t *pos) -{ - return *pos < 1 ? (void *)1 : NULL; -} - -static void *c_next(struct seq_file *m, void *v, loff_t *pos) -{ - ++*pos; - return NULL; -} - -static void c_stop(struct seq_file *m, void *v) -{ - -} - -const struct seq_operations cpuinfo_op = { - .start = c_start, - .next = c_next, - .stop = c_stop, - .show = c_show -}; -#endif /* CONFIG_PROC_FS */ diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S deleted file mode 100644 index 7301f4806bbe..000000000000 --- a/arch/avr32/kernel/entry-avr32b.S +++ /dev/null @@ -1,877 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * This file contains the low-level entry-points into the kernel, that is, - * exception handlers, debug trap handlers, interrupt handlers and the - * system call handler. - */ -#include <linux/errno.h> - -#include <asm/asm.h> -#include <asm/hardirq.h> -#include <asm/irq.h> -#include <asm/ocd.h> -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/ptrace.h> -#include <asm/sysreg.h> -#include <asm/thread_info.h> -#include <asm/unistd.h> - -#ifdef CONFIG_PREEMPT -# define preempt_stop mask_interrupts -#else -# define preempt_stop -# define fault_resume_kernel fault_restore_all -#endif - -#define __MASK(x) ((1 << (x)) - 1) -#define IRQ_MASK ((__MASK(SOFTIRQ_BITS) << SOFTIRQ_SHIFT) | \ - (__MASK(HARDIRQ_BITS) << HARDIRQ_SHIFT)) - - .section .ex.text,"ax",@progbits - .align 2 -exception_vectors: - bral handle_critical - .align 2 - bral handle_critical - .align 2 - bral do_bus_error_write - .align 2 - bral do_bus_error_read - .align 2 - bral do_nmi_ll - .align 2 - bral handle_address_fault - .align 2 - bral handle_protection_fault - .align 2 - bral handle_debug - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral do_fpe_ll - .align 2 - bral do_illegal_opcode_ll - .align 2 - bral handle_address_fault - .align 2 - bral handle_address_fault - .align 2 - bral handle_protection_fault - .align 2 - bral handle_protection_fault - .align 2 - bral do_dtlb_modified - -#define tlbmiss_save pushm r0-r3 -#define tlbmiss_restore popm r0-r3 - - .org 0x50 - .global itlb_miss -itlb_miss: - tlbmiss_save - rjmp tlb_miss_common - - .org 0x60 -dtlb_miss_read: - tlbmiss_save - rjmp tlb_miss_common - - .org 0x70 -dtlb_miss_write: - tlbmiss_save - - .global tlb_miss_common - .align 2 -tlb_miss_common: - mfsr r0, SYSREG_TLBEAR - mfsr r1, SYSREG_PTBR - - /* - * First level lookup: The PGD contains virtual pointers to - * the second-level page tables, but they may be NULL if not - * present. - */ -pgtbl_lookup: - lsr r2, r0, PGDIR_SHIFT - ld.w r3, r1[r2 << 2] - bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT - cp.w r3, 0 - breq page_table_not_present - - /* Second level lookup */ - ld.w r2, r3[r1 << 2] - mfsr r0, SYSREG_TLBARLO - bld r2, _PAGE_BIT_PRESENT - brcc page_not_present - - /* Mark the page as accessed */ - sbr r2, _PAGE_BIT_ACCESSED - st.w r3[r1 << 2], r2 - - /* Drop software flags */ - andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff - mtsr SYSREG_TLBELO, r2 - - /* Figure out which entry we want to replace */ - mfsr r1, SYSREG_MMUCR - clz r2, r0 - brcc 1f - mov r3, -1 /* All entries have been accessed, */ - mov r2, 0 /* so start at 0 */ - mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */ - -1: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE - mtsr SYSREG_MMUCR, r1 - tlbw - - tlbmiss_restore - rete - - /* The slow path of the TLB miss handler */ - .align 2 -page_table_not_present: - /* Do we need to synchronize with swapper_pg_dir? */ - bld r0, 31 - brcs sync_with_swapper_pg_dir - -page_not_present: - tlbmiss_restore - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_page_fault - rjmp ret_from_exception - - .align 2 -sync_with_swapper_pg_dir: - /* - * If swapper_pg_dir contains a non-NULL second-level page - * table pointer, copy it into the current PGD. If not, we - * must handle it as a full-blown page fault. - * - * Jumping back to pgtbl_lookup causes an unnecessary lookup, - * but it is guaranteed to be a cache hit, it won't happen - * very often, and we absolutely do not want to sacrifice any - * performance in the fast path in order to improve this. - */ - mov r1, lo(swapper_pg_dir) - orh r1, hi(swapper_pg_dir) - ld.w r3, r1[r2 << 2] - cp.w r3, 0 - breq page_not_present - mfsr r1, SYSREG_PTBR - st.w r1[r2 << 2], r3 - rjmp pgtbl_lookup - - /* - * We currently have two bytes left at this point until we - * crash into the system call handler... - * - * Don't worry, the assembler will let us know. - */ - - - /* --- System Call --- */ - - .org 0x100 -system_call: -#ifdef CONFIG_PREEMPT - mask_interrupts -#endif - pushm r12 /* r12_orig */ - stmts --sp, r0-lr - - mfsr r0, SYSREG_RAR_SUP - mfsr r1, SYSREG_RSR_SUP -#ifdef CONFIG_PREEMPT - unmask_interrupts -#endif - zero_fp - stm --sp, r0-r1 - - /* check for syscall tracing */ - get_thread_info r0 - ld.w r1, r0[TI_flags] - bld r1, TIF_SYSCALL_TRACE - brcs syscall_trace_enter - -syscall_trace_cont: - cp.w r8, NR_syscalls - brhs syscall_badsys - - lddpc lr, syscall_table_addr - ld.w lr, lr[r8 << 2] - mov r8, r5 /* 5th argument (6th is pushed by stub) */ - icall lr - - .global syscall_return -syscall_return: - get_thread_info r0 - mask_interrupts /* make sure we don't miss an interrupt - setting need_resched or sigpending - between sampling and the rets */ - - /* Store the return value so that the correct value is loaded below */ - stdsp sp[REG_R12], r12 - - ld.w r1, r0[TI_flags] - andl r1, _TIF_ALLWORK_MASK, COH - brne syscall_exit_work - -syscall_exit_cont: - popm r8-r9 - mtsr SYSREG_RAR_SUP, r8 - mtsr SYSREG_RSR_SUP, r9 - ldmts sp++, r0-lr - sub sp, -4 /* r12_orig */ - rets - - .align 2 -syscall_table_addr: - .long sys_call_table - -syscall_badsys: - mov r12, -ENOSYS - rjmp syscall_return - - .global ret_from_fork -ret_from_fork: - call schedule_tail - mov r12, 0 - rjmp syscall_return - - .global ret_from_kernel_thread -ret_from_kernel_thread: - call schedule_tail - mov r12, r0 - mov lr, r2 /* syscall_return */ - mov pc, r1 - -syscall_trace_enter: - pushm r8-r12 - call syscall_trace - popm r8-r12 - rjmp syscall_trace_cont - -syscall_exit_work: - bld r1, TIF_SYSCALL_TRACE - brcc 1f - unmask_interrupts - call syscall_trace - mask_interrupts - ld.w r1, r0[TI_flags] - -1: bld r1, TIF_NEED_RESCHED - brcc 2f - unmask_interrupts - call schedule - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp 1b - -2: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME - tst r1, r2 - breq 3f - unmask_interrupts - mov r12, sp - mov r11, r0 - call do_notify_resume - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp 1b - -3: bld r1, TIF_BREAKPOINT - brcc syscall_exit_cont - rjmp enter_monitor_mode - - /* This function expects to find offending PC in SYSREG_RAR_EX */ - .type save_full_context_ex, @function - .align 2 -save_full_context_ex: - mfsr r11, SYSREG_RAR_EX - sub r9, pc, . - debug_trampoline - mfsr r8, SYSREG_RSR_EX - cp.w r9, r11 - breq 3f - mov r12, r8 - andh r8, (MODE_MASK >> 16), COH - brne 2f - -1: pushm r11, r12 /* PC and SR */ - unmask_exceptions - ret r12 - -2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) - stdsp sp[4], r10 /* replace saved SP */ - rjmp 1b - - /* - * The debug handler set up a trampoline to make us - * automatically enter monitor mode upon return, but since - * we're saving the full context, we must assume that the - * exception handler might want to alter the return address - * and/or status register. So we need to restore the original - * context and enter monitor mode manually after the exception - * has been handled. - */ -3: get_thread_info r8 - ld.w r11, r8[TI_rar_saved] - ld.w r12, r8[TI_rsr_saved] - rjmp 1b - .size save_full_context_ex, . - save_full_context_ex - - /* Low-level exception handlers */ -handle_critical: - /* - * AT32AP700x errata: - * - * After a Java stack overflow or underflow trap, any CPU - * memory access may cause erratic behavior. This will happen - * when the four least significant bits of the JOSP system - * register contains any value between 9 and 15 (inclusive). - * - * Possible workarounds: - * - Don't use the Java Extension Module - * - Ensure that the stack overflow and underflow trap - * handlers do not do any memory access or trigger any - * exceptions before the overflow/underflow condition is - * cleared (by incrementing or decrementing the JOSP) - * - Make sure that JOSP does not contain any problematic - * value before doing any exception or interrupt - * processing. - * - Set up a critical exception handler which writes a - * known-to-be-safe value, e.g. 4, to JOSP before doing - * any further processing. - * - * We'll use the last workaround for now since we cannot - * guarantee that user space processes don't use Java mode. - * Non-well-behaving userland will be terminated with extreme - * prejudice. - */ -#ifdef CONFIG_CPU_AT32AP700X - /* - * There's a chance we can't touch memory, so temporarily - * borrow PTBR to save the stack pointer while we fix things - * up... - */ - mtsr SYSREG_PTBR, sp - mov sp, 4 - mtsr SYSREG_JOSP, sp - mfsr sp, SYSREG_PTBR - sub pc, -2 - - /* Push most of pt_regs on stack. We'll do the rest later */ - sub sp, 4 - pushm r0-r12 - - /* PTBR mirrors current_thread_info()->task->active_mm->pgd */ - get_thread_info r0 - ld.w r1, r0[TI_task] - ld.w r2, r1[TSK_active_mm] - ld.w r3, r2[MM_pgd] - mtsr SYSREG_PTBR, r3 -#else - sub sp, 4 - pushm r0-r12 -#endif - sub r0, sp, -(14 * 4) - mov r1, lr - mfsr r2, SYSREG_RAR_EX - mfsr r3, SYSREG_RSR_EX - pushm r0-r3 - - mfsr r12, SYSREG_ECR - mov r11, sp - call do_critical_exception - - /* We should never get here... */ -bad_return: - sub r12, pc, (. - 1f) - lddpc pc, 2f - .align 2 -1: .asciz "Return from critical exception!" -2: .long panic - - .align 1 -do_bus_error_write: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mov r11, 1 - rjmp 1f - -do_bus_error_read: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mov r11, 0 -1: mfsr r12, SYSREG_BEAR - mov r10, sp - call do_bus_error - rjmp ret_from_exception - - .align 1 -do_nmi_ll: - sub sp, 4 - stmts --sp, r0-lr - mfsr r9, SYSREG_RSR_NMI - mfsr r8, SYSREG_RAR_NMI - bfextu r0, r9, MODE_SHIFT, 3 - brne 2f - -1: pushm r8, r9 /* PC and SR */ - mfsr r12, SYSREG_ECR - mov r11, sp - call do_nmi - popm r8-r9 - mtsr SYSREG_RAR_NMI, r8 - tst r0, r0 - mtsr SYSREG_RSR_NMI, r9 - brne 3f - - ldmts sp++, r0-lr - sub sp, -4 /* skip r12_orig */ - rete - -2: sub r10, sp, -(FRAME_SIZE_FULL - REG_LR) - stdsp sp[4], r10 /* replace saved SP */ - rjmp 1b - -3: popm lr - sub sp, -4 /* skip sp */ - popm r0-r12 - sub sp, -4 /* skip r12_orig */ - rete - -handle_address_fault: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_address_exception - rjmp ret_from_exception - -handle_protection_fault: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_page_fault - rjmp ret_from_exception - - .align 1 -do_illegal_opcode_ll: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - mfsr r12, SYSREG_ECR - mov r11, sp - call do_illegal_opcode - rjmp ret_from_exception - -do_dtlb_modified: - pushm r0-r3 - mfsr r1, SYSREG_TLBEAR - mfsr r0, SYSREG_PTBR - lsr r2, r1, PGDIR_SHIFT - ld.w r0, r0[r2 << 2] - lsl r1, (32 - PGDIR_SHIFT) - lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT - - /* Translate to virtual address in P1 */ - andl r0, 0xf000 - sbr r0, 31 - add r2, r0, r1 << 2 - ld.w r3, r2[0] - sbr r3, _PAGE_BIT_DIRTY - mov r0, r3 - st.w r2[0], r3 - - /* The page table is up-to-date. Update the TLB entry as well */ - andl r0, lo(_PAGE_FLAGS_HARDWARE_MASK) - mtsr SYSREG_TLBELO, r0 - - /* MMUCR[DRP] is updated automatically, so let's go... */ - tlbw - - popm r0-r3 - rete - -do_fpe_ll: - sub sp, 4 - stmts --sp, r0-lr - call save_full_context_ex - unmask_interrupts - mov r12, 26 - mov r11, sp - call do_fpe - rjmp ret_from_exception - -ret_from_exception: - mask_interrupts - lddsp r4, sp[REG_SR] - - andh r4, (MODE_MASK >> 16), COH - brne fault_resume_kernel - - get_thread_info r0 - ld.w r1, r0[TI_flags] - andl r1, _TIF_WORK_MASK, COH - brne fault_exit_work - -fault_resume_user: - popm r8-r9 - mask_exceptions - mtsr SYSREG_RAR_EX, r8 - mtsr SYSREG_RSR_EX, r9 - ldmts sp++, r0-lr - sub sp, -4 - rete - -fault_resume_kernel: -#ifdef CONFIG_PREEMPT - get_thread_info r0 - ld.w r2, r0[TI_preempt_count] - cp.w r2, 0 - brne 1f - ld.w r1, r0[TI_flags] - bld r1, TIF_NEED_RESCHED - brcc 1f - lddsp r4, sp[REG_SR] - bld r4, SYSREG_GM_OFFSET - brcs 1f - call preempt_schedule_irq -1: -#endif - - popm r8-r9 - mask_exceptions - mfsr r1, SYSREG_SR - mtsr SYSREG_RAR_EX, r8 - mtsr SYSREG_RSR_EX, r9 - popm lr - sub sp, -4 /* ignore SP */ - popm r0-r12 - sub sp, -4 /* ignore r12_orig */ - rete - -irq_exit_work: - /* Switch to exception mode so that we can share the same code. */ - mfsr r8, SYSREG_SR - cbr r8, SYSREG_M0_OFFSET - orh r8, hi(SYSREG_BIT(M1) | SYSREG_BIT(M2)) - mtsr SYSREG_SR, r8 - sub pc, -2 - get_thread_info r0 - ld.w r1, r0[TI_flags] - -fault_exit_work: - bld r1, TIF_NEED_RESCHED - brcc 1f - unmask_interrupts - call schedule - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp fault_exit_work - -1: mov r2, _TIF_SIGPENDING | _TIF_NOTIFY_RESUME - tst r1, r2 - breq 2f - unmask_interrupts - mov r12, sp - mov r11, r0 - call do_notify_resume - mask_interrupts - ld.w r1, r0[TI_flags] - rjmp fault_exit_work - -2: bld r1, TIF_BREAKPOINT - brcc fault_resume_user - rjmp enter_monitor_mode - - .section .kprobes.text, "ax", @progbits - .type handle_debug, @function -handle_debug: - sub sp, 4 /* r12_orig */ - stmts --sp, r0-lr - mfsr r8, SYSREG_RAR_DBG - mfsr r9, SYSREG_RSR_DBG - unmask_exceptions - pushm r8-r9 - bfextu r9, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - brne debug_fixup_regs - -.Ldebug_fixup_cont: -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_off -#endif - mov r12, sp - call do_debug - mov sp, r12 - - lddsp r2, sp[REG_SR] - bfextu r3, r2, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - brne debug_resume_kernel - - get_thread_info r0 - ld.w r1, r0[TI_flags] - mov r2, _TIF_DBGWORK_MASK - tst r1, r2 - brne debug_exit_work - - bld r1, TIF_SINGLE_STEP - brcc 1f - mfdr r4, OCD_DC - sbr r4, OCD_DC_SS_BIT - mtdr OCD_DC, r4 - -1: popm r10,r11 - mask_exceptions - mtsr SYSREG_RSR_DBG, r11 - mtsr SYSREG_RAR_DBG, r10 -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_on -1: -#endif - ldmts sp++, r0-lr - sub sp, -4 - retd - .size handle_debug, . - handle_debug - - /* Mode of the trapped context is in r9 */ - .type debug_fixup_regs, @function -debug_fixup_regs: - mfsr r8, SYSREG_SR - mov r10, r8 - bfins r8, r9, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - mtsr SYSREG_SR, r8 - sub pc, -2 - stdsp sp[REG_LR], lr - mtsr SYSREG_SR, r10 - sub pc, -2 - sub r8, sp, -FRAME_SIZE_FULL - stdsp sp[REG_SP], r8 - rjmp .Ldebug_fixup_cont - .size debug_fixup_regs, . - debug_fixup_regs - - .type debug_resume_kernel, @function -debug_resume_kernel: - mask_exceptions - popm r10, r11 - mtsr SYSREG_RAR_DBG, r10 - mtsr SYSREG_RSR_DBG, r11 -#ifdef CONFIG_TRACE_IRQFLAGS - bld r11, SYSREG_GM_OFFSET - brcc 1f - call trace_hardirqs_on -1: -#endif - mfsr r2, SYSREG_SR - mov r1, r2 - bfins r2, r3, SYSREG_MODE_OFFSET, SYSREG_MODE_SIZE - mtsr SYSREG_SR, r2 - sub pc, -2 - popm lr - mtsr SYSREG_SR, r1 - sub pc, -2 - sub sp, -4 /* skip SP */ - popm r0-r12 - sub sp, -4 - retd - .size debug_resume_kernel, . - debug_resume_kernel - - .type debug_exit_work, @function -debug_exit_work: - /* - * We must return from Monitor Mode using a retd, and we must - * not schedule since that involves the D bit in SR getting - * cleared by something other than the debug hardware. This - * may cause undefined behaviour according to the Architecture - * manual. - * - * So we fix up the return address and status and return to a - * stub below in Exception mode. From there, we can follow the - * normal exception return path. - * - * The real return address and status registers are stored on - * the stack in the way the exception return path understands, - * so no need to fix anything up there. - */ - sub r8, pc, . - fault_exit_work - mtsr SYSREG_RAR_DBG, r8 - mov r9, 0 - orh r9, hi(SR_EM | SR_GM | MODE_EXCEPTION) - mtsr SYSREG_RSR_DBG, r9 - sub pc, -2 - retd - .size debug_exit_work, . - debug_exit_work - - .set rsr_int0, SYSREG_RSR_INT0 - .set rsr_int1, SYSREG_RSR_INT1 - .set rsr_int2, SYSREG_RSR_INT2 - .set rsr_int3, SYSREG_RSR_INT3 - .set rar_int0, SYSREG_RAR_INT0 - .set rar_int1, SYSREG_RAR_INT1 - .set rar_int2, SYSREG_RAR_INT2 - .set rar_int3, SYSREG_RAR_INT3 - - .macro IRQ_LEVEL level - .type irq_level\level, @function -irq_level\level: - sub sp, 4 /* r12_orig */ - stmts --sp,r0-lr - mfsr r8, rar_int\level - mfsr r9, rsr_int\level - -#ifdef CONFIG_PREEMPT - sub r11, pc, (. - system_call) - cp.w r11, r8 - breq 4f -#endif - - pushm r8-r9 - - mov r11, sp - mov r12, \level - - call do_IRQ - - lddsp r4, sp[REG_SR] - bfextu r4, r4, SYSREG_M0_OFFSET, 3 - cp.w r4, MODE_SUPERVISOR >> SYSREG_M0_OFFSET - breq 2f - cp.w r4, MODE_USER >> SYSREG_M0_OFFSET -#ifdef CONFIG_PREEMPT - brne 3f -#else - brne 1f -#endif - - get_thread_info r0 - ld.w r1, r0[TI_flags] - andl r1, _TIF_WORK_MASK, COH - brne irq_exit_work - -1: -#ifdef CONFIG_TRACE_IRQFLAGS - call trace_hardirqs_on -#endif - popm r8-r9 - mtsr rar_int\level, r8 - mtsr rsr_int\level, r9 - ldmts sp++,r0-lr - sub sp, -4 /* ignore r12_orig */ - rete - -#ifdef CONFIG_PREEMPT -4: mask_interrupts - mfsr r8, rsr_int\level - sbr r8, 16 - mtsr rsr_int\level, r8 - ldmts sp++, r0-lr - sub sp, -4 /* ignore r12_orig */ - rete -#endif - -2: get_thread_info r0 - ld.w r1, r0[TI_flags] - bld r1, TIF_CPU_GOING_TO_SLEEP -#ifdef CONFIG_PREEMPT - brcc 3f -#else - brcc 1b -#endif - sub r1, pc, . - cpu_idle_skip_sleep - stdsp sp[REG_PC], r1 -#ifdef CONFIG_PREEMPT -3: get_thread_info r0 - ld.w r2, r0[TI_preempt_count] - cp.w r2, 0 - brne 1b - ld.w r1, r0[TI_flags] - bld r1, TIF_NEED_RESCHED - brcc 1b - lddsp r4, sp[REG_SR] - bld r4, SYSREG_GM_OFFSET - brcs 1b - call preempt_schedule_irq -#endif - rjmp 1b - .endm - - .section .irq.text,"ax",@progbits - - .global irq_level0 - .global irq_level1 - .global irq_level2 - .global irq_level3 - IRQ_LEVEL 0 - IRQ_LEVEL 1 - IRQ_LEVEL 2 - IRQ_LEVEL 3 - - .section .kprobes.text, "ax", @progbits - .type enter_monitor_mode, @function -enter_monitor_mode: - /* - * We need to enter monitor mode to do a single step. The - * monitor code will alter the return address so that we - * return directly to the user instead of returning here. - */ - breakpoint - rjmp breakpoint_failed - - .size enter_monitor_mode, . - enter_monitor_mode - - .type debug_trampoline, @function - .global debug_trampoline -debug_trampoline: - /* - * Save the registers on the stack so that the monitor code - * can find them easily. - */ - sub sp, 4 /* r12_orig */ - stmts --sp, r0-lr - get_thread_info r0 - ld.w r8, r0[TI_rar_saved] - ld.w r9, r0[TI_rsr_saved] - pushm r8-r9 - - /* - * The monitor code will alter the return address so we don't - * return here. - */ - breakpoint - rjmp breakpoint_failed - .size debug_trampoline, . - debug_trampoline - - .type breakpoint_failed, @function -breakpoint_failed: - /* - * Something went wrong. Perhaps the debug hardware isn't - * enabled? - */ - lda.w r12, msg_breakpoint_failed - mov r11, sp - mov r10, 9 /* SIGKILL */ - call die -1: rjmp 1b - -msg_breakpoint_failed: - .asciz "Failed to enter Debug Mode" diff --git a/arch/avr32/kernel/head.S b/arch/avr32/kernel/head.S deleted file mode 100644 index 59eae6dfbed2..000000000000 --- a/arch/avr32/kernel/head.S +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Non-board-specific low-level startup code - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/linkage.h> - -#include <asm/page.h> - - .section .init.text,"ax" - .global kernel_entry -kernel_entry: - /* Start the show */ - lddpc pc, kernel_start_addr - - .align 2 -kernel_start_addr: - .long start_kernel diff --git a/arch/avr32/kernel/irq.c b/arch/avr32/kernel/irq.c deleted file mode 100644 index 900e49b2258b..000000000000 --- a/arch/avr32/kernel/irq.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on arch/i386/kernel/irq.c - * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel_stat.h> -#include <linux/proc_fs.h> -#include <linux/seq_file.h> -#include <linux/device.h> - -/* May be overridden by platform code */ -int __weak nmi_enable(void) -{ - return -ENOSYS; -} - -void __weak nmi_disable(void) -{ - -} diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c deleted file mode 100644 index a94ece4a72c8..000000000000 --- a/arch/avr32/kernel/kprobes.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Kernel Probes (KProbes) - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * Based on arch/ppc64/kernel/kprobes.c - * Copyright (C) IBM Corporation, 2002, 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/kprobes.h> -#include <linux/ptrace.h> - -#include <asm/cacheflush.h> -#include <linux/kdebug.h> -#include <asm/ocd.h> - -DEFINE_PER_CPU(struct kprobe *, current_kprobe); -static unsigned long kprobe_status; -static struct pt_regs jprobe_saved_regs; - -struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}}; - -int __kprobes arch_prepare_kprobe(struct kprobe *p) -{ - int ret = 0; - - if ((unsigned long)p->addr & 0x01) { - printk("Attempt to register kprobe at an unaligned address\n"); - ret = -EINVAL; - } - - /* XXX: Might be a good idea to check if p->addr is a valid - * kernel address as well... */ - - if (!ret) { - pr_debug("copy kprobe at %p\n", p->addr); - memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); - p->opcode = *p->addr; - } - - return ret; -} - -void __kprobes arch_arm_kprobe(struct kprobe *p) -{ - pr_debug("arming kprobe at %p\n", p->addr); - ocd_enable(NULL); - *p->addr = BREAKPOINT_INSTRUCTION; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -void __kprobes arch_disarm_kprobe(struct kprobe *p) -{ - pr_debug("disarming kprobe at %p\n", p->addr); - ocd_disable(NULL); - *p->addr = p->opcode; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) -{ - unsigned long dc; - - pr_debug("preparing to singlestep over %p (PC=%08lx)\n", - p->addr, regs->pc); - - BUG_ON(!(sysreg_read(SR) & SYSREG_BIT(SR_D))); - - dc = ocd_read(DC); - dc |= 1 << OCD_DC_SS_BIT; - ocd_write(DC, dc); - - /* - * We must run the instruction from its original location - * since it may actually reference PC. - * - * TODO: Do the instruction replacement directly in icache. - */ - *p->addr = p->opcode; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) -{ - unsigned long dc; - - pr_debug("resuming execution at PC=%08lx\n", regs->pc); - - dc = ocd_read(DC); - dc &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, dc); - - *p->addr = BREAKPOINT_INSTRUCTION; - flush_icache_range((unsigned long)p->addr, - (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -} - -static void __kprobes set_current_kprobe(struct kprobe *p) -{ - __this_cpu_write(current_kprobe, p); -} - -static int __kprobes kprobe_handler(struct pt_regs *regs) -{ - struct kprobe *p; - void *addr = (void *)regs->pc; - int ret = 0; - - pr_debug("kprobe_handler: kprobe_running=%p\n", - kprobe_running()); - - /* - * We don't want to be preempted for the entire - * duration of kprobe processing - */ - preempt_disable(); - - /* Check that we're not recursing */ - if (kprobe_running()) { - p = get_kprobe(addr); - if (p) { - if (kprobe_status == KPROBE_HIT_SS) { - printk("FIXME: kprobe hit while single-stepping!\n"); - goto no_kprobe; - } - - printk("FIXME: kprobe hit while handling another kprobe\n"); - goto no_kprobe; - } else { - p = kprobe_running(); - if (p->break_handler && p->break_handler(p, regs)) - goto ss_probe; - } - /* If it's not ours, can't be delete race, (we hold lock). */ - goto no_kprobe; - } - - p = get_kprobe(addr); - if (!p) - goto no_kprobe; - - kprobe_status = KPROBE_HIT_ACTIVE; - set_current_kprobe(p); - if (p->pre_handler && p->pre_handler(p, regs)) - /* handler has already set things up, so skip ss setup */ - return 1; - -ss_probe: - prepare_singlestep(p, regs); - kprobe_status = KPROBE_HIT_SS; - return 1; - -no_kprobe: - preempt_enable_no_resched(); - return ret; -} - -static int __kprobes post_kprobe_handler(struct pt_regs *regs) -{ - struct kprobe *cur = kprobe_running(); - - pr_debug("post_kprobe_handler, cur=%p\n", cur); - - if (!cur) - return 0; - - if (cur->post_handler) { - kprobe_status = KPROBE_HIT_SSDONE; - cur->post_handler(cur, regs, 0); - } - - resume_execution(cur, regs); - reset_current_kprobe(); - preempt_enable_no_resched(); - - return 1; -} - -int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) -{ - struct kprobe *cur = kprobe_running(); - - pr_debug("kprobe_fault_handler: trapnr=%d\n", trapnr); - - if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) - return 1; - - if (kprobe_status & KPROBE_HIT_SS) { - resume_execution(cur, regs); - preempt_enable_no_resched(); - } - return 0; -} - -/* - * Wrapper routine to for handling exceptions. - */ -int __kprobes kprobe_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = (struct die_args *)data; - int ret = NOTIFY_DONE; - - pr_debug("kprobe_exceptions_notify: val=%lu, data=%p\n", - val, data); - - switch (val) { - case DIE_BREAKPOINT: - if (kprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - case DIE_SSTEP: - if (post_kprobe_handler(args->regs)) - ret = NOTIFY_STOP; - break; - default: - break; - } - - return ret; -} - -int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) -{ - struct jprobe *jp = container_of(p, struct jprobe, kp); - - memcpy(&jprobe_saved_regs, regs, sizeof(struct pt_regs)); - - /* - * TODO: We should probably save some of the stack here as - * well, since gcc may pass arguments on the stack for certain - * functions (lots of arguments, large aggregates, varargs) - */ - - /* setup return addr to the jprobe handler routine */ - regs->pc = (unsigned long)jp->entry; - return 1; -} - -void __kprobes jprobe_return(void) -{ - asm volatile("breakpoint" ::: "memory"); -} - -int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) -{ - /* - * FIXME - we should ideally be validating that we got here 'cos - * of the "trap" in jprobe_return() above, before restoring the - * saved regs... - */ - memcpy(regs, &jprobe_saved_regs, sizeof(struct pt_regs)); - return 1; -} - -int __init arch_init_kprobes(void) -{ - /* TODO: Register kretprobe trampoline */ - return 0; -} diff --git a/arch/avr32/kernel/module.c b/arch/avr32/kernel/module.c deleted file mode 100644 index 2b4c54c04cb6..000000000000 --- a/arch/avr32/kernel/module.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - * AVR32-specific kernel module loader - * - * Copyright (C) 2005-2006 Atmel Corporation - * - * GOT initialization parts are based on the s390 version - * Copyright (C) 2002, 2003 IBM Deutschland Entwicklung GmbH, - * IBM Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/bug.h> -#include <linux/elf.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleloader.h> -#include <linux/vmalloc.h> - -void module_arch_freeing_init(struct module *mod) -{ - vfree(mod->arch.syminfo); - mod->arch.syminfo = NULL; -} - -static inline int check_rela(Elf32_Rela *rela, struct module *module, - char *strings, Elf32_Sym *symbols) -{ - struct mod_arch_syminfo *info; - - info = module->arch.syminfo + ELF32_R_SYM(rela->r_info); - switch (ELF32_R_TYPE(rela->r_info)) { - case R_AVR32_GOT32: - case R_AVR32_GOT16: - case R_AVR32_GOT8: - case R_AVR32_GOT21S: - case R_AVR32_GOT18SW: /* mcall */ - case R_AVR32_GOT16S: /* ld.w */ - if (rela->r_addend != 0) { - printk(KERN_ERR - "GOT relocation against %s at offset %u with addend\n", - strings + symbols[ELF32_R_SYM(rela->r_info)].st_name, - rela->r_offset); - return -ENOEXEC; - } - if (info->got_offset == -1UL) { - info->got_offset = module->arch.got_size; - module->arch.got_size += sizeof(void *); - } - pr_debug("GOT[%3lu] %s\n", info->got_offset, - strings + symbols[ELF32_R_SYM(rela->r_info)].st_name); - break; - } - - return 0; -} - -int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *module) -{ - Elf32_Shdr *symtab; - Elf32_Sym *symbols; - Elf32_Rela *rela; - char *strings; - int nrela, i, j; - int ret; - - /* Find the symbol table */ - symtab = NULL; - for (i = 0; i < hdr->e_shnum; i++) - switch (sechdrs[i].sh_type) { - case SHT_SYMTAB: - symtab = &sechdrs[i]; - break; - } - if (!symtab) { - printk(KERN_ERR "module %s: no symbol table\n", module->name); - return -ENOEXEC; - } - - /* Allocate room for one syminfo structure per symbol. */ - module->arch.nsyms = symtab->sh_size / sizeof(Elf_Sym); - module->arch.syminfo = vmalloc(module->arch.nsyms - * sizeof(struct mod_arch_syminfo)); - if (!module->arch.syminfo) - return -ENOMEM; - - symbols = (void *)hdr + symtab->sh_offset; - strings = (void *)hdr + sechdrs[symtab->sh_link].sh_offset; - for (i = 0; i < module->arch.nsyms; i++) { - if (symbols[i].st_shndx == SHN_UNDEF && - strcmp(strings + symbols[i].st_name, - "_GLOBAL_OFFSET_TABLE_") == 0) - /* "Define" it as absolute. */ - symbols[i].st_shndx = SHN_ABS; - module->arch.syminfo[i].got_offset = -1UL; - module->arch.syminfo[i].got_initialized = 0; - } - - /* Allocate GOT entries for symbols that need it. */ - module->arch.got_size = 0; - for (i = 0; i < hdr->e_shnum; i++) { - if (sechdrs[i].sh_type != SHT_RELA) - continue; - nrela = sechdrs[i].sh_size / sizeof(Elf32_Rela); - rela = (void *)hdr + sechdrs[i].sh_offset; - for (j = 0; j < nrela; j++) { - ret = check_rela(rela + j, module, - strings, symbols); - if (ret) - goto out_free_syminfo; - } - } - - /* - * Increase core size to make room for GOT and set start - * offset for GOT. - */ - module->core_layout.size = ALIGN(module->core_layout.size, 4); - module->arch.got_offset = module->core_layout.size; - module->core_layout.size += module->arch.got_size; - - return 0; - -out_free_syminfo: - vfree(module->arch.syminfo); - module->arch.syminfo = NULL; - - return ret; -} - -static inline int reloc_overflow(struct module *module, const char *reloc_name, - Elf32_Addr relocation) -{ - printk(KERN_ERR "module %s: Value %lx does not fit relocation %s\n", - module->name, (unsigned long)relocation, reloc_name); - return -ENOEXEC; -} - -#define get_u16(loc) (*((uint16_t *)loc)) -#define put_u16(loc, val) (*((uint16_t *)loc) = (val)) - -int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, - unsigned int symindex, unsigned int relindex, - struct module *module) -{ - Elf32_Shdr *symsec = sechdrs + symindex; - Elf32_Shdr *relsec = sechdrs + relindex; - Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; - Elf32_Rela *rel = (void *)relsec->sh_addr; - unsigned int i; - int ret = 0; - - for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) { - struct mod_arch_syminfo *info; - Elf32_Sym *sym; - Elf32_Addr relocation; - uint32_t *location; - uint32_t value; - - location = (void *)dstsec->sh_addr + rel->r_offset; - sym = (Elf32_Sym *)symsec->sh_addr + ELF32_R_SYM(rel->r_info); - relocation = sym->st_value + rel->r_addend; - - info = module->arch.syminfo + ELF32_R_SYM(rel->r_info); - - /* Initialize GOT entry if necessary */ - switch (ELF32_R_TYPE(rel->r_info)) { - case R_AVR32_GOT32: - case R_AVR32_GOT16: - case R_AVR32_GOT8: - case R_AVR32_GOT21S: - case R_AVR32_GOT18SW: - case R_AVR32_GOT16S: - if (!info->got_initialized) { - Elf32_Addr *gotent; - - gotent = (module->core_layout.base - + module->arch.got_offset - + info->got_offset); - *gotent = relocation; - info->got_initialized = 1; - } - - relocation = info->got_offset; - break; - } - - switch (ELF32_R_TYPE(rel->r_info)) { - case R_AVR32_32: - case R_AVR32_32_CPENT: - *location = relocation; - break; - case R_AVR32_22H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xffe00001) != 0 - && (relocation & 0xffc00001) != 0xffc00000) - return reloc_overflow(module, - "R_AVR32_22H_PCREL", - relocation); - relocation >>= 1; - - value = *location; - value = ((value & 0xe1ef0000) - | (relocation & 0xffff) - | ((relocation & 0x10000) << 4) - | ((relocation & 0x1e0000) << 8)); - *location = value; - break; - case R_AVR32_11H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xfffffc01) != 0 - && (relocation & 0xfffff801) != 0xfffff800) - return reloc_overflow(module, - "R_AVR32_11H_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf00c) - | ((relocation & 0x1fe) << 3) - | ((relocation & 0x600) >> 9)); - put_u16(location, value); - break; - case R_AVR32_9H_PCREL: - relocation -= (Elf32_Addr)location; - if ((relocation & 0xffffff01) != 0 - && (relocation & 0xfffffe01) != 0xfffffe00) - return reloc_overflow(module, - "R_AVR32_9H_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf00f) - | ((relocation & 0x1fe) << 3)); - put_u16(location, value); - break; - case R_AVR32_9UW_PCREL: - relocation -= ((Elf32_Addr)location) & 0xfffffffc; - if ((relocation & 0xfffffc03) != 0) - return reloc_overflow(module, - "R_AVR32_9UW_PCREL", - relocation); - value = get_u16(location); - value = ((value & 0xf80f) - | ((relocation & 0x1fc) << 2)); - put_u16(location, value); - break; - case R_AVR32_GOTPC: - /* - * R6 = PC - (PC - GOT) - * - * At this point, relocation contains the - * value of PC. Just subtract the value of - * GOT, and we're done. - */ - pr_debug("GOTPC: PC=0x%x, got_offset=0x%lx, core=0x%p\n", - relocation, module->arch.got_offset, - module->core_layout.base); - relocation -= ((unsigned long)module->core_layout.base - + module->arch.got_offset); - *location = relocation; - break; - case R_AVR32_GOT18SW: - if ((relocation & 0xfffe0003) != 0 - && (relocation & 0xfffc0000) != 0xfffc0000) - return reloc_overflow(module, "R_AVR32_GOT18SW", - relocation); - relocation >>= 2; - /* fall through */ - case R_AVR32_GOT16S: - if ((relocation & 0xffff8000) != 0 - && (relocation & 0xffff0000) != 0xffff0000) - return reloc_overflow(module, "R_AVR32_GOT16S", - relocation); - pr_debug("GOT reloc @ 0x%x -> %u\n", - rel->r_offset, relocation); - value = *location; - value = ((value & 0xffff0000) - | (relocation & 0xffff)); - *location = value; - break; - - default: - printk(KERN_ERR "module %s: Unknown relocation: %u\n", - module->name, ELF32_R_TYPE(rel->r_info)); - return -ENOEXEC; - } - } - - return ret; -} diff --git a/arch/avr32/kernel/nmi_debug.c b/arch/avr32/kernel/nmi_debug.c deleted file mode 100644 index 25823049bb99..000000000000 --- a/arch/avr32/kernel/nmi_debug.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/delay.h> -#include <linux/kdebug.h> -#include <linux/notifier.h> -#include <linux/sched.h> -#include <linux/sched/debug.h> - -#include <asm/irq.h> - -enum nmi_action { - NMI_SHOW_STATE = 1 << 0, - NMI_SHOW_REGS = 1 << 1, - NMI_DIE = 1 << 2, - NMI_DEBOUNCE = 1 << 3, -}; - -static unsigned long nmi_actions; - -static int nmi_debug_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = data; - - if (likely(val != DIE_NMI)) - return NOTIFY_DONE; - - if (nmi_actions & NMI_SHOW_STATE) - show_state(); - if (nmi_actions & NMI_SHOW_REGS) - show_regs(args->regs); - if (nmi_actions & NMI_DEBOUNCE) - mdelay(10); - if (nmi_actions & NMI_DIE) - return NOTIFY_BAD; - - return NOTIFY_OK; -} - -static struct notifier_block nmi_debug_nb = { - .notifier_call = nmi_debug_notify, -}; - -static int __init nmi_debug_setup(char *str) -{ - char *p, *sep; - - register_die_notifier(&nmi_debug_nb); - if (nmi_enable()) { - printk(KERN_WARNING "Unable to enable NMI.\n"); - return 0; - } - - if (*str != '=') - return 0; - - for (p = str + 1; *p; p = sep + 1) { - sep = strchr(p, ','); - if (sep) - *sep = 0; - if (strcmp(p, "state") == 0) - nmi_actions |= NMI_SHOW_STATE; - else if (strcmp(p, "regs") == 0) - nmi_actions |= NMI_SHOW_REGS; - else if (strcmp(p, "debounce") == 0) - nmi_actions |= NMI_DEBOUNCE; - else if (strcmp(p, "die") == 0) - nmi_actions |= NMI_DIE; - else - printk(KERN_WARNING "NMI: Unrecognized action `%s'\n", - p); - if (!sep) - break; - } - - return 0; -} -__setup("nmi_debug", nmi_debug_setup); diff --git a/arch/avr32/kernel/ocd.c b/arch/avr32/kernel/ocd.c deleted file mode 100644 index 1b0245d4e0ca..000000000000 --- a/arch/avr32/kernel/ocd.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/spinlock.h> - -#include <asm/ocd.h> - -static long ocd_count; -static spinlock_t ocd_lock; - -/** - * ocd_enable - enable on-chip debugging - * @child: task to be debugged - * - * If @child is non-NULL, ocd_enable() first checks if debugging has - * already been enabled for @child, and if it has, does nothing. - * - * If @child is NULL (e.g. when debugging the kernel), or debugging - * has not already been enabled for it, ocd_enable() increments the - * reference count and enables the debugging hardware. - */ -void ocd_enable(struct task_struct *child) -{ - u32 dc; - - if (child) - pr_debug("ocd_enable: child=%s [%u]\n", - child->comm, child->pid); - else - pr_debug("ocd_enable (no child)\n"); - - if (!child || !test_and_set_tsk_thread_flag(child, TIF_DEBUG)) { - spin_lock(&ocd_lock); - ocd_count++; - dc = ocd_read(DC); - dc |= (1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT); - ocd_write(DC, dc); - spin_unlock(&ocd_lock); - } -} - -/** - * ocd_disable - disable on-chip debugging - * @child: task that was being debugged, but isn't anymore - * - * If @child is non-NULL, ocd_disable() checks if debugging is enabled - * for @child, and if it isn't, does nothing. - * - * If @child is NULL (e.g. when debugging the kernel), or debugging is - * enabled, ocd_disable() decrements the reference count, and if it - * reaches zero, disables the debugging hardware. - */ -void ocd_disable(struct task_struct *child) -{ - u32 dc; - - if (!child) - pr_debug("ocd_disable (no child)\n"); - else if (test_tsk_thread_flag(child, TIF_DEBUG)) - pr_debug("ocd_disable: child=%s [%u]\n", - child->comm, child->pid); - - if (!child || test_and_clear_tsk_thread_flag(child, TIF_DEBUG)) { - spin_lock(&ocd_lock); - ocd_count--; - - WARN_ON(ocd_count < 0); - - if (ocd_count <= 0) { - dc = ocd_read(DC); - dc &= ~((1 << OCD_DC_MM_BIT) | (1 << OCD_DC_DBE_BIT)); - ocd_write(DC, dc); - } - spin_unlock(&ocd_lock); - } -} - -#ifdef CONFIG_DEBUG_FS -#include <linux/debugfs.h> -#include <linux/module.h> - -static struct dentry *ocd_debugfs_root; -static struct dentry *ocd_debugfs_DC; -static struct dentry *ocd_debugfs_DS; -static struct dentry *ocd_debugfs_count; - -static int ocd_DC_get(void *data, u64 *val) -{ - *val = ocd_read(DC); - return 0; -} -static int ocd_DC_set(void *data, u64 val) -{ - ocd_write(DC, val); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_DC, ocd_DC_get, ocd_DC_set, "0x%08llx\n"); - -static int ocd_DS_get(void *data, u64 *val) -{ - *val = ocd_read(DS); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_DS, ocd_DS_get, NULL, "0x%08llx\n"); - -static int ocd_count_get(void *data, u64 *val) -{ - *val = ocd_count; - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(fops_count, ocd_count_get, NULL, "%lld\n"); - -static void ocd_debugfs_init(void) -{ - struct dentry *root; - - root = debugfs_create_dir("ocd", NULL); - if (IS_ERR(root) || !root) - goto err_root; - ocd_debugfs_root = root; - - ocd_debugfs_DC = debugfs_create_file("DC", S_IRUSR | S_IWUSR, - root, NULL, &fops_DC); - if (!ocd_debugfs_DC) - goto err_DC; - - ocd_debugfs_DS = debugfs_create_file("DS", S_IRUSR, root, - NULL, &fops_DS); - if (!ocd_debugfs_DS) - goto err_DS; - - ocd_debugfs_count = debugfs_create_file("count", S_IRUSR, root, - NULL, &fops_count); - if (!ocd_debugfs_count) - goto err_count; - - return; - -err_count: - debugfs_remove(ocd_debugfs_DS); -err_DS: - debugfs_remove(ocd_debugfs_DC); -err_DC: - debugfs_remove(ocd_debugfs_root); -err_root: - printk(KERN_WARNING "OCD: Failed to create debugfs entries\n"); -} -#else -static inline void ocd_debugfs_init(void) -{ - -} -#endif - -static int __init ocd_init(void) -{ - spin_lock_init(&ocd_lock); - ocd_debugfs_init(); - return 0; -} -arch_initcall(ocd_init); diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c deleted file mode 100644 index ad0dfccedb79..000000000000 --- a/arch/avr32/kernel/process.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/sched.h> -#include <linux/sched/debug.h> -#include <linux/sched/task.h> -#include <linux/sched/task_stack.h> -#include <linux/module.h> -#include <linux/kallsyms.h> -#include <linux/fs.h> -#include <linux/pm.h> -#include <linux/ptrace.h> -#include <linux/slab.h> -#include <linux/reboot.h> -#include <linux/tick.h> -#include <linux/uaccess.h> -#include <linux/unistd.h> - -#include <asm/sysreg.h> -#include <asm/ocd.h> -#include <asm/syscalls.h> - -#include <mach/pm.h> - -void (*pm_power_off)(void); -EXPORT_SYMBOL(pm_power_off); - -/* - * This file handles the architecture-dependent parts of process handling.. - */ - -void arch_cpu_idle(void) -{ - cpu_enter_idle(); -} - -void machine_halt(void) -{ - /* - * Enter Stop mode. The 32 kHz oscillator will keep running so - * the RTC will keep the time properly and the system will - * boot quickly. - */ - asm volatile("sleep 3\n\t" - "sub pc, -2"); -} - -void machine_power_off(void) -{ - if (pm_power_off) - pm_power_off(); -} - -void machine_restart(char *cmd) -{ - ocd_write(DC, (1 << OCD_DC_DBE_BIT)); - ocd_write(DC, (1 << OCD_DC_RES_BIT)); - while (1) ; -} - -/* - * Free current thread data structures etc - */ -void exit_thread(struct task_struct *tsk) -{ - ocd_disable(tsk); -} - -void flush_thread(void) -{ - /* nothing to do */ -} - -void release_thread(struct task_struct *dead_task) -{ - /* do nothing */ -} - -static void dump_mem(const char *str, const char *log_lvl, - unsigned long bottom, unsigned long top) -{ - unsigned long p; - int i; - - printk("%s%s(0x%08lx to 0x%08lx)\n", log_lvl, str, bottom, top); - - for (p = bottom & ~31; p < top; ) { - printk("%s%04lx: ", log_lvl, p & 0xffff); - - for (i = 0; i < 8; i++, p += 4) { - unsigned int val; - - if (p < bottom || p >= top) - printk(" "); - else { - if (__get_user(val, (unsigned int __user *)p)) { - printk("\n"); - goto out; - } - printk("%08x ", val); - } - } - printk("\n"); - } - -out: - return; -} - -static inline int valid_stack_ptr(struct thread_info *tinfo, unsigned long p) -{ - return (p > (unsigned long)tinfo) - && (p < (unsigned long)tinfo + THREAD_SIZE - 3); -} - -#ifdef CONFIG_FRAME_POINTER -static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs, const char *log_lvl) -{ - unsigned long lr, fp; - struct thread_info *tinfo; - - if (regs) - fp = regs->r7; - else if (tsk == current) - asm("mov %0, r7" : "=r"(fp)); - else - fp = tsk->thread.cpu_context.r7; - - /* - * Walk the stack as long as the frame pointer (a) is within - * the kernel stack of the task, and (b) it doesn't move - * downwards. - */ - tinfo = task_thread_info(tsk); - printk("%sCall trace:\n", log_lvl); - while (valid_stack_ptr(tinfo, fp)) { - unsigned long new_fp; - - lr = *(unsigned long *)fp; -#ifdef CONFIG_KALLSYMS - printk("%s [<%08lx>] ", log_lvl, lr); -#else - printk(" [<%08lx>] ", lr); -#endif - print_symbol("%s\n", lr); - - new_fp = *(unsigned long *)(fp + 4); - if (new_fp <= fp) - break; - fp = new_fp; - } - printk("\n"); -} -#else -static void show_trace_log_lvl(struct task_struct *tsk, unsigned long *sp, - struct pt_regs *regs, const char *log_lvl) -{ - unsigned long addr; - - printk("%sCall trace:\n", log_lvl); - - while (!kstack_end(sp)) { - addr = *sp++; - if (kernel_text_address(addr)) { -#ifdef CONFIG_KALLSYMS - printk("%s [<%08lx>] ", log_lvl, addr); -#else - printk(" [<%08lx>] ", addr); -#endif - print_symbol("%s\n", addr); - } - } - printk("\n"); -} -#endif - -void show_stack_log_lvl(struct task_struct *tsk, unsigned long sp, - struct pt_regs *regs, const char *log_lvl) -{ - struct thread_info *tinfo; - - if (sp == 0) { - if (tsk) - sp = tsk->thread.cpu_context.ksp; - else - sp = (unsigned long)&tinfo; - } - if (!tsk) - tsk = current; - - tinfo = task_thread_info(tsk); - - if (valid_stack_ptr(tinfo, sp)) { - dump_mem("Stack: ", log_lvl, sp, - THREAD_SIZE + (unsigned long)tinfo); - show_trace_log_lvl(tsk, (unsigned long *)sp, regs, log_lvl); - } -} - -void show_stack(struct task_struct *tsk, unsigned long *stack) -{ - show_stack_log_lvl(tsk, (unsigned long)stack, NULL, ""); -} - -static const char *cpu_modes[] = { - "Application", "Supervisor", "Interrupt level 0", "Interrupt level 1", - "Interrupt level 2", "Interrupt level 3", "Exception", "NMI" -}; - -void show_regs_log_lvl(struct pt_regs *regs, const char *log_lvl) -{ - unsigned long sp = regs->sp; - unsigned long lr = regs->lr; - unsigned long mode = (regs->sr & MODE_MASK) >> MODE_SHIFT; - - show_regs_print_info(log_lvl); - - if (!user_mode(regs)) { - sp = (unsigned long)regs + FRAME_SIZE_FULL; - - printk("%s", log_lvl); - print_symbol("PC is at %s\n", instruction_pointer(regs)); - printk("%s", log_lvl); - print_symbol("LR is at %s\n", lr); - } - - printk("%spc : [<%08lx>] lr : [<%08lx>] %s\n" - "%ssp : %08lx r12: %08lx r11: %08lx\n", - log_lvl, instruction_pointer(regs), lr, print_tainted(), - log_lvl, sp, regs->r12, regs->r11); - printk("%sr10: %08lx r9 : %08lx r8 : %08lx\n", - log_lvl, regs->r10, regs->r9, regs->r8); - printk("%sr7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", - log_lvl, regs->r7, regs->r6, regs->r5, regs->r4); - printk("%sr3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", - log_lvl, regs->r3, regs->r2, regs->r1, regs->r0); - printk("%sFlags: %c%c%c%c%c\n", log_lvl, - regs->sr & SR_Q ? 'Q' : 'q', - regs->sr & SR_V ? 'V' : 'v', - regs->sr & SR_N ? 'N' : 'n', - regs->sr & SR_Z ? 'Z' : 'z', - regs->sr & SR_C ? 'C' : 'c'); - printk("%sMode bits: %c%c%c%c%c%c%c%c%c%c\n", log_lvl, - regs->sr & SR_H ? 'H' : 'h', - regs->sr & SR_J ? 'J' : 'j', - regs->sr & SR_DM ? 'M' : 'm', - regs->sr & SR_D ? 'D' : 'd', - regs->sr & SR_EM ? 'E' : 'e', - regs->sr & SR_I3M ? '3' : '.', - regs->sr & SR_I2M ? '2' : '.', - regs->sr & SR_I1M ? '1' : '.', - regs->sr & SR_I0M ? '0' : '.', - regs->sr & SR_GM ? 'G' : 'g'); - printk("%sCPU Mode: %s\n", log_lvl, cpu_modes[mode]); -} - -void show_regs(struct pt_regs *regs) -{ - unsigned long sp = regs->sp; - - if (!user_mode(regs)) - sp = (unsigned long)regs + FRAME_SIZE_FULL; - - show_regs_log_lvl(regs, ""); - show_trace_log_lvl(current, (unsigned long *)sp, regs, ""); -} -EXPORT_SYMBOL(show_regs); - -/* Fill in the fpu structure for a core dump. This is easy -- we don't have any */ -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -{ - /* Not valid */ - return 0; -} - -asmlinkage void ret_from_fork(void); -asmlinkage void ret_from_kernel_thread(void); -asmlinkage void syscall_return(void); - -int copy_thread(unsigned long clone_flags, unsigned long usp, - unsigned long arg, - struct task_struct *p) -{ - struct pt_regs *childregs = task_pt_regs(p); - - if (unlikely(p->flags & PF_KTHREAD)) { - memset(childregs, 0, sizeof(struct pt_regs)); - p->thread.cpu_context.r0 = arg; - p->thread.cpu_context.r1 = usp; /* fn */ - p->thread.cpu_context.r2 = (unsigned long)syscall_return; - p->thread.cpu_context.pc = (unsigned long)ret_from_kernel_thread; - childregs->sr = MODE_SUPERVISOR; - } else { - *childregs = *current_pt_regs(); - if (usp) - childregs->sp = usp; - childregs->r12 = 0; /* Set return value for child */ - p->thread.cpu_context.pc = (unsigned long)ret_from_fork; - } - - p->thread.cpu_context.sr = MODE_SUPERVISOR | SR_GM; - p->thread.cpu_context.ksp = (unsigned long)childregs; - - clear_tsk_thread_flag(p, TIF_DEBUG); - if ((clone_flags & CLONE_PTRACE) && test_thread_flag(TIF_DEBUG)) - ocd_enable(p); - - return 0; -} - -/* - * This function is supposed to answer the question "who called - * schedule()?" - */ -unsigned long get_wchan(struct task_struct *p) -{ - unsigned long pc; - unsigned long stack_page; - - if (!p || p == current || p->state == TASK_RUNNING) - return 0; - - stack_page = (unsigned long)task_stack_page(p); - BUG_ON(!stack_page); - - /* - * The stored value of PC is either the address right after - * the call to __switch_to() or ret_from_fork. - */ - pc = thread_saved_pc(p); - if (in_sched_functions(pc)) { -#ifdef CONFIG_FRAME_POINTER - unsigned long fp = p->thread.cpu_context.r7; - BUG_ON(fp < stack_page || fp > (THREAD_SIZE + stack_page)); - pc = *(unsigned long *)fp; -#else - /* - * We depend on the frame size of schedule here, which - * is actually quite ugly. It might be possible to - * determine the frame size automatically at build - * time by doing this: - * - compile sched/core.c - * - disassemble the resulting sched.o - * - look for 'sub sp,??' shortly after '<schedule>:' - */ - unsigned long sp = p->thread.cpu_context.ksp + 16; - BUG_ON(sp < stack_page || sp > (THREAD_SIZE + stack_page)); - pc = *(unsigned long *)sp; -#endif - } - - return pc; -} diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c deleted file mode 100644 index 41a14e96a1db..000000000000 --- a/arch/avr32/kernel/ptrace.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#undef DEBUG -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/sched/task_stack.h> -#include <linux/mm.h> -#include <linux/ptrace.h> -#include <linux/errno.h> -#include <linux/user.h> -#include <linux/security.h> -#include <linux/unistd.h> -#include <linux/notifier.h> - -#include <asm/traps.h> -#include <linux/uaccess.h> -#include <asm/ocd.h> -#include <asm/mmu_context.h> -#include <linux/kdebug.h> - -static struct pt_regs *get_user_regs(struct task_struct *tsk) -{ - return (struct pt_regs *)((unsigned long)task_stack_page(tsk) + - THREAD_SIZE - sizeof(struct pt_regs)); -} - -void user_enable_single_step(struct task_struct *tsk) -{ - pr_debug("user_enable_single_step: pid=%u, PC=0x%08lx, SR=0x%08lx\n", - tsk->pid, task_pt_regs(tsk)->pc, task_pt_regs(tsk)->sr); - - /* - * We can't schedule in Debug mode, so when TIF_BREAKPOINT is - * set, the system call or exception handler will do a - * breakpoint to enter monitor mode before returning to - * userspace. - * - * The monitor code will then notice that TIF_SINGLE_STEP is - * set and return to userspace with single stepping enabled. - * The CPU will then enter monitor mode again after exactly - * one instruction has been executed, and the monitor code - * will then send a SIGTRAP to the process. - */ - set_tsk_thread_flag(tsk, TIF_BREAKPOINT); - set_tsk_thread_flag(tsk, TIF_SINGLE_STEP); -} - -void user_disable_single_step(struct task_struct *child) -{ - /* XXX(hch): a no-op here seems wrong.. */ -} - -/* - * Called by kernel/ptrace.c when detaching - * - * Make sure any single step bits, etc. are not set - */ -void ptrace_disable(struct task_struct *child) -{ - clear_tsk_thread_flag(child, TIF_SINGLE_STEP); - clear_tsk_thread_flag(child, TIF_BREAKPOINT); - ocd_disable(child); -} - -/* - * Read the word at offset "offset" into the task's "struct user". We - * actually access the pt_regs struct stored on the kernel stack. - */ -static int ptrace_read_user(struct task_struct *tsk, unsigned long offset, - unsigned long __user *data) -{ - unsigned long *regs; - unsigned long value; - - if (offset & 3 || offset >= sizeof(struct user)) { - printk("ptrace_read_user: invalid offset 0x%08lx\n", offset); - return -EIO; - } - - regs = (unsigned long *)get_user_regs(tsk); - - value = 0; - if (offset < sizeof(struct pt_regs)) - value = regs[offset / sizeof(regs[0])]; - - pr_debug("ptrace_read_user(%s[%u], %#lx, %p) -> %#lx\n", - tsk->comm, tsk->pid, offset, data, value); - - return put_user(value, data); -} - -/* - * Write the word "value" to offset "offset" into the task's "struct - * user". We actually access the pt_regs struct stored on the kernel - * stack. - */ -static int ptrace_write_user(struct task_struct *tsk, unsigned long offset, - unsigned long value) -{ - unsigned long *regs; - - pr_debug("ptrace_write_user(%s[%u], %#lx, %#lx)\n", - tsk->comm, tsk->pid, offset, value); - - if (offset & 3 || offset >= sizeof(struct user)) { - pr_debug(" invalid offset 0x%08lx\n", offset); - return -EIO; - } - - if (offset >= sizeof(struct pt_regs)) - return 0; - - regs = (unsigned long *)get_user_regs(tsk); - regs[offset / sizeof(regs[0])] = value; - - return 0; -} - -static int ptrace_getregs(struct task_struct *tsk, void __user *uregs) -{ - struct pt_regs *regs = get_user_regs(tsk); - - return copy_to_user(uregs, regs, sizeof(*regs)) ? -EFAULT : 0; -} - -static int ptrace_setregs(struct task_struct *tsk, const void __user *uregs) -{ - struct pt_regs newregs; - int ret; - - ret = -EFAULT; - if (copy_from_user(&newregs, uregs, sizeof(newregs)) == 0) { - struct pt_regs *regs = get_user_regs(tsk); - - ret = -EINVAL; - if (valid_user_regs(&newregs)) { - *regs = newregs; - ret = 0; - } - } - - return ret; -} - -long arch_ptrace(struct task_struct *child, long request, - unsigned long addr, unsigned long data) -{ - int ret; - void __user *datap = (void __user *) data; - - switch (request) { - /* Read the word at location addr in the child process */ - case PTRACE_PEEKTEXT: - case PTRACE_PEEKDATA: - ret = generic_ptrace_peekdata(child, addr, data); - break; - - case PTRACE_PEEKUSR: - ret = ptrace_read_user(child, addr, datap); - break; - - /* Write the word in data at location addr */ - case PTRACE_POKETEXT: - case PTRACE_POKEDATA: - ret = generic_ptrace_pokedata(child, addr, data); - break; - - case PTRACE_POKEUSR: - ret = ptrace_write_user(child, addr, data); - break; - - case PTRACE_GETREGS: - ret = ptrace_getregs(child, datap); - break; - - case PTRACE_SETREGS: - ret = ptrace_setregs(child, datap); - break; - - default: - ret = ptrace_request(child, request, addr, data); - break; - } - - return ret; -} - -asmlinkage void syscall_trace(void) -{ - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - return; - if (!(current->ptrace & PT_PTRACED)) - return; - - /* The 0x80 provides a way for the tracing parent to - * distinguish between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it - * will do for normal use. strace only continues with a - * signal if the stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - pr_debug("syscall_trace: sending signal %d to PID %u\n", - current->exit_code, current->pid); - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} - -/* - * debug_trampoline() is an assembly stub which will store all user - * registers on the stack and execute a breakpoint instruction. - * - * If we single-step into an exception handler which runs with - * interrupts disabled the whole time so it doesn't have to check for - * pending work, its return address will be modified so that it ends - * up returning to debug_trampoline. - * - * If the exception handler decides to store the user context and - * enable interrupts after all, it will restore the original return - * address and status register value. Before it returns, it will - * notice that TIF_BREAKPOINT is set and execute a breakpoint - * instruction. - */ -extern void debug_trampoline(void); - -asmlinkage struct pt_regs *do_debug(struct pt_regs *regs) -{ - struct thread_info *ti; - unsigned long trampoline_addr; - u32 status; - u32 ctrl; - int code; - - status = ocd_read(DS); - ti = current_thread_info(); - code = TRAP_BRKPT; - - pr_debug("do_debug: status=0x%08x PC=0x%08lx SR=0x%08lx tif=0x%08lx\n", - status, regs->pc, regs->sr, ti->flags); - - if (!user_mode(regs)) { - unsigned long die_val = DIE_BREAKPOINT; - - if (status & (1 << OCD_DS_SSS_BIT)) - die_val = DIE_SSTEP; - - if (notify_die(die_val, "ptrace", regs, 0, 0, SIGTRAP) - == NOTIFY_STOP) - return regs; - - if ((status & (1 << OCD_DS_SWB_BIT)) - && test_and_clear_ti_thread_flag( - ti, TIF_BREAKPOINT)) { - /* - * Explicit breakpoint from trampoline or - * exception/syscall/interrupt handler. - * - * The real saved regs are on the stack right - * after the ones we saved on entry. - */ - regs++; - pr_debug(" -> TIF_BREAKPOINT done, adjusted regs:" - "PC=0x%08lx SR=0x%08lx\n", - regs->pc, regs->sr); - BUG_ON(!user_mode(regs)); - - if (test_thread_flag(TIF_SINGLE_STEP)) { - pr_debug("Going to do single step...\n"); - return regs; - } - - /* - * No TIF_SINGLE_STEP means we're done - * stepping over a syscall. Do the trap now. - */ - code = TRAP_TRACE; - } else if ((status & (1 << OCD_DS_SSS_BIT)) - && test_ti_thread_flag(ti, TIF_SINGLE_STEP)) { - - pr_debug("Stepped into something, " - "setting TIF_BREAKPOINT...\n"); - set_ti_thread_flag(ti, TIF_BREAKPOINT); - - /* - * We stepped into an exception, interrupt or - * syscall handler. Some exception handlers - * don't check for pending work, so we need to - * set up a trampoline just in case. - * - * The exception entry code will undo the - * trampoline stuff if it does a full context - * save (which also means that it'll check for - * pending work later.) - */ - if ((regs->sr & MODE_MASK) == MODE_EXCEPTION) { - trampoline_addr - = (unsigned long)&debug_trampoline; - - pr_debug("Setting up trampoline...\n"); - ti->rar_saved = sysreg_read(RAR_EX); - ti->rsr_saved = sysreg_read(RSR_EX); - sysreg_write(RAR_EX, trampoline_addr); - sysreg_write(RSR_EX, (MODE_EXCEPTION - | SR_EM | SR_GM)); - BUG_ON(ti->rsr_saved & MODE_MASK); - } - - /* - * If we stepped into a system call, we - * shouldn't do a single step after we return - * since the return address is right after the - * "scall" instruction we were told to step - * over. - */ - if ((regs->sr & MODE_MASK) == MODE_SUPERVISOR) { - pr_debug("Supervisor; no single step\n"); - clear_ti_thread_flag(ti, TIF_SINGLE_STEP); - } - - ctrl = ocd_read(DC); - ctrl &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, ctrl); - - return regs; - } else { - printk(KERN_ERR "Unexpected OCD_DS value: 0x%08x\n", - status); - printk(KERN_ERR "Thread flags: 0x%08lx\n", ti->flags); - die("Unhandled debug trap in kernel mode", - regs, SIGTRAP); - } - } else if (status & (1 << OCD_DS_SSS_BIT)) { - /* Single step in user mode */ - code = TRAP_TRACE; - - ctrl = ocd_read(DC); - ctrl &= ~(1 << OCD_DC_SS_BIT); - ocd_write(DC, ctrl); - } - - pr_debug("Sending SIGTRAP: code=%d PC=0x%08lx SR=0x%08lx\n", - code, regs->pc, regs->sr); - - clear_thread_flag(TIF_SINGLE_STEP); - _exception(SIGTRAP, regs, code, instruction_pointer(regs)); - - return regs; -} diff --git a/arch/avr32/kernel/setup.c b/arch/avr32/kernel/setup.c deleted file mode 100644 index e6928896da2a..000000000000 --- a/arch/avr32/kernel/setup.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk.h> -#include <linux/init.h> -#include <linux/initrd.h> -#include <linux/sched.h> -#include <linux/console.h> -#include <linux/ioport.h> -#include <linux/bootmem.h> -#include <linux/fs.h> -#include <linux/module.h> -#include <linux/pfn.h> -#include <linux/root_dev.h> -#include <linux/cpu.h> -#include <linux/kernel.h> - -#include <asm/sections.h> -#include <asm/processor.h> -#include <asm/pgtable.h> -#include <asm/setup.h> -#include <asm/sysreg.h> - -#include <mach/board.h> -#include <mach/init.h> - -extern int root_mountflags; - -/* - * Initialize loops_per_jiffy as 5000000 (500MIPS). - * Better make it too large than too small... - */ -struct avr32_cpuinfo boot_cpu_data = { - .loops_per_jiffy = 5000000 -}; -EXPORT_SYMBOL(boot_cpu_data); - -static char __initdata command_line[COMMAND_LINE_SIZE]; - -/* - * Standard memory resources - */ -static struct resource __initdata kernel_data = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_SYSTEM_RAM, -}; -static struct resource __initdata kernel_code = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_SYSTEM_RAM, - .sibling = &kernel_data, -}; - -/* - * Available system RAM and reserved regions as singly linked - * lists. These lists are traversed using the sibling pointer in - * struct resource and are kept sorted at all times. - */ -static struct resource *__initdata system_ram; -static struct resource *__initdata reserved = &kernel_code; - -/* - * We need to allocate these before the bootmem allocator is up and - * running, so we need this "cache". 32 entries are probably enough - * for all but the most insanely complex systems. - */ -static struct resource __initdata res_cache[32]; -static unsigned int __initdata res_cache_next_free; - -static void __init resource_init(void) -{ - struct resource *mem, *res; - struct resource *new; - - kernel_code.start = __pa(init_mm.start_code); - - for (mem = system_ram; mem; mem = mem->sibling) { - new = alloc_bootmem_low(sizeof(struct resource)); - memcpy(new, mem, sizeof(struct resource)); - - new->sibling = NULL; - if (request_resource(&iomem_resource, new)) - printk(KERN_WARNING "Bad RAM resource %08x-%08x\n", - mem->start, mem->end); - } - - for (res = reserved; res; res = res->sibling) { - new = alloc_bootmem_low(sizeof(struct resource)); - memcpy(new, res, sizeof(struct resource)); - - new->sibling = NULL; - if (insert_resource(&iomem_resource, new)) - printk(KERN_WARNING - "Bad reserved resource %s (%08x-%08x)\n", - res->name, res->start, res->end); - } -} - -static void __init -add_physical_memory(resource_size_t start, resource_size_t end) -{ - struct resource *new, *next, **pprev; - - for (pprev = &system_ram, next = system_ram; next; - pprev = &next->sibling, next = next->sibling) { - if (end < next->start) - break; - if (start <= next->end) { - printk(KERN_WARNING - "Warning: Physical memory map is broken\n"); - printk(KERN_WARNING - "Warning: %08x-%08x overlaps %08x-%08x\n", - start, end, next->start, next->end); - return; - } - } - - if (res_cache_next_free >= ARRAY_SIZE(res_cache)) { - printk(KERN_WARNING - "Warning: Failed to add physical memory %08x-%08x\n", - start, end); - return; - } - - new = &res_cache[res_cache_next_free++]; - new->start = start; - new->end = end; - new->name = "System RAM"; - new->flags = IORESOURCE_SYSTEM_RAM; - - *pprev = new; -} - -static int __init -add_reserved_region(resource_size_t start, resource_size_t end, - const char *name) -{ - struct resource *new, *next, **pprev; - - if (end < start) - return -EINVAL; - - if (res_cache_next_free >= ARRAY_SIZE(res_cache)) - return -ENOMEM; - - for (pprev = &reserved, next = reserved; next; - pprev = &next->sibling, next = next->sibling) { - if (end < next->start) - break; - if (start <= next->end) - return -EBUSY; - } - - new = &res_cache[res_cache_next_free++]; - new->start = start; - new->end = end; - new->name = name; - new->sibling = next; - new->flags = IORESOURCE_MEM; - - *pprev = new; - - return 0; -} - -static unsigned long __init -find_free_region(const struct resource *mem, resource_size_t size, - resource_size_t align) -{ - struct resource *res; - unsigned long target; - - target = ALIGN(mem->start, align); - for (res = reserved; res; res = res->sibling) { - if ((target + size) <= res->start) - break; - if (target <= res->end) - target = ALIGN(res->end + 1, align); - } - - if ((target + size) > (mem->end + 1)) - return mem->end + 1; - - return target; -} - -static int __init -alloc_reserved_region(resource_size_t *start, resource_size_t size, - resource_size_t align, const char *name) -{ - struct resource *mem; - resource_size_t target; - int ret; - - for (mem = system_ram; mem; mem = mem->sibling) { - target = find_free_region(mem, size, align); - if (target <= mem->end) { - ret = add_reserved_region(target, target + size - 1, - name); - if (!ret) - *start = target; - return ret; - } - } - - return -ENOMEM; -} - -/* - * Early framebuffer allocation. Works as follows: - * - If fbmem_size is zero, nothing will be allocated or reserved. - * - If fbmem_start is zero when setup_bootmem() is called, - * a block of fbmem_size bytes will be reserved before bootmem - * initialization. It will be aligned to the largest page size - * that fbmem_size is a multiple of. - * - If fbmem_start is nonzero, an area of size fbmem_size will be - * reserved at the physical address fbmem_start if possible. If - * it collides with other reserved memory, a different block of - * same size will be allocated, just as if fbmem_start was zero. - * - * Board-specific code may use these variables to set up platform data - * for the framebuffer driver if fbmem_size is nonzero. - */ -resource_size_t __initdata fbmem_start; -resource_size_t __initdata fbmem_size; - -/* - * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for - * use as framebuffer. - * - * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and - * starting at yyy to be reserved for use as framebuffer. - * - * The kernel won't verify that the memory region starting at yyy - * actually contains usable RAM. - */ -static int __init early_parse_fbmem(char *p) -{ - int ret; - unsigned long align; - - fbmem_size = memparse(p, &p); - if (*p == '@') { - fbmem_start = memparse(p + 1, &p); - ret = add_reserved_region(fbmem_start, - fbmem_start + fbmem_size - 1, - "Framebuffer"); - if (ret) { - printk(KERN_WARNING - "Failed to reserve framebuffer memory\n"); - fbmem_start = 0; - } - } - - if (!fbmem_start) { - if ((fbmem_size & 0x000fffffUL) == 0) - align = 0x100000; /* 1 MiB */ - else if ((fbmem_size & 0x0000ffffUL) == 0) - align = 0x10000; /* 64 KiB */ - else - align = 0x1000; /* 4 KiB */ - - ret = alloc_reserved_region(&fbmem_start, fbmem_size, - align, "Framebuffer"); - if (ret) { - printk(KERN_WARNING - "Failed to allocate framebuffer memory\n"); - fbmem_size = 0; - } else { - memset(__va(fbmem_start), 0, fbmem_size); - } - } - - return 0; -} -early_param("fbmem", early_parse_fbmem); - -/* - * Pick out the memory size. We look for mem=size@start, - * where start and size are "size[KkMmGg]" - */ -static int __init early_mem(char *p) -{ - resource_size_t size, start; - - start = system_ram->start; - size = memparse(p, &p); - if (*p == '@') - start = memparse(p + 1, &p); - - system_ram->start = start; - system_ram->end = system_ram->start + size - 1; - return 0; -} -early_param("mem", early_mem); - -static int __init parse_tag_core(struct tag *tag) -{ - if (tag->hdr.size > 2) { - if ((tag->u.core.flags & 1) == 0) - root_mountflags &= ~MS_RDONLY; - ROOT_DEV = new_decode_dev(tag->u.core.rootdev); - } - return 0; -} -__tagtable(ATAG_CORE, parse_tag_core); - -static int __init parse_tag_mem(struct tag *tag) -{ - unsigned long start, end; - - /* - * Ignore zero-sized entries. If we're running standalone, the - * SDRAM code may emit such entries if something goes - * wrong... - */ - if (tag->u.mem_range.size == 0) - return 0; - - start = tag->u.mem_range.addr; - end = tag->u.mem_range.addr + tag->u.mem_range.size - 1; - - add_physical_memory(start, end); - return 0; -} -__tagtable(ATAG_MEM, parse_tag_mem); - -static int __init parse_tag_rdimg(struct tag *tag) -{ -#ifdef CONFIG_BLK_DEV_INITRD - struct tag_mem_range *mem = &tag->u.mem_range; - int ret; - - if (initrd_start) { - printk(KERN_WARNING - "Warning: Only the first initrd image will be used\n"); - return 0; - } - - ret = add_reserved_region(mem->addr, mem->addr + mem->size - 1, - "initrd"); - if (ret) { - printk(KERN_WARNING - "Warning: Failed to reserve initrd memory\n"); - return ret; - } - - initrd_start = (unsigned long)__va(mem->addr); - initrd_end = initrd_start + mem->size; -#else - printk(KERN_WARNING "RAM disk image present, but " - "no initrd support in kernel, ignoring\n"); -#endif - - return 0; -} -__tagtable(ATAG_RDIMG, parse_tag_rdimg); - -static int __init parse_tag_rsvd_mem(struct tag *tag) -{ - struct tag_mem_range *mem = &tag->u.mem_range; - - return add_reserved_region(mem->addr, mem->addr + mem->size - 1, - "Reserved"); -} -__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem); - -static int __init parse_tag_cmdline(struct tag *tag) -{ - strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE); - return 0; -} -__tagtable(ATAG_CMDLINE, parse_tag_cmdline); - -static int __init parse_tag_clock(struct tag *tag) -{ - /* - * We'll figure out the clocks by peeking at the system - * manager regs directly. - */ - return 0; -} -__tagtable(ATAG_CLOCK, parse_tag_clock); - -/* - * The board_number correspond to the bd->bi_board_number in U-Boot. This - * parameter is only available during initialisation and can be used in some - * kind of board identification. - */ -u32 __initdata board_number; - -static int __init parse_tag_boardinfo(struct tag *tag) -{ - board_number = tag->u.boardinfo.board_number; - - return 0; -} -__tagtable(ATAG_BOARDINFO, parse_tag_boardinfo); - -/* - * Scan the tag table for this tag, and call its parse function. The - * tag table is built by the linker from all the __tagtable - * declarations. - */ -static int __init parse_tag(struct tag *tag) -{ - extern struct tagtable __tagtable_begin, __tagtable_end; - struct tagtable *t; - - for (t = &__tagtable_begin; t < &__tagtable_end; t++) - if (tag->hdr.tag == t->tag) { - t->parse(tag); - break; - } - - return t < &__tagtable_end; -} - -/* - * Parse all tags in the list we got from the boot loader - */ -static void __init parse_tags(struct tag *t) -{ - for (; t->hdr.tag != ATAG_NONE; t = tag_next(t)) - if (!parse_tag(t)) - printk(KERN_WARNING - "Ignoring unrecognised tag 0x%08x\n", - t->hdr.tag); -} - -/* - * Find a free memory region large enough for storing the - * bootmem bitmap. - */ -static unsigned long __init -find_bootmap_pfn(const struct resource *mem) -{ - unsigned long bootmap_pages, bootmap_len; - unsigned long node_pages = PFN_UP(resource_size(mem)); - unsigned long bootmap_start; - - bootmap_pages = bootmem_bootmap_pages(node_pages); - bootmap_len = bootmap_pages << PAGE_SHIFT; - - /* - * Find a large enough region without reserved pages for - * storing the bootmem bitmap. We can take advantage of the - * fact that all lists have been sorted. - * - * We have to check that we don't collide with any reserved - * regions, which includes the kernel image and any RAMDISK - * images. - */ - bootmap_start = find_free_region(mem, bootmap_len, PAGE_SIZE); - - return bootmap_start >> PAGE_SHIFT; -} - -#define MAX_LOWMEM HIGHMEM_START -#define MAX_LOWMEM_PFN PFN_DOWN(MAX_LOWMEM) - -static void __init setup_bootmem(void) -{ - unsigned bootmap_size; - unsigned long first_pfn, bootmap_pfn, pages; - unsigned long max_pfn, max_low_pfn; - unsigned node = 0; - struct resource *res; - - printk(KERN_INFO "Physical memory:\n"); - for (res = system_ram; res; res = res->sibling) - printk(" %08x-%08x\n", res->start, res->end); - printk(KERN_INFO "Reserved memory:\n"); - for (res = reserved; res; res = res->sibling) - printk(" %08x-%08x: %s\n", - res->start, res->end, res->name); - - nodes_clear(node_online_map); - - if (system_ram->sibling) - printk(KERN_WARNING "Only using first memory bank\n"); - - for (res = system_ram; res; res = NULL) { - first_pfn = PFN_UP(res->start); - max_low_pfn = max_pfn = PFN_DOWN(res->end + 1); - bootmap_pfn = find_bootmap_pfn(res); - if (bootmap_pfn > max_pfn) - panic("No space for bootmem bitmap!\n"); - - if (max_low_pfn > MAX_LOWMEM_PFN) { - max_low_pfn = MAX_LOWMEM_PFN; -#ifndef CONFIG_HIGHMEM - /* - * Lowmem is memory that can be addressed - * directly through P1/P2 - */ - printk(KERN_WARNING - "Node %u: Only %ld MiB of memory will be used.\n", - node, MAX_LOWMEM >> 20); - printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n"); -#else -#error HIGHMEM is not supported by AVR32 yet -#endif - } - - /* Initialize the boot-time allocator with low memory only. */ - bootmap_size = init_bootmem_node(NODE_DATA(node), bootmap_pfn, - first_pfn, max_low_pfn); - - /* - * Register fully available RAM pages with the bootmem - * allocator. - */ - pages = max_low_pfn - first_pfn; - free_bootmem_node (NODE_DATA(node), PFN_PHYS(first_pfn), - PFN_PHYS(pages)); - - /* Reserve space for the bootmem bitmap... */ - reserve_bootmem_node(NODE_DATA(node), - PFN_PHYS(bootmap_pfn), - bootmap_size, - BOOTMEM_DEFAULT); - - /* ...and any other reserved regions. */ - for (res = reserved; res; res = res->sibling) { - if (res->start > PFN_PHYS(max_pfn)) - break; - - /* - * resource_init will complain about partial - * overlaps, so we'll just ignore such - * resources for now. - */ - if (res->start >= PFN_PHYS(first_pfn) - && res->end < PFN_PHYS(max_pfn)) - reserve_bootmem_node(NODE_DATA(node), - res->start, - resource_size(res), - BOOTMEM_DEFAULT); - } - - node_set_online(node); - } -} - -void __init setup_arch (char **cmdline_p) -{ - struct clk *cpu_clk; - - init_mm.start_code = (unsigned long)_stext; - init_mm.end_code = (unsigned long)_etext; - init_mm.end_data = (unsigned long)_edata; - init_mm.brk = (unsigned long)_end; - - /* - * Include .init section to make allocations easier. It will - * be removed before the resource is actually requested. - */ - kernel_code.start = __pa(__init_begin); - kernel_code.end = __pa(init_mm.end_code - 1); - kernel_data.start = __pa(init_mm.end_code); - kernel_data.end = __pa(init_mm.brk - 1); - - parse_tags(bootloader_tags); - - setup_processor(); - setup_platform(); - setup_board(); - - cpu_clk = clk_get(NULL, "cpu"); - if (IS_ERR(cpu_clk)) { - printk(KERN_WARNING "Warning: Unable to get CPU clock\n"); - } else { - unsigned long cpu_hz = clk_get_rate(cpu_clk); - - /* - * Well, duh, but it's probably a good idea to - * increment the use count. - */ - clk_enable(cpu_clk); - - boot_cpu_data.clk = cpu_clk; - boot_cpu_data.loops_per_jiffy = cpu_hz * 4; - printk("CPU: Running at %lu.%03lu MHz\n", - ((cpu_hz + 500) / 1000) / 1000, - ((cpu_hz + 500) / 1000) % 1000); - } - - strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; - parse_early_param(); - - setup_bootmem(); - -#ifdef CONFIG_VT - conswitchp = &dummy_con; -#endif - - paging_init(); - resource_init(); -} diff --git a/arch/avr32/kernel/signal.c b/arch/avr32/kernel/signal.c deleted file mode 100644 index b5fcc4914fe4..000000000000 --- a/arch/avr32/kernel/signal.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * Based on linux/arch/sh/kernel/signal.c - * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima - * Copyright (C) 1991, 1992 Linus Torvalds - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/ptrace.h> -#include <linux/unistd.h> -#include <linux/tracehook.h> - -#include <linux/uaccess.h> -#include <asm/ucontext.h> -#include <asm/syscalls.h> - -struct rt_sigframe -{ - struct siginfo info; - struct ucontext uc; - unsigned long retcode; -}; - -static int -restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) -{ - int err = 0; - -#define COPY(x) err |= __get_user(regs->x, &sc->x) - COPY(sr); - COPY(pc); - COPY(lr); - COPY(sp); - COPY(r12); - COPY(r11); - COPY(r10); - COPY(r9); - COPY(r8); - COPY(r7); - COPY(r6); - COPY(r5); - COPY(r4); - COPY(r3); - COPY(r2); - COPY(r1); - COPY(r0); -#undef COPY - - /* - * Don't allow anyone to pretend they're running in supervisor - * mode or something... - */ - err |= !valid_user_regs(regs); - - return err; -} - - -asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - sigset_t set; - - /* Always make any pending restarted system calls return -EINTR */ - current->restart_block.fn = do_no_restart_syscall; - - frame = (struct rt_sigframe __user *)regs->sp; - pr_debug("SIG return: frame = %p\n", frame); - - if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) - goto badframe; - - if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) - goto badframe; - - set_current_blocked(&set); - - if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - pr_debug("Context restored: pc = %08lx, lr = %08lx, sp = %08lx\n", - regs->pc, regs->lr, regs->sp); - - return regs->r12; - -badframe: - force_sig(SIGSEGV, current); - return 0; -} - -static int -setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs) -{ - int err = 0; - -#define COPY(x) err |= __put_user(regs->x, &sc->x) - COPY(sr); - COPY(pc); - COPY(lr); - COPY(sp); - COPY(r12); - COPY(r11); - COPY(r10); - COPY(r9); - COPY(r8); - COPY(r7); - COPY(r6); - COPY(r5); - COPY(r4); - COPY(r3); - COPY(r2); - COPY(r1); - COPY(r0); -#undef COPY - - return err; -} - -static inline void __user * -get_sigframe(struct ksignal *ksig, struct pt_regs *regs, int framesize) -{ - unsigned long sp = sigsp(regs->sp, ksig); - - return (void __user *)((sp - framesize) & ~3); -} - -static int -setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) -{ - struct rt_sigframe __user *frame; - int err = 0; - - frame = get_sigframe(ksig, regs, sizeof(*frame)); - err = -EFAULT; - if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) - goto out; - - /* - * Set up the return code: - * - * mov r8, __NR_rt_sigreturn - * scall - * - * Note: This will blow up since we're using a non-executable - * stack. Better use SA_RESTORER. - */ -#if __NR_rt_sigreturn > 127 -# error __NR_rt_sigreturn must be < 127 to fit in a short mov -#endif - err = __put_user(0x3008d733 | (__NR_rt_sigreturn << 20), - &frame->retcode); - - err |= copy_siginfo_to_user(&frame->info, &ksig->info); - - /* Set up the ucontext */ - err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(NULL, &frame->uc.uc_link); - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigcontext(&frame->uc.uc_mcontext, regs); - err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); - - if (err) - goto out; - - regs->r12 = ksig->sig; - regs->r11 = (unsigned long) &frame->info; - regs->r10 = (unsigned long) &frame->uc; - regs->sp = (unsigned long) frame; - if (ksig->ka.sa.sa_flags & SA_RESTORER) - regs->lr = (unsigned long)ksig->ka.sa.sa_restorer; - else { - printk(KERN_NOTICE "[%s:%d] did not set SA_RESTORER\n", - current->comm, current->pid); - regs->lr = (unsigned long) &frame->retcode; - } - - pr_debug("SIG deliver [%s:%d]: sig=%d sp=0x%lx pc=0x%lx->0x%p lr=0x%lx\n", - current->comm, current->pid, ksig->sig, regs->sp, - regs->pc, ksig->ka.sa.sa_handler, regs->lr); - - regs->pc = (unsigned long)ksig->ka.sa.sa_handler; - -out: - return err; -} - -static inline void setup_syscall_restart(struct pt_regs *regs) -{ - if (regs->r12 == -ERESTART_RESTARTBLOCK) - regs->r8 = __NR_restart_syscall; - else - regs->r12 = regs->r12_orig; - regs->pc -= 2; -} - -static inline void -handle_signal(struct ksignal *ksig, struct pt_regs *regs, int syscall) -{ - int ret; - - /* - * Set up the stack frame - */ - ret = setup_rt_frame(ksig, sigmask_to_save(), regs); - - /* - * Check that the resulting registers are sane - */ - ret |= !valid_user_regs(regs); - - /* - * Block the signal if we were successful. - */ - signal_setup_done(ret, ksig, 0); -} - -/* - * Note that 'init' is a special process: it doesn't get signals it - * doesn't want to handle. Thus you cannot kill init even with a - * SIGKILL even by mistake. - */ -static void do_signal(struct pt_regs *regs, int syscall) -{ - struct ksignal ksig; - - /* - * We want the common case to go fast, which is why we may in - * certain cases get here from kernel mode. Just return - * without doing anything if so. - */ - if (!user_mode(regs)) - return; - - get_signal(&ksig); - if (syscall) { - switch (regs->r12) { - case -ERESTART_RESTARTBLOCK: - case -ERESTARTNOHAND: - if (ksig.sig > 0) { - regs->r12 = -EINTR; - break; - } - /* fall through */ - case -ERESTARTSYS: - if (ksig.sig > 0 && !(ksig.ka.sa.sa_flags & SA_RESTART)) { - regs->r12 = -EINTR; - break; - } - /* fall through */ - case -ERESTARTNOINTR: - setup_syscall_restart(regs); - } - } - - if (!ksig.sig) { - /* No signal to deliver -- put the saved sigmask back */ - restore_saved_sigmask(); - return; - } - - handle_signal(&ksig, regs, syscall); -} - -asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) -{ - int syscall = 0; - - if ((sysreg_read(SR) & MODE_MASK) == MODE_SUPERVISOR) - syscall = 1; - - if (ti->flags & _TIF_SIGPENDING) - do_signal(regs, syscall); - - if (ti->flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - } -} diff --git a/arch/avr32/kernel/stacktrace.c b/arch/avr32/kernel/stacktrace.c deleted file mode 100644 index f8cc995cf0e0..000000000000 --- a/arch/avr32/kernel/stacktrace.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Stack trace management functions - * - * Copyright (C) 2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/sched.h> -#include <linux/sched/task_stack.h> -#include <linux/stacktrace.h> -#include <linux/thread_info.h> -#include <linux/module.h> - -register unsigned long current_frame_pointer asm("r7"); - -struct stackframe { - unsigned long lr; - unsigned long fp; -}; - -/* - * Save stack-backtrace addresses into a stack_trace buffer. - */ -void save_stack_trace(struct stack_trace *trace) -{ - unsigned long low, high; - unsigned long fp; - struct stackframe *frame; - int skip = trace->skip; - - low = (unsigned long)task_stack_page(current); - high = low + THREAD_SIZE; - fp = current_frame_pointer; - - while (fp >= low && fp <= (high - 8)) { - frame = (struct stackframe *)fp; - - if (skip) { - skip--; - } else { - trace->entries[trace->nr_entries++] = frame->lr; - if (trace->nr_entries >= trace->max_entries) - break; - } - - /* - * The next frame must be at a higher address than the - * current frame. - */ - low = fp + 8; - fp = frame->fp; - } -} -EXPORT_SYMBOL_GPL(save_stack_trace); diff --git a/arch/avr32/kernel/switch_to.S b/arch/avr32/kernel/switch_to.S deleted file mode 100644 index a48d046723c5..000000000000 --- a/arch/avr32/kernel/switch_to.S +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <asm/sysreg.h> - - .text - .global __switch_to - .type __switch_to, @function - - /* Switch thread context from "prev" to "next", returning "last" - * r12 : prev - * r11 : &prev->thread + 1 - * r10 : &next->thread - */ -__switch_to: - stm --r11, r0,r1,r2,r3,r4,r5,r6,r7,sp,lr - mfsr r9, SYSREG_SR - st.w --r11, r9 - ld.w r8, r10++ - /* - * schedule() may have been called from a mode with a different - * set of registers. Make sure we don't lose anything here. - */ - pushm r10,r12 - mtsr SYSREG_SR, r8 - frs /* flush the return stack */ - sub pc, -2 /* flush the pipeline */ - popm r10,r12 - ldm r10++, r0,r1,r2,r3,r4,r5,r6,r7,sp,pc - .size __switch_to, . - __switch_to diff --git a/arch/avr32/kernel/syscall-stubs.S b/arch/avr32/kernel/syscall-stubs.S deleted file mode 100644 index cb256534ed92..000000000000 --- a/arch/avr32/kernel/syscall-stubs.S +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2005-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* - * Stubs for syscalls that require access to pt_regs or that take more - * than five parameters. - */ - -#define ARG6 r3 - - .text - .global __sys_rt_sigsuspend - .type __sys_rt_sigsuspend,@function -__sys_rt_sigsuspend: - mov r10, sp - rjmp sys_rt_sigsuspend - - .global __sys_rt_sigreturn - .type __sys_rt_sigreturn,@function -__sys_rt_sigreturn: - mov r12, sp - rjmp sys_rt_sigreturn - - .global __sys_mmap2 - .type __sys_mmap2,@function -__sys_mmap2: - pushm lr - st.w --sp, ARG6 - call sys_mmap_pgoff - sub sp, -4 - popm pc - - .global __sys_sendto - .type __sys_sendto,@function -__sys_sendto: - pushm lr - st.w --sp, ARG6 - call sys_sendto - sub sp, -4 - popm pc - - .global __sys_recvfrom - .type __sys_recvfrom,@function -__sys_recvfrom: - pushm lr - st.w --sp, ARG6 - call sys_recvfrom - sub sp, -4 - popm pc - - .global __sys_pselect6 - .type __sys_pselect6,@function -__sys_pselect6: - pushm lr - st.w --sp, ARG6 - call sys_pselect6 - sub sp, -4 - popm pc - - .global __sys_splice - .type __sys_splice,@function -__sys_splice: - pushm lr - st.w --sp, ARG6 - call sys_splice - sub sp, -4 - popm pc - - .global __sys_epoll_pwait - .type __sys_epoll_pwait,@function -__sys_epoll_pwait: - pushm lr - st.w --sp, ARG6 - call sys_epoll_pwait - sub sp, -4 - popm pc - - .global __sys_sync_file_range - .type __sys_sync_file_range,@function -__sys_sync_file_range: - pushm lr - st.w --sp, ARG6 - call sys_sync_file_range - sub sp, -4 - popm pc - - .global __sys_fallocate - .type __sys_fallocate,@function -__sys_fallocate: - pushm lr - st.w --sp, ARG6 - call sys_fallocate - sub sp, -4 - popm pc - - .global __sys_fanotify_mark - .type __sys_fanotify_mark,@function -__sys_fanotify_mark: - pushm lr - st.w --sp, ARG6 - call sys_fanotify_mark - sub sp, -4 - popm pc - - .global __sys_process_vm_readv - .type __sys_process_vm_readv,@function -__sys_process_vm_readv: - pushm lr - st.w --sp, ARG6 - call sys_process_vm_readv - sub sp, -4 - popm pc - - .global __sys_process_vm_writev - .type __sys_process_vm_writev,@function -__sys_process_vm_writev: - pushm lr - st.w --sp, ARG6 - call sys_process_vm_writev - sub sp, -4 - popm pc - - .global __sys_copy_file_range - .type __sys_copy_file_range,@function -__sys_copy_file_range: - pushm lr - st.w --sp, ARG6 - call sys_copy_file_range - sub sp, -4 - popm pc - - .global __sys_preadv2 - .type __sys_preadv2,@function -__sys_preadv2: - pushm lr - st.w --sp, ARG6 - call sys_preadv2 - sub sp, -4 - popm pc - - .global __sys_pwritev2 - .type __sys_pwritev2,@function -__sys_pwritev2: - pushm lr - st.w --sp, ARG6 - call sys_pwritev2 - sub sp, -4 - popm pc diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S deleted file mode 100644 index 774ce57f4948..000000000000 --- a/arch/avr32/kernel/syscall_table.S +++ /dev/null @@ -1,347 +0,0 @@ -/* - * AVR32 system call table - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - .section .rodata,"a",@progbits - .type sys_call_table,@object - .global sys_call_table - .align 2 -sys_call_table: - .long sys_restart_syscall - .long sys_exit - .long sys_fork - .long sys_read - .long sys_write - .long sys_open - .long sys_close - .long sys_umask - .long sys_creat - .long sys_link - .long sys_unlink /* 10 */ - .long sys_execve - .long sys_chdir - .long sys_time - .long sys_mknod - .long sys_chmod - .long sys_chown - .long sys_lchown - .long sys_lseek - .long sys_llseek - .long sys_getpid /* 20 */ - .long sys_mount - .long sys_umount - .long sys_setuid - .long sys_getuid - .long sys_stime - .long sys_ptrace - .long sys_alarm - .long sys_pause - .long sys_utime - .long sys_newstat /* 30 */ - .long sys_newfstat - .long sys_newlstat - .long sys_access - .long sys_chroot - .long sys_sync - .long sys_fsync - .long sys_kill - .long sys_rename - .long sys_mkdir - .long sys_rmdir /* 40 */ - .long sys_dup - .long sys_pipe - .long sys_times - .long sys_clone - .long sys_brk - .long sys_setgid - .long sys_getgid - .long sys_getcwd - .long sys_geteuid - .long sys_getegid /* 50 */ - .long sys_acct - .long sys_setfsuid - .long sys_setfsgid - .long sys_ioctl - .long sys_fcntl - .long sys_setpgid - .long sys_mremap - .long sys_setresuid - .long sys_getresuid - .long sys_setreuid /* 60 */ - .long sys_setregid - .long sys_ustat - .long sys_dup2 - .long sys_getppid - .long sys_getpgrp - .long sys_setsid - .long sys_rt_sigaction - .long __sys_rt_sigreturn - .long sys_rt_sigprocmask - .long sys_rt_sigpending /* 70 */ - .long sys_rt_sigtimedwait - .long sys_rt_sigqueueinfo - .long __sys_rt_sigsuspend - .long sys_sethostname - .long sys_setrlimit - .long sys_getrlimit - .long sys_getrusage - .long sys_gettimeofday - .long sys_settimeofday - .long sys_getgroups /* 80 */ - .long sys_setgroups - .long sys_select - .long sys_symlink - .long sys_fchdir - .long sys_readlink - .long sys_pread64 - .long sys_pwrite64 - .long sys_swapon - .long sys_reboot - .long __sys_mmap2 /* 90 */ - .long sys_munmap - .long sys_truncate - .long sys_ftruncate - .long sys_fchmod - .long sys_fchown - .long sys_getpriority - .long sys_setpriority - .long sys_wait4 - .long sys_statfs - .long sys_fstatfs /* 100 */ - .long sys_vhangup - .long sys_sigaltstack - .long sys_syslog - .long sys_setitimer - .long sys_getitimer - .long sys_swapoff - .long sys_sysinfo - .long sys_ni_syscall /* was sys_ipc briefly */ - .long sys_sendfile - .long sys_setdomainname /* 110 */ - .long sys_newuname - .long sys_adjtimex - .long sys_mprotect - .long sys_vfork - .long sys_init_module - .long sys_delete_module - .long sys_quotactl - .long sys_getpgid - .long sys_bdflush - .long sys_sysfs /* 120 */ - .long sys_personality - .long sys_ni_syscall /* reserved for afs_syscall */ - .long sys_getdents - .long sys_flock - .long sys_msync - .long sys_readv - .long sys_writev - .long sys_getsid - .long sys_fdatasync - .long sys_sysctl /* 130 */ - .long sys_mlock - .long sys_munlock - .long sys_mlockall - .long sys_munlockall - .long sys_sched_setparam - .long sys_sched_getparam - .long sys_sched_setscheduler - .long sys_sched_getscheduler - .long sys_sched_yield - .long sys_sched_get_priority_max /* 140 */ - .long sys_sched_get_priority_min - .long sys_sched_rr_get_interval - .long sys_nanosleep - .long sys_poll - .long sys_ni_syscall /* 145 was nfsservctl */ - .long sys_setresgid - .long sys_getresgid - .long sys_prctl - .long sys_socket - .long sys_bind /* 150 */ - .long sys_connect - .long sys_listen - .long sys_accept - .long sys_getsockname - .long sys_getpeername - .long sys_socketpair - .long sys_send - .long sys_recv - .long __sys_sendto - .long __sys_recvfrom /* 160 */ - .long sys_shutdown - .long sys_setsockopt - .long sys_getsockopt - .long sys_sendmsg - .long sys_recvmsg - .long sys_truncate64 - .long sys_ftruncate64 - .long sys_stat64 - .long sys_lstat64 - .long sys_fstat64 /* 170 */ - .long sys_pivot_root - .long sys_mincore - .long sys_madvise - .long sys_getdents64 - .long sys_fcntl64 - .long sys_gettid - .long sys_readahead - .long sys_setxattr - .long sys_lsetxattr - .long sys_fsetxattr /* 180 */ - .long sys_getxattr - .long sys_lgetxattr - .long sys_fgetxattr - .long sys_listxattr - .long sys_llistxattr - .long sys_flistxattr - .long sys_removexattr - .long sys_lremovexattr - .long sys_fremovexattr - .long sys_tkill /* 190 */ - .long sys_sendfile64 - .long sys_futex - .long sys_sched_setaffinity - .long sys_sched_getaffinity - .long sys_capget - .long sys_capset - .long sys_io_setup - .long sys_io_destroy - .long sys_io_getevents - .long sys_io_submit /* 200 */ - .long sys_io_cancel - .long sys_fadvise64 - .long sys_exit_group - .long sys_lookup_dcookie - .long sys_epoll_create - .long sys_epoll_ctl - .long sys_epoll_wait - .long sys_remap_file_pages - .long sys_set_tid_address - .long sys_timer_create /* 210 */ - .long sys_timer_settime - .long sys_timer_gettime - .long sys_timer_getoverrun - .long sys_timer_delete - .long sys_clock_settime - .long sys_clock_gettime - .long sys_clock_getres - .long sys_clock_nanosleep - .long sys_statfs64 - .long sys_fstatfs64 /* 220 */ - .long sys_tgkill - .long sys_ni_syscall /* reserved for TUX */ - .long sys_utimes - .long sys_fadvise64_64 - .long sys_cacheflush - .long sys_ni_syscall /* sys_vserver */ - .long sys_mq_open - .long sys_mq_unlink - .long sys_mq_timedsend - .long sys_mq_timedreceive /* 230 */ - .long sys_mq_notify - .long sys_mq_getsetattr - .long sys_kexec_load - .long sys_waitid - .long sys_add_key - .long sys_request_key - .long sys_keyctl - .long sys_ioprio_set - .long sys_ioprio_get - .long sys_inotify_init /* 240 */ - .long sys_inotify_add_watch - .long sys_inotify_rm_watch - .long sys_openat - .long sys_mkdirat - .long sys_mknodat - .long sys_fchownat - .long sys_futimesat - .long sys_fstatat64 - .long sys_unlinkat - .long sys_renameat /* 250 */ - .long sys_linkat - .long sys_symlinkat - .long sys_readlinkat - .long sys_fchmodat - .long sys_faccessat - .long __sys_pselect6 - .long sys_ppoll - .long sys_unshare - .long sys_set_robust_list - .long sys_get_robust_list /* 260 */ - .long __sys_splice - .long __sys_sync_file_range - .long sys_tee - .long sys_vmsplice - .long __sys_epoll_pwait - .long sys_msgget - .long sys_msgsnd - .long sys_msgrcv - .long sys_msgctl - .long sys_semget /* 270 */ - .long sys_semop - .long sys_semctl - .long sys_semtimedop - .long sys_shmat - .long sys_shmget - .long sys_shmdt - .long sys_shmctl - .long sys_utimensat - .long sys_signalfd - .long sys_ni_syscall /* 280, was sys_timerfd */ - .long sys_eventfd - .long sys_ni_syscall /* 282, was half-implemented recvmmsg */ - .long sys_setns - .long sys_pread64 - .long sys_pwrite64 - .long sys_timerfd_create - .long __sys_fallocate - .long sys_timerfd_settime - .long sys_timerfd_gettime - .long sys_signalfd4 /* 290 */ - .long sys_eventfd2 - .long sys_epoll_create1 - .long sys_dup3 - .long sys_pipe2 - .long sys_inotify_init1 - .long sys_preadv - .long sys_pwritev - .long sys_rt_tgsigqueueinfo - .long sys_perf_event_open - .long sys_recvmmsg /* 300 */ - .long sys_fanotify_init - .long __sys_fanotify_mark - .long sys_prlimit64 - .long sys_name_to_handle_at - .long sys_open_by_handle_at - .long sys_clock_adjtime - .long sys_syncfs - .long sys_sendmmsg - .long __sys_process_vm_readv - .long __sys_process_vm_writev /* 310 */ - .long sys_kcmp - .long sys_finit_module - .long sys_sched_setattr - .long sys_sched_getattr - .long sys_renameat2 - .long sys_seccomp - .long sys_getrandom - .long sys_memfd_create - .long sys_bpf - .long sys_execveat /* 320 */ - .long sys_accept4 - .long sys_userfaultfd - .long sys_membarrier - .long sys_mlock2 - .long __sys_copy_file_range - .long __sys_preadv2 - .long __sys_pwritev2 - .long sys_pkey_mprotect - .long sys_pkey_alloc - .long sys_pkey_free /* 330 */ - .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ diff --git a/arch/avr32/kernel/time.c b/arch/avr32/kernel/time.c deleted file mode 100644 index 4d9b69615979..000000000000 --- a/arch/avr32/kernel/time.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2004-2007 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include <linux/clk.h> -#include <linux/clockchips.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/kernel.h> -#include <linux/time.h> -#include <linux/cpu.h> - -#include <asm/sysreg.h> - -#include <mach/pm.h> - -static bool disable_cpu_idle_poll; - -static u64 read_cycle_count(struct clocksource *cs) -{ - return (u64)sysreg_read(COUNT); -} - -/* - * The architectural cycle count registers are a fine clocksource unless - * the system idle loop use sleep states like "idle": the CPU cycles - * measured by COUNT (and COMPARE) don't happen during sleep states. - * Their duration also changes if cpufreq changes the CPU clock rate. - * So we rate the clocksource using COUNT as very low quality. - */ -static struct clocksource counter = { - .name = "avr32_counter", - .rating = 50, - .read = read_cycle_count, - .mask = CLOCKSOURCE_MASK(32), - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static irqreturn_t timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evdev = dev_id; - - if (unlikely(!(intc_get_pending(0) & 1))) - return IRQ_NONE; - - /* - * Disable the interrupt until the clockevent subsystem - * reprograms it. - */ - sysreg_write(COMPARE, 0); - - evdev->event_handler(evdev); - return IRQ_HANDLED; -} - -static struct irqaction timer_irqaction = { - .handler = timer_interrupt, - /* Oprofile uses the same irq as the timer, so allow it to be shared */ - .flags = IRQF_TIMER | IRQF_SHARED, - .name = "avr32_comparator", -}; - -static int comparator_next_event(unsigned long delta, - struct clock_event_device *evdev) -{ - unsigned long flags; - - raw_local_irq_save(flags); - - /* The time to read COUNT then update COMPARE must be less - * than the min_delta_ns value for this clockevent source. - */ - sysreg_write(COMPARE, (sysreg_read(COUNT) + delta) ? : 1); - - raw_local_irq_restore(flags); - - return 0; -} - -static int comparator_shutdown(struct clock_event_device *evdev) -{ - pr_debug("%s: %s\n", __func__, evdev->name); - sysreg_write(COMPARE, 0); - - if (disable_cpu_idle_poll) { - disable_cpu_idle_poll = false; - /* - * Only disable idle poll if we have forced that - * in a previous call. - */ - cpu_idle_poll_ctrl(false); - } - return 0; -} - -static int comparator_set_oneshot(struct clock_event_device *evdev) -{ - pr_debug("%s: %s\n", __func__, evdev->name); - - disable_cpu_idle_poll = true; - /* - * If we're using the COUNT and COMPARE registers we - * need to force idle poll. - */ - cpu_idle_poll_ctrl(true); - - return 0; -} - -static struct clock_event_device comparator = { - .name = "avr32_comparator", - .features = CLOCK_EVT_FEAT_ONESHOT, - .shift = 16, - .rating = 50, - .set_next_event = comparator_next_event, - .set_state_shutdown = comparator_shutdown, - .set_state_oneshot = comparator_set_oneshot, - .tick_resume = comparator_set_oneshot, -}; - -void read_persistent_clock(struct timespec *ts) -{ - ts->tv_sec = mktime(2007, 1, 1, 0, 0, 0); - ts->tv_nsec = 0; -} - -void __init time_init(void) -{ - unsigned long counter_hz; - int ret; - - /* figure rate for counter */ - counter_hz = clk_get_rate(boot_cpu_data.clk); - ret = clocksource_register_hz(&counter, counter_hz); - if (ret) - pr_debug("timer: could not register clocksource: %d\n", ret); - - /* setup COMPARE clockevent */ - comparator.mult = div_sc(counter_hz, NSEC_PER_SEC, comparator.shift); - comparator.max_delta_ns = clockevent_delta2ns((u32)~0, &comparator); - comparator.min_delta_ns = clockevent_delta2ns(50, &comparator) + 1; - comparator.cpumask = cpumask_of(0); - - sysreg_write(COMPARE, 0); - timer_irqaction.dev_id = &comparator; - - ret = setup_irq(0, &timer_irqaction); - if (ret) - pr_debug("timer: could not request IRQ 0: %d\n", ret); - else { - clockevents_register_device(&comparator); - - pr_info("%s: irq 0, %lu.%03lu MHz\n", comparator.name, - ((counter_hz + 500) / 1000) / 1000, - ((counter_hz + 500) / 1000) % 1000); - } -} diff --git a/arch/avr32/kernel/traps.c b/arch/avr32/kernel/traps.c deleted file mode 100644 index 50b541325025..000000000000 --- a/arch/avr32/kernel/traps.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/bug.h> -#include <linux/hardirq.h> -#include <linux/init.h> -#include <linux/kallsyms.h> -#include <linux/kdebug.h> -#include <linux/extable.h> -#include <linux/module.h> /* print_modules */ -#include <linux/notifier.h> -#include <linux/sched/signal.h> -#include <linux/uaccess.h> - -#include <asm/addrspace.h> -#include <asm/mmu_context.h> -#include <asm/ocd.h> -#include <asm/sysreg.h> -#include <asm/traps.h> - -static DEFINE_SPINLOCK(die_lock); - -void die(const char *str, struct pt_regs *regs, long err) -{ - static int die_counter; - - console_verbose(); - spin_lock_irq(&die_lock); - bust_spinlocks(1); - - printk(KERN_ALERT "Oops: %s, sig: %ld [#%d]\n", - str, err, ++die_counter); - - printk(KERN_EMERG); - -#ifdef CONFIG_PREEMPT - printk(KERN_CONT "PREEMPT "); -#endif -#ifdef CONFIG_FRAME_POINTER - printk(KERN_CONT "FRAME_POINTER "); -#endif - if (current_cpu_data.features & AVR32_FEATURE_OCD) { - unsigned long did = ocd_read(DID); - printk(KERN_CONT "chip: 0x%03lx:0x%04lx rev %lu\n", - (did >> 1) & 0x7ff, - (did >> 12) & 0x7fff, - (did >> 28) & 0xf); - } else { - printk(KERN_CONT "cpu: arch %u r%u / core %u r%u\n", - current_cpu_data.arch_type, - current_cpu_data.arch_revision, - current_cpu_data.cpu_type, - current_cpu_data.cpu_revision); - } - - print_modules(); - show_regs_log_lvl(regs, KERN_EMERG); - show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG); - bust_spinlocks(0); - add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); - spin_unlock_irq(&die_lock); - - if (in_interrupt()) - panic("Fatal exception in interrupt"); - - if (panic_on_oops) - panic("Fatal exception"); - - do_exit(err); -} - -void _exception(long signr, struct pt_regs *regs, int code, - unsigned long addr) -{ - siginfo_t info; - - if (!user_mode(regs)) { - const struct exception_table_entry *fixup; - - /* Are we prepared to handle this kernel fault? */ - fixup = search_exception_tables(regs->pc); - if (fixup) { - regs->pc = fixup->fixup; - return; - } - die("Unhandled exception in kernel mode", regs, signr); - } - - memset(&info, 0, sizeof(info)); - info.si_signo = signr; - info.si_code = code; - info.si_addr = (void __user *)addr; - force_sig_info(signr, &info, current); -} - -asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs) -{ - int ret; - - nmi_enter(); - - ret = notify_die(DIE_NMI, "NMI", regs, 0, ecr, SIGINT); - switch (ret) { - case NOTIFY_OK: - case NOTIFY_STOP: - break; - case NOTIFY_BAD: - die("Fatal Non-Maskable Interrupt", regs, SIGINT); - default: - printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n"); - nmi_disable(); - break; - } - nmi_exit(); -} - -asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs) -{ - die("Critical exception", regs, SIGKILL); -} - -asmlinkage void do_address_exception(unsigned long ecr, struct pt_regs *regs) -{ - _exception(SIGBUS, regs, BUS_ADRALN, regs->pc); -} - -/* This way of handling undefined instructions is stolen from ARM */ -static LIST_HEAD(undef_hook); -static DEFINE_SPINLOCK(undef_lock); - -void register_undef_hook(struct undef_hook *hook) -{ - spin_lock_irq(&undef_lock); - list_add(&hook->node, &undef_hook); - spin_unlock_irq(&undef_lock); -} - -void unregister_undef_hook(struct undef_hook *hook) -{ - spin_lock_irq(&undef_lock); - list_del(&hook->node); - spin_unlock_irq(&undef_lock); -} - -static int do_cop_absent(u32 insn) -{ - int cop_nr; - u32 cpucr; - - if ((insn & 0xfdf00000) == 0xf1900000) - /* LDC0 */ - cop_nr = 0; - else - cop_nr = (insn >> 13) & 0x7; - - /* Try enabling the coprocessor */ - cpucr = sysreg_read(CPUCR); - cpucr |= (1 << (24 + cop_nr)); - sysreg_write(CPUCR, cpucr); - - cpucr = sysreg_read(CPUCR); - if (!(cpucr & (1 << (24 + cop_nr)))) - return -ENODEV; - - return 0; -} - -#ifdef CONFIG_BUG -int is_valid_bugaddr(unsigned long pc) -{ - unsigned short opcode; - - if (pc < PAGE_OFFSET) - return 0; - if (probe_kernel_address((u16 *)pc, opcode)) - return 0; - - return opcode == AVR32_BUG_OPCODE; -} -#endif - -asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs) -{ - u32 insn; - struct undef_hook *hook; - void __user *pc; - long code; - -#ifdef CONFIG_BUG - if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) { - enum bug_trap_type type; - - type = report_bug(regs->pc, regs); - switch (type) { - case BUG_TRAP_TYPE_NONE: - break; - case BUG_TRAP_TYPE_WARN: - regs->pc += 2; - return; - case BUG_TRAP_TYPE_BUG: - die("Kernel BUG", regs, SIGKILL); - } - } -#endif - - local_irq_enable(); - - if (user_mode(regs)) { - pc = (void __user *)instruction_pointer(regs); - if (get_user(insn, (u32 __user *)pc)) - goto invalid_area; - - if (ecr == ECR_COPROC_ABSENT && !do_cop_absent(insn)) - return; - - spin_lock_irq(&undef_lock); - list_for_each_entry(hook, &undef_hook, node) { - if ((insn & hook->insn_mask) == hook->insn_val) { - if (hook->fn(regs, insn) == 0) { - spin_unlock_irq(&undef_lock); - return; - } - } - } - spin_unlock_irq(&undef_lock); - } - - switch (ecr) { - case ECR_PRIVILEGE_VIOLATION: - code = ILL_PRVOPC; - break; - case ECR_COPROC_ABSENT: - code = ILL_COPROC; - break; - default: - code = ILL_ILLOPC; - break; - } - - _exception(SIGILL, regs, code, regs->pc); - return; - -invalid_area: - _exception(SIGSEGV, regs, SEGV_MAPERR, regs->pc); -} - -asmlinkage void do_fpe(unsigned long ecr, struct pt_regs *regs) -{ - /* We have no FPU yet */ - _exception(SIGILL, regs, ILL_COPROC, regs->pc); -} - - -void __init trap_init(void) -{ - -} diff --git a/arch/avr32/kernel/vmlinux.lds.S b/arch/avr32/kernel/vmlinux.lds.S deleted file mode 100644 index 17f2730eb497..000000000000 --- a/arch/avr32/kernel/vmlinux.lds.S +++ /dev/null @@ -1,89 +0,0 @@ -/* - * AVR32 linker script for the Linux kernel - * - * Copyright (C) 2004-2006 Atmel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#define LOAD_OFFSET 0x00000000 -#include <asm-generic/vmlinux.lds.h> -#include <asm/cache.h> -#include <asm/thread_info.h> - -OUTPUT_FORMAT("elf32-avr32", "elf32-avr32", "elf32-avr32") -OUTPUT_ARCH(avr32) -ENTRY(_start) - -/* Big endian */ -jiffies = jiffies_64 + 4; - -SECTIONS -{ - . = CONFIG_ENTRY_ADDRESS; - .init : AT(ADDR(.init) - LOAD_OFFSET) { - _text = .; - __init_begin = .; - _sinittext = .; - *(.text.reset) - INIT_TEXT - /* - * .exit.text is discarded at runtime, not - * link time, to deal with references from - * __bug_table - */ - EXIT_TEXT - _einittext = .; - . = ALIGN(4); - __tagtable_begin = .; - *(.taglist.init) - __tagtable_end = .; - } - INIT_DATA_SECTION(16) - . = ALIGN(PAGE_SIZE); - __init_end = .; - - .text : AT(ADDR(.text) - LOAD_OFFSET) { - _evba = .; - _stext = .; - *(.ex.text) - *(.irq.text) - KPROBES_TEXT - TEXT_TEXT - SCHED_TEXT - CPUIDLE_TEXT - LOCK_TEXT - *(.fixup) - *(.gnu.warning) - _etext = .; - } = 0xd703d703 - - EXCEPTION_TABLE(4) - RODATA - - .data : AT(ADDR(.data) - LOAD_OFFSET) { - _data = .; - _sdata = .; - - INIT_TASK_DATA(THREAD_SIZE) - PAGE_ALIGNED_DATA(PAGE_SIZE); - CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES) - *(.data.rel*) - DATA_DATA - CONSTRUCTORS - - _edata = .; - } - - BSS_SECTION(0, 8, 8) - _end = .; - - DWARF_DEBUG - - /* When something in the kernel is NOT compiled as a module, the module - * cleanup code and data are put into these segments. Both can then be - * thrown away, as cleanup code is never called unless it's a module. - */ - DISCARDS -} |