aboutsummaryrefslogtreecommitdiff
path: root/arch/m68k/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/m68k/kernel')
-rw-r--r--arch/m68k/kernel/Makefile12
-rw-r--r--arch/m68k/kernel/asm-offsets.c5
-rw-r--r--arch/m68k/kernel/bootinfo_proc.c80
-rw-r--r--arch/m68k/kernel/dma.c168
-rw-r--r--arch/m68k/kernel/dma_mm.c131
-rw-r--r--arch/m68k/kernel/dma_no.c75
-rw-r--r--arch/m68k/kernel/early_printk.c67
-rw-r--r--arch/m68k/kernel/entry.S424
-rw-r--r--arch/m68k/kernel/entry_mm.S419
-rw-r--r--arch/m68k/kernel/entry_no.S130
-rw-r--r--arch/m68k/kernel/head.S307
-rw-r--r--arch/m68k/kernel/init_task.c35
-rw-r--r--arch/m68k/kernel/ints.c11
-rw-r--r--arch/m68k/kernel/irq.c1
-rw-r--r--arch/m68k/kernel/machine_kexec.c58
-rw-r--r--arch/m68k/kernel/module.c4
-rw-r--r--arch/m68k/kernel/pcibios.c104
-rw-r--r--arch/m68k/kernel/process.c278
-rw-r--r--arch/m68k/kernel/process_mm.c369
-rw-r--r--arch/m68k/kernel/process_no.c406
-rw-r--r--arch/m68k/kernel/ptrace.c305
-rw-r--r--arch/m68k/kernel/ptrace_mm.c295
-rw-r--r--arch/m68k/kernel/ptrace_no.c255
-rw-r--r--arch/m68k/kernel/relocate_kernel.S159
-rw-r--r--arch/m68k/kernel/setup_mm.c69
-rw-r--r--arch/m68k/kernel/setup_no.c28
-rw-r--r--arch/m68k/kernel/signal.c1139
-rw-r--r--arch/m68k/kernel/signal_mm.c1115
-rw-r--r--arch/m68k/kernel/signal_no.c765
-rw-r--r--arch/m68k/kernel/sys_m68k.c25
-rw-r--r--arch/m68k/kernel/syscalltable.S11
-rw-r--r--arch/m68k/kernel/time.c114
-rw-r--r--arch/m68k/kernel/time_mm.c114
-rw-r--r--arch/m68k/kernel/time_no.c90
-rw-r--r--arch/m68k/kernel/traps.c249
-rw-r--r--arch/m68k/kernel/vectors.c1
-rw-r--r--arch/m68k/kernel/vmlinux-nommu.lds198
-rw-r--r--arch/m68k/kernel/vmlinux-std.lds2
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds2
39 files changed, 3230 insertions, 4790 deletions
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile
index 40d29a788b0..e47778f8588 100644
--- a/arch/m68k/kernel/Makefile
+++ b/arch/m68k/kernel/Makefile
@@ -13,13 +13,17 @@ extra-$(CONFIG_SUN3X) := head.o
extra-$(CONFIG_SUN3) := sun3-head.o
extra-y += vmlinux.lds
-obj-y := entry.o init_task.o irq.o m68k_ksyms.o module.o process.o ptrace.o
+obj-y := entry.o irq.o m68k_ksyms.o module.o process.o ptrace.o
obj-y += setup.o signal.o sys_m68k.o syscalltable.o time.o traps.o
obj-$(CONFIG_MMU_MOTOROLA) += ints.o vectors.o
obj-$(CONFIG_MMU_SUN3) += ints.o vectors.o
+obj-$(CONFIG_PCI) += pcibios.o
-ifndef CONFIG_MMU_SUN3
-obj-y += dma.o
-endif
+obj-$(CONFIG_HAS_DMA) += dma.o
+
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
+obj-$(CONFIG_BOOTINFO_PROC) += bootinfo_proc.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/m68k/kernel/asm-offsets.c b/arch/m68k/kernel/asm-offsets.c
index a972b00cd77..3a386341aa6 100644
--- a/arch/m68k/kernel/asm-offsets.c
+++ b/arch/m68k/kernel/asm-offsets.c
@@ -77,7 +77,7 @@ int main(void)
DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
DEFINE(BIR_DATA, offsetof(struct bi_record, data));
- /* offsets into font_desc (drivers/video/console/font.h) */
+ /* offsets into the font_desc struct */
DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
@@ -98,6 +98,9 @@ int main(void)
DEFINE(CIABBASE, &ciab);
DEFINE(C_PRA, offsetof(struct CIA, pra));
DEFINE(ZTWOBASE, zTwoBase);
+
+ /* enum m68k_fixup_type */
+ DEFINE(M68K_FIXUP_MEMOFFSET, m68k_fixup_memoffset);
#endif
return 0;
diff --git a/arch/m68k/kernel/bootinfo_proc.c b/arch/m68k/kernel/bootinfo_proc.c
new file mode 100644
index 00000000000..7ee853e1432
--- /dev/null
+++ b/arch/m68k/kernel/bootinfo_proc.c
@@ -0,0 +1,80 @@
+/*
+ * Based on arch/arm/kernel/atags_proc.c
+ */
+
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
+
+
+static char bootinfo_tmp[1536] __initdata;
+
+static void *bootinfo_copy;
+static size_t bootinfo_size;
+
+static ssize_t bootinfo_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ return simple_read_from_buffer(buf, count, ppos, bootinfo_copy,
+ bootinfo_size);
+}
+
+static const struct file_operations bootinfo_fops = {
+ .read = bootinfo_read,
+ .llseek = default_llseek,
+};
+
+void __init save_bootinfo(const struct bi_record *bi)
+{
+ const void *start = bi;
+ size_t size = sizeof(bi->tag);
+
+ while (be16_to_cpu(bi->tag) != BI_LAST) {
+ uint16_t n = be16_to_cpu(bi->size);
+ size += n;
+ bi = (struct bi_record *)((unsigned long)bi + n);
+ }
+
+ if (size > sizeof(bootinfo_tmp)) {
+ pr_err("Cannot save %zu bytes of bootinfo\n", size);
+ return;
+ }
+
+ pr_info("Saving %zu bytes of bootinfo\n", size);
+ memcpy(bootinfo_tmp, start, size);
+ bootinfo_size = size;
+}
+
+static int __init init_bootinfo_procfs(void)
+{
+ /*
+ * This cannot go into save_bootinfo() because kmalloc and proc don't
+ * work yet when it is called.
+ */
+ struct proc_dir_entry *pde;
+
+ if (!bootinfo_size)
+ return -EINVAL;
+
+ bootinfo_copy = kmalloc(bootinfo_size, GFP_KERNEL);
+ if (!bootinfo_copy)
+ return -ENOMEM;
+
+ memcpy(bootinfo_copy, bootinfo_tmp, bootinfo_size);
+
+ pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_fops, NULL);
+ if (!pde) {
+ kfree(bootinfo_copy);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+arch_initcall(init_bootinfo_procfs);
diff --git a/arch/m68k/kernel/dma.c b/arch/m68k/kernel/dma.c
index 90e8cb726c8..e546a5534dd 100644
--- a/arch/m68k/kernel/dma.c
+++ b/arch/m68k/kernel/dma.c
@@ -1,5 +1,165 @@
-#ifdef CONFIG_MMU
-#include "dma_mm.c"
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#undef DEBUG
+
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/export.h>
+
+#include <asm/pgalloc.h>
+
+#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *handle, gfp_t flag)
+{
+ struct page *page, **map;
+ pgprot_t pgprot;
+ void *addr;
+ int i, order;
+
+ pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
+
+ size = PAGE_ALIGN(size);
+ order = get_order(size);
+
+ page = alloc_pages(flag, order);
+ if (!page)
+ return NULL;
+
+ *handle = page_to_phys(page);
+ map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
+ if (!map) {
+ __free_pages(page, order);
+ return NULL;
+ }
+ split_page(page, order);
+
+ order = 1 << order;
+ size >>= PAGE_SHIFT;
+ map[0] = page;
+ for (i = 1; i < size; i++)
+ map[i] = page + i;
+ for (; i < order; i++)
+ __free_page(page + i);
+ pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+ if (CPU_IS_040_OR_060)
+ pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
+ else
+ pgprot_val(pgprot) |= _PAGE_NOCACHE030;
+ addr = vmap(map, size, VM_MAP, pgprot);
+ kfree(map);
+
+ return addr;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+ void *addr, dma_addr_t handle)
+{
+ pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
+ vfree(addr);
+}
+
#else
-#include "dma_no.c"
-#endif
+
+#include <asm/cacheflush.h>
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ void *ret;
+ /* ignore region specifiers */
+ gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
+
+ if (dev == NULL || (*dev->dma_mask < 0xffffffff))
+ gfp |= GFP_DMA;
+ ret = (void *)__get_free_pages(gfp, get_order(size));
+
+ if (ret != NULL) {
+ memset(ret, 0, size);
+ *dma_handle = virt_to_phys(ret);
+ }
+ return ret;
+}
+
+void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ free_pages((unsigned long)vaddr, get_order(size));
+}
+
+#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
+
+EXPORT_SYMBOL(dma_alloc_coherent);
+EXPORT_SYMBOL(dma_free_coherent);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ switch (dir) {
+ case DMA_BIDIRECTIONAL:
+ case DMA_TO_DEVICE:
+ cache_push(handle, size);
+ break;
+ case DMA_FROM_DEVICE:
+ cache_clear(handle, size);
+ break;
+ default:
+ if (printk_ratelimit())
+ printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
+ break;
+ }
+}
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ int i;
+
+ for (i = 0; i < nents; sg++, i++)
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
+ enum dma_data_direction dir)
+{
+ dma_addr_t handle = virt_to_bus(addr);
+
+ dma_sync_single_for_device(dev, handle, size, dir);
+ return handle;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ dma_addr_t handle = page_to_phys(page) + offset;
+
+ dma_sync_single_for_device(dev, handle, size, dir);
+ return handle;
+}
+EXPORT_SYMBOL(dma_map_page);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ int i;
+
+ for (i = 0; i < nents; sg++, i++) {
+ sg->dma_address = sg_phys(sg);
+ dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
+ }
+ return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/m68k/kernel/dma_mm.c b/arch/m68k/kernel/dma_mm.c
deleted file mode 100644
index a3c471b523f..00000000000
--- a/arch/m68k/kernel/dma_mm.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#undef DEBUG
-
-#include <linux/dma-mapping.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/scatterlist.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/export.h>
-
-#include <asm/pgalloc.h>
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *handle, gfp_t flag)
-{
- struct page *page, **map;
- pgprot_t pgprot;
- void *addr;
- int i, order;
-
- pr_debug("dma_alloc_coherent: %d,%x\n", size, flag);
-
- size = PAGE_ALIGN(size);
- order = get_order(size);
-
- page = alloc_pages(flag, order);
- if (!page)
- return NULL;
-
- *handle = page_to_phys(page);
- map = kmalloc(sizeof(struct page *) << order, flag & ~__GFP_DMA);
- if (!map) {
- __free_pages(page, order);
- return NULL;
- }
- split_page(page, order);
-
- order = 1 << order;
- size >>= PAGE_SHIFT;
- map[0] = page;
- for (i = 1; i < size; i++)
- map[i] = page + i;
- for (; i < order; i++)
- __free_page(page + i);
- pgprot = __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
- if (CPU_IS_040_OR_060)
- pgprot_val(pgprot) |= _PAGE_GLOBAL040 | _PAGE_NOCACHE_S;
- else
- pgprot_val(pgprot) |= _PAGE_NOCACHE030;
- addr = vmap(map, size, VM_MAP, pgprot);
- kfree(map);
-
- return addr;
-}
-EXPORT_SYMBOL(dma_alloc_coherent);
-
-void dma_free_coherent(struct device *dev, size_t size,
- void *addr, dma_addr_t handle)
-{
- pr_debug("dma_free_coherent: %p, %x\n", addr, handle);
- vfree(addr);
-}
-EXPORT_SYMBOL(dma_free_coherent);
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- switch (dir) {
- case DMA_TO_DEVICE:
- cache_push(handle, size);
- break;
- case DMA_FROM_DEVICE:
- cache_clear(handle, size);
- break;
- default:
- if (printk_ratelimit())
- printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
- break;
- }
-}
-EXPORT_SYMBOL(dma_sync_single_for_device);
-
-void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
-{
- int i;
-
- for (i = 0; i < nents; sg++, i++)
- dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
-}
-EXPORT_SYMBOL(dma_sync_sg_for_device);
-
-dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
- enum dma_data_direction dir)
-{
- dma_addr_t handle = virt_to_bus(addr);
-
- dma_sync_single_for_device(dev, handle, size, dir);
- return handle;
-}
-EXPORT_SYMBOL(dma_map_single);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- dma_addr_t handle = page_to_phys(page) + offset;
-
- dma_sync_single_for_device(dev, handle, size, dir);
- return handle;
-}
-EXPORT_SYMBOL(dma_map_page);
-
-int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
- enum dma_data_direction dir)
-{
- int i;
-
- for (i = 0; i < nents; sg++, i++) {
- sg->dma_address = sg_phys(sg);
- dma_sync_single_for_device(dev, sg->dma_address, sg->length, dir);
- }
- return nents;
-}
-EXPORT_SYMBOL(dma_map_sg);
diff --git a/arch/m68k/kernel/dma_no.c b/arch/m68k/kernel/dma_no.c
deleted file mode 100644
index f1dc3fc71bc..00000000000
--- a/arch/m68k/kernel/dma_no.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Dynamic DMA mapping support.
- *
- * We never have any address translations to worry about, so this
- * is just alloc/free.
- */
-
-#include <linux/types.h>
-#include <linux/gfp.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/export.h>
-#include <asm/cacheflush.h>
-
-void *dma_alloc_coherent(struct device *dev, size_t size,
- dma_addr_t *dma_handle, gfp_t gfp)
-{
- void *ret;
- /* ignore region specifiers */
- gfp &= ~(__GFP_DMA | __GFP_HIGHMEM);
-
- if (dev == NULL || (*dev->dma_mask < 0xffffffff))
- gfp |= GFP_DMA;
- ret = (void *)__get_free_pages(gfp, get_order(size));
-
- if (ret != NULL) {
- memset(ret, 0, size);
- *dma_handle = virt_to_phys(ret);
- }
- return ret;
-}
-
-void dma_free_coherent(struct device *dev, size_t size,
- void *vaddr, dma_addr_t dma_handle)
-{
- free_pages((unsigned long)vaddr, get_order(size));
-}
-
-void dma_sync_single_for_device(struct device *dev, dma_addr_t handle,
- size_t size, enum dma_data_direction dir)
-{
- switch (dir) {
- case DMA_TO_DEVICE:
- flush_dcache_range(handle, size);
- break;
- case DMA_FROM_DEVICE:
- /* Should be clear already */
- break;
- default:
- if (printk_ratelimit())
- printk("dma_sync_single_for_device: unsupported dir %u\n", dir);
- break;
- }
-}
-
-EXPORT_SYMBOL(dma_sync_single_for_device);
-dma_addr_t dma_map_single(struct device *dev, void *addr, size_t size,
- enum dma_data_direction dir)
-{
- dma_addr_t handle = virt_to_phys(addr);
- flush_dcache_range(handle, size);
- return handle;
-}
-EXPORT_SYMBOL(dma_map_single);
-
-dma_addr_t dma_map_page(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
- enum dma_data_direction dir)
-{
- dma_addr_t handle = page_to_phys(page) + offset;
- dma_sync_single_for_device(dev, handle, size, dir);
- return handle;
-}
-EXPORT_SYMBOL(dma_map_page);
diff --git a/arch/m68k/kernel/early_printk.c b/arch/m68k/kernel/early_printk.c
new file mode 100644
index 00000000000..ff9708d7192
--- /dev/null
+++ b/arch/m68k/kernel/early_printk.c
@@ -0,0 +1,67 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2014 Finn Thain
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/setup.h>
+
+extern void mvme16x_cons_write(struct console *co,
+ const char *str, unsigned count);
+
+asmlinkage void __init debug_cons_nputs(const char *s, unsigned n);
+
+static void __ref debug_cons_write(struct console *c,
+ const char *s, unsigned n)
+{
+#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68360) || \
+ defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE))
+ if (MACH_IS_MVME16x)
+ mvme16x_cons_write(c, s, n);
+ else
+ debug_cons_nputs(s, n);
+#endif
+}
+
+static struct console early_console_instance = {
+ .name = "debug",
+ .write = debug_cons_write,
+ .flags = CON_PRINTBUFFER | CON_BOOT,
+ .index = -1
+};
+
+static int __init setup_early_printk(char *buf)
+{
+ if (early_console || buf)
+ return 0;
+
+ early_console = &early_console_instance;
+ register_console(early_console);
+
+ return 0;
+}
+early_param("earlyprintk", setup_early_printk);
+
+/*
+ * debug_cons_nputs() defined in arch/m68k/kernel/head.S cannot be called
+ * after init sections are discarded (for platforms that use it).
+ */
+#if !(defined(CONFIG_SUN3) || defined(CONFIG_M68360) || \
+ defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE))
+
+static int __init unregister_early_console(void)
+{
+ if (!early_console || MACH_IS_MVME16x)
+ return 0;
+
+ return unregister_console(early_console);
+}
+late_initcall(unregister_early_console);
+
+#endif
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index b8daf64e347..b54ac7aba85 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -1,5 +1,423 @@
-#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
-#include "entry_mm.S"
+/* -*- mode: asm -*-
+ *
+ * linux/arch/m68k/kernel/entry.S
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ */
+
+/*
+ * entry.S contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ * all pointers that used to be 'current' are now entry
+ * number 0 in the 'current_set' list.
+ *
+ * 6/05/00 RZ: addedd writeback completion after return from sighandler
+ * for 68040
+ */
+
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+#include <asm/unistd.h>
+#include <asm/asm-offsets.h>
+#include <asm/entry.h>
+
+.globl system_call, buserr, trap, resume
+.globl sys_call_table
+.globl __sys_fork, __sys_clone, __sys_vfork
+.globl bad_interrupt
+.globl auto_irqhandler_fixup
+.globl user_irqvec_fixup
+
+.text
+ENTRY(__sys_fork)
+ SAVE_SWITCH_STACK
+ jbsr sys_fork
+ lea %sp@(24),%sp
+ rts
+
+ENTRY(__sys_clone)
+ SAVE_SWITCH_STACK
+ pea %sp@(SWITCH_STACK_SIZE)
+ jbsr m68k_clone
+ lea %sp@(28),%sp
+ rts
+
+ENTRY(__sys_vfork)
+ SAVE_SWITCH_STACK
+ jbsr sys_vfork
+ lea %sp@(24),%sp
+ rts
+
+ENTRY(sys_sigreturn)
+ SAVE_SWITCH_STACK
+ jbsr do_sigreturn
+ RESTORE_SWITCH_STACK
+ rts
+
+ENTRY(sys_rt_sigreturn)
+ SAVE_SWITCH_STACK
+ jbsr do_rt_sigreturn
+ RESTORE_SWITCH_STACK
+ rts
+
+ENTRY(buserr)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+ movel %sp,%sp@- | stack frame pointer argument
+ jbsr buserr_c
+ addql #4,%sp
+ jra ret_from_exception
+
+ENTRY(trap)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+ movel %sp,%sp@- | stack frame pointer argument
+ jbsr trap_c
+ addql #4,%sp
+ jra ret_from_exception
+
+ | After a fork we jump here directly from resume,
+ | so that %d1 contains the previous task
+ | schedule_tail now used regardless of CONFIG_SMP
+ENTRY(ret_from_fork)
+ movel %d1,%sp@-
+ jsr schedule_tail
+ addql #4,%sp
+ jra ret_from_exception
+
+ENTRY(ret_from_kernel_thread)
+ | a3 contains the kernel thread payload, d7 - its argument
+ movel %d1,%sp@-
+ jsr schedule_tail
+ movel %d7,(%sp)
+ jsr %a3@
+ addql #4,%sp
+ jra ret_from_exception
+
+#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
+
+#ifdef TRAP_DBG_INTERRUPT
+
+.globl dbginterrupt
+ENTRY(dbginterrupt)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+ movel %sp,%sp@- /* stack frame pointer argument */
+ jsr dbginterrupt_c
+ addql #4,%sp
+ jra ret_from_exception
+#endif
+
+ENTRY(reschedule)
+ /* save top of frame */
+ pea %sp@
+ jbsr set_esp0
+ addql #4,%sp
+ pea ret_from_exception
+ jmp schedule
+
+ENTRY(ret_from_user_signal)
+ moveq #__NR_sigreturn,%d0
+ trap #0
+
+ENTRY(ret_from_user_rt_signal)
+ movel #__NR_rt_sigreturn,%d0
+ trap #0
+
#else
-#include "entry_no.S"
+
+do_trace_entry:
+ movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
+ subql #4,%sp
+ SAVE_SWITCH_STACK
+ jbsr syscall_trace
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ movel %sp@(PT_OFF_ORIG_D0),%d0
+ cmpl #NR_syscalls,%d0
+ jcs syscall
+badsys:
+ movel #-ENOSYS,%sp@(PT_OFF_D0)
+ jra ret_from_syscall
+
+do_trace_exit:
+ subql #4,%sp
+ SAVE_SWITCH_STACK
+ jbsr syscall_trace
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ jra .Lret_from_exception
+
+ENTRY(ret_from_signal)
+ movel %curptr@(TASK_STACK),%a1
+ tstb %a1@(TINFO_FLAGS+2)
+ jge 1f
+ jbsr syscall_trace
+1: RESTORE_SWITCH_STACK
+ addql #4,%sp
+/* on 68040 complete pending writebacks if any */
+#ifdef CONFIG_M68040
+ bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0
+ subql #7,%d0 | bus error frame ?
+ jbne 1f
+ movel %sp,%sp@-
+ jbsr berr_040cleanup
+ addql #4,%sp
+1:
+#endif
+ jra .Lret_from_exception
+
+ENTRY(system_call)
+ SAVE_ALL_SYS
+
+ GET_CURRENT(%d1)
+ movel %d1,%a1
+
+ | save top of frame
+ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+
+ | syscall trace?
+ tstb %a1@(TINFO_FLAGS+2)
+ jmi do_trace_entry
+ cmpl #NR_syscalls,%d0
+ jcc badsys
+syscall:
+ jbsr @(sys_call_table,%d0:l:4)@(0)
+ movel %d0,%sp@(PT_OFF_D0) | save the return value
+ret_from_syscall:
+ |oriw #0x0700,%sr
+ movel %curptr@(TASK_STACK),%a1
+ movew %a1@(TINFO_FLAGS+2),%d0
+ jne syscall_exit_work
+1: RESTORE_ALL
+
+syscall_exit_work:
+ btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
+ bnes 1b | if so, skip resched, signals
+ lslw #1,%d0
+ jcs do_trace_exit
+ jmi do_delayed_trace
+ lslw #8,%d0
+ jne do_signal_return
+ pea resume_userspace
+ jra schedule
+
+
+ENTRY(ret_from_exception)
+.Lret_from_exception:
+ btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
+ bnes 1f | if so, skip resched, signals
+ | only allow interrupts when we are really the last one on the
+ | kernel stack, otherwise stack overflow can occur during
+ | heavy interrupt load
+ andw #ALLOWINT,%sr
+
+resume_userspace:
+ movel %curptr@(TASK_STACK),%a1
+ moveb %a1@(TINFO_FLAGS+3),%d0
+ jne exit_work
+1: RESTORE_ALL
+
+exit_work:
+ | save top of frame
+ movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+ lslb #1,%d0
+ jne do_signal_return
+ pea resume_userspace
+ jra schedule
+
+
+do_signal_return:
+ |andw #ALLOWINT,%sr
+ subql #4,%sp | dummy return address
+ SAVE_SWITCH_STACK
+ pea %sp@(SWITCH_STACK_SIZE)
+ bsrl do_notify_resume
+ addql #4,%sp
+ RESTORE_SWITCH_STACK
+ addql #4,%sp
+ jbra resume_userspace
+
+do_delayed_trace:
+ bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
+ pea 1 | send SIGTRAP
+ movel %curptr,%sp@-
+ pea LSIGTRAP
+ jbsr send_sig
+ addql #8,%sp
+ addql #4,%sp
+ jbra resume_userspace
+
+
+/* This is the main interrupt handler for autovector interrupts */
+
+ENTRY(auto_inthandler)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+ | put exception # in d0
+ bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
+ subw #VEC_SPUR,%d0
+
+ movel %sp,%sp@-
+ movel %d0,%sp@- | put vector # on stack
+auto_irqhandler_fixup = . + 2
+ jsr do_IRQ | process the IRQ
+ addql #8,%sp | pop parameters off stack
+ jra ret_from_exception
+
+/* Handler for user defined interrupt vectors */
+
+ENTRY(user_inthandler)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+ | put exception # in d0
+ bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
+user_irqvec_fixup = . + 2
+ subw #VEC_USER,%d0
+
+ movel %sp,%sp@-
+ movel %d0,%sp@- | put vector # on stack
+ jsr do_IRQ | process the IRQ
+ addql #8,%sp | pop parameters off stack
+ jra ret_from_exception
+
+/* Handler for uninitialized and spurious interrupts */
+
+ENTRY(bad_inthandler)
+ SAVE_ALL_INT
+ GET_CURRENT(%d0)
+
+ movel %sp,%sp@-
+ jsr handle_badint
+ addql #4,%sp
+ jra ret_from_exception
+
+resume:
+ /*
+ * Beware - when entering resume, prev (the current task) is
+ * in a0, next (the new task) is in a1,so don't change these
+ * registers until their contents are no longer needed.
+ */
+
+ /* save sr */
+ movew %sr,%a0@(TASK_THREAD+THREAD_SR)
+
+ /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+ movec %sfc,%d0
+ movew %d0,%a0@(TASK_THREAD+THREAD_FS)
+
+ /* save usp */
+ /* it is better to use a movel here instead of a movew 8*) */
+ movec %usp,%d0
+ movel %d0,%a0@(TASK_THREAD+THREAD_USP)
+
+ /* save non-scratch registers on stack */
+ SAVE_SWITCH_STACK
+
+ /* save current kernel stack pointer */
+ movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+ /* save floating point context */
+#ifndef CONFIG_M68KFPU_EMU_ONLY
+#ifdef CONFIG_M68KFPU_EMU
+ tstl m68k_fputype
+ jeq 3f
+#endif
+ fsave %a0@(TASK_THREAD+THREAD_FPSTATE)
+
+#if defined(CONFIG_M68060)
+#if !defined(CPU_M68060_ONLY)
+ btst #3,m68k_cputype+3
+ beqs 1f
+#endif
+ /* The 060 FPU keeps status in bits 15-8 of the first longword */
+ tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2)
+ jeq 3f
+#if !defined(CPU_M68060_ONLY)
+ jra 2f
+#endif
+#endif /* CONFIG_M68060 */
+#if !defined(CPU_M68060_ONLY)
+1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)
+ jeq 3f
+#endif
+2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)
+ fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)
+3:
+#endif /* CONFIG_M68KFPU_EMU_ONLY */
+ /* Return previous task in %d1 */
+ movel %curptr,%d1
+
+ /* switch to new task (a1 contains new task) */
+ movel %a1,%curptr
+
+ /* restore floating point context */
+#ifndef CONFIG_M68KFPU_EMU_ONLY
+#ifdef CONFIG_M68KFPU_EMU
+ tstl m68k_fputype
+ jeq 4f
+#endif
+#if defined(CONFIG_M68060)
+#if !defined(CPU_M68060_ONLY)
+ btst #3,m68k_cputype+3
+ beqs 1f
+#endif
+ /* The 060 FPU keeps status in bits 15-8 of the first longword */
+ tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2)
+ jeq 3f
+#if !defined(CPU_M68060_ONLY)
+ jra 2f
+#endif
+#endif /* CONFIG_M68060 */
+#if !defined(CPU_M68060_ONLY)
+1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)
+ jeq 3f
#endif
+2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7
+ fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar
+3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)
+4:
+#endif /* CONFIG_M68KFPU_EMU_ONLY */
+
+ /* restore the kernel stack pointer */
+ movel %a1@(TASK_THREAD+THREAD_KSP),%sp
+
+ /* restore non-scratch registers */
+ RESTORE_SWITCH_STACK
+
+ /* restore user stack pointer */
+ movel %a1@(TASK_THREAD+THREAD_USP),%a0
+ movel %a0,%usp
+
+ /* restore fs (sfc,%dfc) */
+ movew %a1@(TASK_THREAD+THREAD_FS),%a0
+ movec %a0,%sfc
+ movec %a0,%dfc
+
+ /* restore status register */
+ movew %a1@(TASK_THREAD+THREAD_SR),%sr
+
+ rts
+
+#endif /* CONFIG_MMU && !CONFIG_COLDFIRE */
diff --git a/arch/m68k/kernel/entry_mm.S b/arch/m68k/kernel/entry_mm.S
deleted file mode 100644
index 675a854966a..00000000000
--- a/arch/m68k/kernel/entry_mm.S
+++ /dev/null
@@ -1,419 +0,0 @@
-/* -*- mode: asm -*-
- *
- * linux/arch/m68k/kernel/entry.S
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
- * Linux/m68k support by Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- *
- */
-
-/*
- * entry.S contains the system-call and fault low-level handling routines.
- * This also contains the timer-interrupt handler, as well as all interrupts
- * and faults that can result in a task-switch.
- *
- * NOTE: This code handles signal-recognition, which happens every time
- * after a timer-interrupt and after each system call.
- *
- */
-
-/*
- * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
- * all pointers that used to be 'current' are now entry
- * number 0 in the 'current_set' list.
- *
- * 6/05/00 RZ: addedd writeback completion after return from sighandler
- * for 68040
- */
-
-#include <linux/linkage.h>
-#include <asm/entry.h>
-#include <asm/errno.h>
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/traps.h>
-#include <asm/unistd.h>
-
-#include <asm/asm-offsets.h>
-
-.globl system_call, buserr, trap, resume
-.globl sys_call_table
-.globl sys_fork, sys_clone, sys_vfork
-.globl ret_from_interrupt, bad_interrupt
-.globl auto_irqhandler_fixup
-.globl user_irqvec_fixup
-
-.text
-ENTRY(buserr)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %sp,%sp@- | stack frame pointer argument
- bsrl buserr_c
- addql #4,%sp
- jra .Lret_from_exception
-
-ENTRY(trap)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %sp,%sp@- | stack frame pointer argument
- bsrl trap_c
- addql #4,%sp
- jra .Lret_from_exception
-
- | After a fork we jump here directly from resume,
- | so that %d1 contains the previous task
- | schedule_tail now used regardless of CONFIG_SMP
-ENTRY(ret_from_fork)
- movel %d1,%sp@-
- jsr schedule_tail
- addql #4,%sp
- jra .Lret_from_exception
-
-do_trace_entry:
- movel #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
- subql #4,%sp
- SAVE_SWITCH_STACK
- jbsr syscall_trace
- RESTORE_SWITCH_STACK
- addql #4,%sp
- movel %sp@(PT_OFF_ORIG_D0),%d0
- cmpl #NR_syscalls,%d0
- jcs syscall
-badsys:
- movel #-ENOSYS,%sp@(PT_OFF_D0)
- jra ret_from_syscall
-
-do_trace_exit:
- subql #4,%sp
- SAVE_SWITCH_STACK
- jbsr syscall_trace
- RESTORE_SWITCH_STACK
- addql #4,%sp
- jra .Lret_from_exception
-
-ENTRY(ret_from_signal)
- movel %curptr@(TASK_STACK),%a1
- tstb %a1@(TINFO_FLAGS+2)
- jge 1f
- jbsr syscall_trace
-1: RESTORE_SWITCH_STACK
- addql #4,%sp
-/* on 68040 complete pending writebacks if any */
-#ifdef CONFIG_M68040
- bfextu %sp@(PT_OFF_FORMATVEC){#0,#4},%d0
- subql #7,%d0 | bus error frame ?
- jbne 1f
- movel %sp,%sp@-
- jbsr berr_040cleanup
- addql #4,%sp
-1:
-#endif
- jra .Lret_from_exception
-
-ENTRY(system_call)
- SAVE_ALL_SYS
-
- GET_CURRENT(%d1)
- movel %d1,%a1
-
- | save top of frame
- movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
-
- | syscall trace?
- tstb %a1@(TINFO_FLAGS+2)
- jmi do_trace_entry
- cmpl #NR_syscalls,%d0
- jcc badsys
-syscall:
- jbsr @(sys_call_table,%d0:l:4)@(0)
- movel %d0,%sp@(PT_OFF_D0) | save the return value
-ret_from_syscall:
- |oriw #0x0700,%sr
- movel %curptr@(TASK_STACK),%a1
- movew %a1@(TINFO_FLAGS+2),%d0
- jne syscall_exit_work
-1: RESTORE_ALL
-
-syscall_exit_work:
- btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
- bnes 1b | if so, skip resched, signals
- lslw #1,%d0
- jcs do_trace_exit
- jmi do_delayed_trace
- lslw #8,%d0
- jmi do_signal_return
- pea resume_userspace
- jra schedule
-
-
-ENTRY(ret_from_exception)
-.Lret_from_exception:
- btst #5,%sp@(PT_OFF_SR) | check if returning to kernel
- bnes 1f | if so, skip resched, signals
- | only allow interrupts when we are really the last one on the
- | kernel stack, otherwise stack overflow can occur during
- | heavy interrupt load
- andw #ALLOWINT,%sr
-
-resume_userspace:
- movel %curptr@(TASK_STACK),%a1
- moveb %a1@(TINFO_FLAGS+3),%d0
- jne exit_work
-1: RESTORE_ALL
-
-exit_work:
- | save top of frame
- movel %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
- lslb #1,%d0
- jmi do_signal_return
- pea resume_userspace
- jra schedule
-
-
-do_signal_return:
- |andw #ALLOWINT,%sr
- subql #4,%sp | dummy return address
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- bsrl do_signal
- addql #4,%sp
- RESTORE_SWITCH_STACK
- addql #4,%sp
- jbra resume_userspace
-
-do_delayed_trace:
- bclr #7,%sp@(PT_OFF_SR) | clear trace bit in SR
- pea 1 | send SIGTRAP
- movel %curptr,%sp@-
- pea LSIGTRAP
- jbsr send_sig
- addql #8,%sp
- addql #4,%sp
- jbra resume_userspace
-
-
-/* This is the main interrupt handler for autovector interrupts */
-
-ENTRY(auto_inthandler)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %d0,%a1
- addqb #1,%a1@(TINFO_PREEMPT+1)
- | put exception # in d0
- bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
- subw #VEC_SPUR,%d0
-
- movel %sp,%sp@-
- movel %d0,%sp@- | put vector # on stack
-auto_irqhandler_fixup = . + 2
- jsr do_IRQ | process the IRQ
- addql #8,%sp | pop parameters off stack
-
-ret_from_interrupt:
- movel %curptr@(TASK_STACK),%a1
- subqb #1,%a1@(TINFO_PREEMPT+1)
- jeq ret_from_last_interrupt
-2: RESTORE_ALL
-
- ALIGN
-ret_from_last_interrupt:
- moveq #(~ALLOWINT>>8)&0xff,%d0
- andb %sp@(PT_OFF_SR),%d0
- jne 2b
-
- /* check if we need to do software interrupts */
- tstl irq_stat+CPUSTAT_SOFTIRQ_PENDING
- jeq .Lret_from_exception
- pea ret_from_exception
- jra do_softirq
-
-/* Handler for user defined interrupt vectors */
-
-ENTRY(user_inthandler)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %d0,%a1
- addqb #1,%a1@(TINFO_PREEMPT+1)
- | put exception # in d0
- bfextu %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
-user_irqvec_fixup = . + 2
- subw #VEC_USER,%d0
-
- movel %sp,%sp@-
- movel %d0,%sp@- | put vector # on stack
- jsr do_IRQ | process the IRQ
- addql #8,%sp | pop parameters off stack
-
- movel %curptr@(TASK_STACK),%a1
- subqb #1,%a1@(TINFO_PREEMPT+1)
- jeq ret_from_last_interrupt
- RESTORE_ALL
-
-/* Handler for uninitialized and spurious interrupts */
-
-ENTRY(bad_inthandler)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %d0,%a1
- addqb #1,%a1@(TINFO_PREEMPT+1)
-
- movel %sp,%sp@-
- jsr handle_badint
- addql #4,%sp
-
- movel %curptr@(TASK_STACK),%a1
- subqb #1,%a1@(TINFO_PREEMPT+1)
- jeq ret_from_last_interrupt
- RESTORE_ALL
-
-
-ENTRY(sys_fork)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_fork
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_clone)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_clone
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_vfork)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_vfork
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_sigreturn)
- SAVE_SWITCH_STACK
- jbsr do_sigreturn
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_rt_sigreturn)
- SAVE_SWITCH_STACK
- jbsr do_rt_sigreturn
- RESTORE_SWITCH_STACK
- rts
-
-resume:
- /*
- * Beware - when entering resume, prev (the current task) is
- * in a0, next (the new task) is in a1,so don't change these
- * registers until their contents are no longer needed.
- */
-
- /* save sr */
- movew %sr,%a0@(TASK_THREAD+THREAD_SR)
-
- /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
- movec %sfc,%d0
- movew %d0,%a0@(TASK_THREAD+THREAD_FS)
-
- /* save usp */
- /* it is better to use a movel here instead of a movew 8*) */
- movec %usp,%d0
- movel %d0,%a0@(TASK_THREAD+THREAD_USP)
-
- /* save non-scratch registers on stack */
- SAVE_SWITCH_STACK
-
- /* save current kernel stack pointer */
- movel %sp,%a0@(TASK_THREAD+THREAD_KSP)
-
- /* save floating point context */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
-#ifdef CONFIG_M68KFPU_EMU
- tstl m68k_fputype
- jeq 3f
-#endif
- fsave %a0@(TASK_THREAD+THREAD_FPSTATE)
-
-#if defined(CONFIG_M68060)
-#if !defined(CPU_M68060_ONLY)
- btst #3,m68k_cputype+3
- beqs 1f
-#endif
- /* The 060 FPU keeps status in bits 15-8 of the first longword */
- tstb %a0@(TASK_THREAD+THREAD_FPSTATE+2)
- jeq 3f
-#if !defined(CPU_M68060_ONLY)
- jra 2f
-#endif
-#endif /* CONFIG_M68060 */
-#if !defined(CPU_M68060_ONLY)
-1: tstb %a0@(TASK_THREAD+THREAD_FPSTATE)
- jeq 3f
-#endif
-2: fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)
- fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)
-3:
-#endif /* CONFIG_M68KFPU_EMU_ONLY */
- /* Return previous task in %d1 */
- movel %curptr,%d1
-
- /* switch to new task (a1 contains new task) */
- movel %a1,%curptr
-
- /* restore floating point context */
-#ifndef CONFIG_M68KFPU_EMU_ONLY
-#ifdef CONFIG_M68KFPU_EMU
- tstl m68k_fputype
- jeq 4f
-#endif
-#if defined(CONFIG_M68060)
-#if !defined(CPU_M68060_ONLY)
- btst #3,m68k_cputype+3
- beqs 1f
-#endif
- /* The 060 FPU keeps status in bits 15-8 of the first longword */
- tstb %a1@(TASK_THREAD+THREAD_FPSTATE+2)
- jeq 3f
-#if !defined(CPU_M68060_ONLY)
- jra 2f
-#endif
-#endif /* CONFIG_M68060 */
-#if !defined(CPU_M68060_ONLY)
-1: tstb %a1@(TASK_THREAD+THREAD_FPSTATE)
- jeq 3f
-#endif
-2: fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7
- fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar
-3: frestore %a1@(TASK_THREAD+THREAD_FPSTATE)
-4:
-#endif /* CONFIG_M68KFPU_EMU_ONLY */
-
- /* restore the kernel stack pointer */
- movel %a1@(TASK_THREAD+THREAD_KSP),%sp
-
- /* restore non-scratch registers */
- RESTORE_SWITCH_STACK
-
- /* restore user stack pointer */
- movel %a1@(TASK_THREAD+THREAD_USP),%a0
- movel %a0,%usp
-
- /* restore fs (sfc,%dfc) */
- movew %a1@(TASK_THREAD+THREAD_FS),%a0
- movec %a0,%sfc
- movec %a0,%dfc
-
- /* restore status register */
- movew %a1@(TASK_THREAD+THREAD_SR),%sr
-
- rts
-
diff --git a/arch/m68k/kernel/entry_no.S b/arch/m68k/kernel/entry_no.S
deleted file mode 100644
index d80cba45589..00000000000
--- a/arch/m68k/kernel/entry_no.S
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/entry.S
- *
- * Copyright (C) 1999-2002, Greg Ungerer (gerg@snapgear.com)
- * Copyright (C) 1998 D. Jeff Dionne <jeff@lineo.ca>,
- * Kenneth Albanowski <kjahds@kjahds.com>,
- * Copyright (C) 2000 Lineo Inc. (www.lineo.com)
- *
- * Based on:
- *
- * linux/arch/m68k/kernel/entry.S
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file README.legal in the main directory of this archive
- * for more details.
- *
- * Linux/m68k support by Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- * ColdFire support by Greg Ungerer (gerg@snapgear.com)
- * 5307 fixes by David W. Miller
- * linux 2.4 support David McCullough <davidm@snapgear.com>
- */
-
-#include <linux/linkage.h>
-#include <asm/errno.h>
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/asm-offsets.h>
-#include <asm/entry.h>
-#include <asm/unistd.h>
-
-.text
-
-.globl buserr
-.globl trap
-.globl ret_from_exception
-.globl ret_from_signal
-.globl sys_fork
-.globl sys_clone
-.globl sys_vfork
-
-ENTRY(buserr)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %sp,%sp@- /* stack frame pointer argument */
- jsr buserr_c
- addql #4,%sp
- jra ret_from_exception
-
-ENTRY(trap)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %sp,%sp@- /* stack frame pointer argument */
- jsr trap_c
- addql #4,%sp
- jra ret_from_exception
-
-#ifdef TRAP_DBG_INTERRUPT
-
-.globl dbginterrupt
-ENTRY(dbginterrupt)
- SAVE_ALL_INT
- GET_CURRENT(%d0)
- movel %sp,%sp@- /* stack frame pointer argument */
- jsr dbginterrupt_c
- addql #4,%sp
- jra ret_from_exception
-#endif
-
-ENTRY(reschedule)
- /* save top of frame */
- pea %sp@
- jbsr set_esp0
- addql #4,%sp
- pea ret_from_exception
- jmp schedule
-
-ENTRY(ret_from_fork)
- movel %d1,%sp@-
- jsr schedule_tail
- addql #4,%sp
- jra ret_from_exception
-
-ENTRY(sys_fork)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_fork
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_vfork)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_vfork
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_clone)
- SAVE_SWITCH_STACK
- pea %sp@(SWITCH_STACK_SIZE)
- jbsr m68k_clone
- addql #4,%sp
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_sigreturn)
- SAVE_SWITCH_STACK
- jbsr do_sigreturn
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(sys_rt_sigreturn)
- SAVE_SWITCH_STACK
- jbsr do_rt_sigreturn
- RESTORE_SWITCH_STACK
- rts
-
-ENTRY(ret_from_user_signal)
- moveq #__NR_sigreturn,%d0
- trap #0
-
-ENTRY(ret_from_user_rt_signal)
- movel #__NR_rt_sigreturn,%d0
- trap #0
-
diff --git a/arch/m68k/kernel/head.S b/arch/m68k/kernel/head.S
index d197e7ff62c..a54788458ca 100644
--- a/arch/m68k/kernel/head.S
+++ b/arch/m68k/kernel/head.S
@@ -23,7 +23,7 @@
** 98/04/25 Phil Blundell: added HP300 support
** 1998/08/30 David Kilzer: Added support for font_desc structures
** for linux-2.1.115
-** 9/02/11 Richard Zidlicky: added Q40 support (initial vesion 99/01/01)
+** 1999/02/11 Richard Zidlicky: added Q40 support (initial version 99/01/01)
** 2004/05/13 Kars de Jong: Finalised HP300 support
**
** This file is subject to the terms and conditions of the GNU General Public
@@ -153,7 +153,7 @@
* ------------
* The console is also able to be turned off. The console in head.S
* is specifically for debugging and can be very useful. It is surrounded by
- * #ifdef CONSOLE/#endif clauses so it doesn't have to ship in known-good
+ * #ifdef / #endif clauses so it doesn't have to ship in known-good
* kernels. It's basic algorithm is to determine the size of the screen
* (in height/width and bit depth) and then use that information for
* displaying an 8x8 font or an 8x16 (widthxheight). I prefer the 8x8 for
@@ -198,9 +198,8 @@
* CONFIG_xxx: These are the obvious machine configuration defines created
* during configuration. These are defined in autoconf.h.
*
- * CONSOLE: There is support for head.S console in this file. This
- * console can talk to a Mac frame buffer, but could easily be extrapolated
- * to extend it to support other platforms.
+ * CONSOLE_DEBUG: Only supports a Mac frame buffer but could easily be
+ * extended to support other platforms.
*
* TEST_MMU: This is a test harness for running on any given machine but
* getting an MMU dump for another class of machine. The classes of machines
@@ -222,7 +221,7 @@
* MMU_PRINT: There is a routine built into head.S that can display the
* MMU data structures. It outputs its result through the serial_putc
* interface. So where ever that winds up driving data, that's where the
- * mmu struct will appear. On the Macintosh that's typically the console.
+ * mmu struct will appear.
*
* SERIAL_DEBUG: There are a series of putc() macro statements
* scattered through out the code to give progress of status to the
@@ -250,40 +249,35 @@
* USE_MFP: Use the ST-MFP port (Modem1) for serial debug.
*
* Macintosh constants:
- * MAC_USE_SCC_A: Use SCC port A (modem) for serial debug and early console.
- * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug and early console.
+ * MAC_USE_SCC_A: Use SCC port A (modem) for serial debug.
+ * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug.
*/
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/bootinfo.h>
+#include <asm/bootinfo-amiga.h>
+#include <asm/bootinfo-atari.h>
+#include <asm/bootinfo-hp300.h>
+#include <asm/bootinfo-mac.h>
+#include <asm/bootinfo-q40.h>
+#include <asm/bootinfo-vme.h>
#include <asm/setup.h>
#include <asm/entry.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/asm-offsets.h>
-
#ifdef CONFIG_MAC
-
-#include <asm/machw.h>
-
-#ifdef CONFIG_FRAMEBUFFER_CONSOLE
-#define CONSOLE
-#define CONSOLE_PENGUIN
+# include <asm/machw.h>
#endif
#ifdef CONFIG_EARLY_PRINTK
-#define SERIAL_DEBUG
-#else
-#undef SERIAL_DEBUG
+# define SERIAL_DEBUG
+# if defined(CONFIG_MAC) && defined(CONFIG_FONT_SUPPORT)
+# define CONSOLE_DEBUG
+# endif
#endif
-#else /* !CONFIG_MAC */
-
-#define SERIAL_DEBUG
-
-#endif /* !CONFIG_MAC */
-
#undef MMU_PRINT
#undef MMU_NOCACHE_KERNEL
#undef DEBUG
@@ -298,6 +292,7 @@
.globl kernel_pg_dir
.globl availmem
+.globl m68k_init_mapped_size
.globl m68k_pgtable_cachemode
.globl m68k_supervisor_cachemode
#ifdef CONFIG_MVME16x
@@ -475,22 +470,21 @@ func_define serial_putc,1
func_define console_putc,1
func_define console_init
-func_define console_put_stats
func_define console_put_penguin
func_define console_plot_pixel,3
func_define console_scroll
.macro putc ch
-#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
pea \ch
#endif
-#ifdef CONSOLE
+#ifdef CONSOLE_DEBUG
func_call console_putc
#endif
#ifdef SERIAL_DEBUG
func_call serial_putc
#endif
-#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
addql #4,%sp
#endif
.endm
@@ -510,7 +504,7 @@ func_define putn,1
.endm
.macro puts string
-#if defined(CONSOLE) || defined(SERIAL_DEBUG)
+#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
__INITDATA
.Lstr\@:
.string "\string"
@@ -646,32 +640,9 @@ ENTRY(__start)
lea %pc@(L(mac_rowbytes)),%a1
movel %a0@,%a1@
-#ifdef SERIAL_DEBUG
get_bi_record BI_MAC_SCCBASE
lea %pc@(L(mac_sccbase)),%a1
movel %a0@,%a1@
-#endif
-
-#if 0
- /*
- * Clear the screen
- */
- lea %pc@(L(mac_videobase)),%a0
- movel %a0@,%a1
- lea %pc@(L(mac_dimensions)),%a0
- movel %a0@,%d1
- swap %d1 /* #rows is high bytes */
- andl #0xFFFF,%d1 /* rows */
- subl #10,%d1
- lea %pc@(L(mac_rowbytes)),%a0
-loopy2:
- movel %a0@,%d0
- subql #1,%d0
-loopx2:
- moveb #0x55, %a1@+
- dbra %d0,loopx2
- dbra %d1,loopy2
-#endif
L(test_notmac):
#endif /* CONFIG_MAC */
@@ -901,15 +872,14 @@ L(nothp):
*/
#ifdef CONFIG_MAC
is_not_mac(L(nocon))
-#ifdef CONSOLE
+# ifdef CONSOLE_DEBUG
console_init
-#ifdef CONSOLE_PENGUIN
+# ifdef CONFIG_LOGO
console_put_penguin
-#endif /* CONSOLE_PENGUIN */
- console_put_stats
-#endif /* CONSOLE */
+# endif /* CONFIG_LOGO */
+# endif /* CONSOLE_DEBUG */
L(nocon):
-#endif /* CONFIG_MAC */
+#endif /* CONFIG_MAC */
putc '\n'
@@ -938,10 +908,22 @@ L(nocon):
*
* This block of code does what's necessary to map in the various kinds
* of machines for execution of Linux.
- * First map the first 4 MB of kernel code & data
+ * First map the first 4, 8, or 16 MB of kernel code & data
*/
- mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),#4*1024*1024,\
+ get_bi_record BI_MEMCHUNK
+ movel %a0@(4),%d0
+ movel #16*1024*1024,%d1
+ cmpl %d0,%d1
+ jls 1f
+ lsrl #1,%d1
+ cmpl %d0,%d1
+ jls 1f
+ lsrl #1,%d1
+1:
+ lea %pc@(m68k_init_mapped_size),%a0
+ movel %d1,%a0@
+ mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),%d1,\
%pc@(m68k_supervisor_cachemode)
putc 'C'
@@ -1412,15 +1394,13 @@ L(mmu_fixup_done):
andl L(mac_videobase),%d0
addl #VIDEOMEMBASE,%d0
movel %d0,L(mac_videobase)
-#if defined(CONSOLE)
+#ifdef CONSOLE_DEBUG
movel %pc@(L(phys_kernel_start)),%d0
subl #PAGE_OFFSET,%d0
subl %d0,L(console_font)
subl %d0,L(console_font_data)
#endif
-#ifdef SERIAL_DEBUG
orl #0x50000000,L(mac_sccbase)
-#endif
1:
#endif
@@ -1532,7 +1512,7 @@ L(cache_done):
/*
* Find a tag record in the bootinfo structure
- * The bootinfo structure is located right after the kernel bss
+ * The bootinfo structure is located right after the kernel
* Returns: d0: size (-1 if not found)
* a0: data pointer (end-of-records if not found)
*/
@@ -2750,13 +2730,16 @@ func_return get_new_page
*/
#ifdef CONFIG_MAC
+/* You may define either or both of these. */
+#define MAC_USE_SCC_A /* Modem port */
+#define MAC_USE_SCC_B /* Printer port */
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
+/* Initialisation table for SCC with 3.6864 MHz PCLK */
L(scc_initable_mac):
- .byte 9,12 /* Reset */
.byte 4,0x44 /* x16, 1 stopbit, no parity */
.byte 3,0xc0 /* receiver: 8 bpc */
.byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .byte 9,0 /* no interrupts */
.byte 10,0 /* NRZ */
.byte 11,0x50 /* use baud rate generator */
.byte 12,1,13,0 /* 38400 baud */
@@ -2766,6 +2749,7 @@ L(scc_initable_mac):
.byte -1
.even
#endif
+#endif /* CONFIG_MAC */
#ifdef CONFIG_ATARI
/* #define USE_PRINTER */
@@ -2774,14 +2758,12 @@ L(scc_initable_mac):
#define USE_MFP
#if defined(USE_SCC_A) || defined(USE_SCC_B)
-#define USE_SCC
-/* Initialisation table for SCC */
-L(scc_initable):
- .byte 9,12 /* Reset */
+/* Initialisation table for SCC with 7.9872 MHz PCLK */
+/* PCLK == 8.0539 gives baud == 9680.1 */
+L(scc_initable_atari):
.byte 4,0x44 /* x16, 1 stopbit, no parity */
.byte 3,0xc0 /* receiver: 8 bpc */
.byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */
- .byte 9,0 /* no interrupts */
.byte 10,0 /* NRZ */
.byte 11,0x50 /* use baud rate generator */
.byte 12,24,13,0 /* 9600 baud */
@@ -2830,7 +2812,7 @@ LMFP_UDR = 0xfffa2f
*/
/*
- * Initialize serial port hardware for 9600/8/1
+ * Initialize serial port hardware
*/
func_start serial_init,%d0/%d1/%a0/%a1
/*
@@ -2840,7 +2822,7 @@ func_start serial_init,%d0/%d1/%a0/%a1
* d0 = boot info offset
* CONFIG_ATARI
* a0 = address of SCC
- * a1 = Liobase address/address of scc_initable
+ * a1 = Liobase address/address of scc_initable_atari
* d0 = init data for serial port
* CONFIG_MAC
* a0 = address of SCC
@@ -2861,6 +2843,7 @@ func_start serial_init,%d0/%d1/%a0/%a1
| movew #61,CUSTOMBASE+C_SERPER-ZTWOBASE
1:
#endif
+
#ifdef CONFIG_ATARI
is_not_atari(4f)
movel %pc@(L(iobase)),%a1
@@ -2875,9 +2858,21 @@ func_start serial_init,%d0/%d1/%a0/%a1
moveb %a1@(LPSG_READ),%d0
bset #5,%d0
moveb %d0,%a1@(LPSG_WRITE)
-#elif defined(USE_SCC)
+#elif defined(USE_SCC_A) || defined(USE_SCC_B)
lea %a1@(LSCC_CTRL),%a0
- lea %pc@(L(scc_initable)),%a1
+ /* Reset SCC register pointer */
+ moveb %a0@,%d0
+ /* Reset SCC device: write register pointer then register value */
+ moveb #9,%a0@
+ moveb #0xc0,%a0@
+ /* Wait for 5 PCLK cycles, which is about 63 CPU cycles */
+ /* 5 / 7.9872 MHz = approx. 0.63 us = 63 / 100 MHz */
+ movel #32,%d0
+2:
+ subq #1,%d0
+ jne 2b
+ /* Initialize channel */
+ lea %pc@(L(scc_initable_atari)),%a1
2: moveb %a1@+,%d0
jmi 3f
moveb %d0,%a0@
@@ -2895,22 +2890,29 @@ func_start serial_init,%d0/%d1/%a0/%a1
jra L(serial_init_done)
4:
#endif
+
#ifdef CONFIG_MAC
is_not_mac(L(serial_init_not_mac))
-
-#ifdef SERIAL_DEBUG
-/* You may define either or both of these. */
-#define MAC_USE_SCC_A /* Modem port */
-#define MAC_USE_SCC_B /* Printer port */
-
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
#define mac_scc_cha_b_ctrl_offset 0x0
#define mac_scc_cha_a_ctrl_offset 0x2
#define mac_scc_cha_b_data_offset 0x4
#define mac_scc_cha_a_data_offset 0x6
-
+ movel %pc@(L(mac_sccbase)),%a0
+ /* Reset SCC register pointer */
+ moveb %a0@(mac_scc_cha_a_ctrl_offset),%d0
+ /* Reset SCC device: write register pointer then register value */
+ moveb #9,%a0@(mac_scc_cha_a_ctrl_offset)
+ moveb #0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
+ /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
+ /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
+ movel #35,%d0
+5:
+ subq #1,%d0
+ jne 5b
+#endif
#ifdef MAC_USE_SCC_A
/* Initialize channel A */
- movel %pc@(L(mac_sccbase)),%a0
lea %pc@(L(scc_initable_mac)),%a1
5: moveb %a1@+,%d0
jmi 6f
@@ -2919,12 +2921,8 @@ func_start serial_init,%d0/%d1/%a0/%a1
jra 5b
6:
#endif /* MAC_USE_SCC_A */
-
#ifdef MAC_USE_SCC_B
/* Initialize channel B */
-#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */
- movel %pc@(L(mac_sccbase)),%a0
-#endif /* MAC_USE_SCC_A */
lea %pc@(L(scc_initable_mac)),%a1
7: moveb %a1@+,%d0
jmi 8f
@@ -2933,8 +2931,6 @@ func_start serial_init,%d0/%d1/%a0/%a1
jra 7b
8:
#endif /* MAC_USE_SCC_B */
-#endif /* SERIAL_DEBUG */
-
jra L(serial_init_done)
L(serial_init_not_mac):
#endif /* CONFIG_MAC */
@@ -2964,6 +2960,15 @@ L(serial_init_not_mac):
2:
#endif
+#ifdef CONFIG_MVME16x
+ is_not_mvme16x(L(serial_init_not_mvme16x))
+ moveb #0x10,M167_PCSCCMICR
+ moveb #0x10,M167_PCSCCTICR
+ moveb #0x10,M167_PCSCCRICR
+ jra L(serial_init_done)
+L(serial_init_not_mvme16x):
+#endif
+
#ifdef CONFIG_APOLLO
/* We count on the PROM initializing SIO1 */
#endif
@@ -3003,27 +3008,19 @@ func_start serial_putc,%d0/%d1/%a0/%a1
#ifdef CONFIG_MAC
is_not_mac(5f)
-
-#ifdef SERIAL_DEBUG
-
-#ifdef MAC_USE_SCC_A
+#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
movel %pc@(L(mac_sccbase)),%a1
+#endif
+#ifdef MAC_USE_SCC_A
3: btst #2,%a1@(mac_scc_cha_a_ctrl_offset)
jeq 3b
moveb %d0,%a1@(mac_scc_cha_a_data_offset)
#endif /* MAC_USE_SCC_A */
-
#ifdef MAC_USE_SCC_B
-#ifndef MAC_USE_SCC_A /* Load mac_sccbase only if needed */
- movel %pc@(L(mac_sccbase)),%a1
-#endif /* MAC_USE_SCC_A */
4: btst #2,%a1@(mac_scc_cha_b_ctrl_offset)
jeq 4b
moveb %d0,%a1@(mac_scc_cha_b_data_offset)
#endif /* MAC_USE_SCC_B */
-
-#endif /* SERIAL_DEBUG */
-
jra L(serial_putc_done)
5:
#endif /* CONFIG_MAC */
@@ -3044,7 +3041,7 @@ func_start serial_putc,%d0/%d1/%a0/%a1
nop
bset #5,%d0
moveb %d0,%a1@(LPSG_WRITE)
-#elif defined(USE_SCC)
+#elif defined(USE_SCC_A) || defined(USE_SCC_B)
3: btst #2,%a1@(LSCC_CTRL)
jeq 3b
moveb %d0,%a1@(LSCC_DATA)
@@ -3200,7 +3197,7 @@ func_start puts,%d0/%a0
movel ARG1,%a0
jra 2f
1:
-#ifdef CONSOLE
+#ifdef CONSOLE_DEBUG
console_putc %d0
#endif
#ifdef SERIAL_DEBUG
@@ -3229,7 +3226,7 @@ func_start putn,%d0-%d2
jls 2f
addb #'A'-('9'+1),%d2
2:
-#ifdef CONSOLE
+#ifdef CONSOLE_DEBUG
console_putc %d2
#endif
#ifdef SERIAL_DEBUG
@@ -3239,21 +3236,19 @@ func_start putn,%d0-%d2
func_return putn
-#ifdef CONFIG_MAC
+#ifdef CONFIG_EARLY_PRINTK
/*
- * mac_early_print
- *
* This routine takes its parameters on the stack. It then
* turns around and calls the internal routines. This routine
* is used by the boot console.
*
* The calling parameters are:
- * void mac_early_print(const char *str, unsigned length);
+ * void debug_cons_nputs(const char *str, unsigned length)
*
* This routine does NOT understand variable arguments only
* simple strings!
*/
-ENTRY(mac_early_print)
+ENTRY(debug_cons_nputs)
moveml %d0/%d1/%a0,%sp@-
movew %sr,%sp@-
ori #0x0700,%sr
@@ -3261,7 +3256,7 @@ ENTRY(mac_early_print)
movel %sp@(22),%d1 /* fetch parameter */
jra 2f
1:
-#ifdef CONSOLE
+#ifdef CONSOLE_DEBUG
console_putc %d0
#endif
#ifdef SERIAL_DEBUG
@@ -3275,7 +3270,7 @@ ENTRY(mac_early_print)
movew %sp@+,%sr
moveml %sp@+,%d0/%d1/%a0
rts
-#endif /* CONFIG_MAC */
+#endif /* CONFIG_EARLY_PRINTK */
#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
func_start set_leds,%d0/%a0
@@ -3297,7 +3292,7 @@ func_start set_leds,%d0/%a0
func_return set_leds
#endif
-#ifdef CONSOLE
+#ifdef CONSOLE_DEBUG
/*
* For continuity, see the data alignment
* to which this structure is tied.
@@ -3307,14 +3302,13 @@ func_return set_leds
#define Lconsole_struct_num_columns 8
#define Lconsole_struct_num_rows 12
#define Lconsole_struct_left_edge 16
-#define Lconsole_struct_penguin_putc 20
func_start console_init,%a0-%a4/%d0-%d7
/*
* Some of the register usage that follows
* a0 = pointer to boot_info
* a1 = pointer to screen
- * a2 = pointer to Lconsole_globals
+ * a2 = pointer to console_globals
* d3 = pixel width of screen
* d4 = pixel height of screen
* (d3,d4) ~= (x,y) of a point just below
@@ -3402,44 +3396,7 @@ L(console_clear_loop):
1:
func_return console_init
-func_start console_put_stats,%a0/%d7
- /*
- * Some of the register usage that follows
- * a0 = pointer to boot_info
- * d7 = value of boot_info fields
- */
- puts "\nMacLinux\n"
-
-#ifdef SERIAL_DEBUG
- puts "\n vidaddr:"
- putn %pc@(L(mac_videobase)) /* video addr. */
-
- puts "\n _stext:"
- lea %pc@(_stext),%a0
- putn %a0
-
- puts "\nbootinfo:"
- lea %pc@(_end),%a0
- putn %a0
-
- puts "\n cpuid:"
- putn %pc@(L(cputype))
-
-# ifdef CONFIG_MAC
- puts "\n sccbase:"
- putn %pc@(L(mac_sccbase))
-# endif
-# ifdef MMU_PRINT
- putc '\n'
- jbsr mmu_print_machine_cpu_types
-# endif
-#endif /* SERIAL_DEBUG */
-
- putc '\n'
-
-func_return console_put_stats
-
-#ifdef CONSOLE_PENGUIN
+#ifdef CONFIG_LOGO
func_start console_put_penguin,%a0-%a1/%d0-%d7
/*
* Get 'that_penguin' onto the screen in the upper right corner
@@ -3780,44 +3737,15 @@ L(white_16):
L(console_plot_pixel_exit):
func_return console_plot_pixel
-#endif /* CONSOLE */
-
-#if 0
-/*
- * This is some old code lying around. I don't believe
- * it's used or important anymore. My guess is it contributed
- * to getting to this point, but it's done for now.
- * It was still in the 2.1.77 head.S, so it's still here.
- * (And still not used!)
- */
-L(showtest):
- moveml %a0/%d7,%sp@-
- puts "A="
- putn %a1
+#endif /* CONSOLE_DEBUG */
- .long 0xf0119f15 | ptestr #5,%a1@,#7,%a0
-
- puts "DA="
- putn %a0
-
- puts "D="
- putn %a0@
-
- puts "S="
- lea %pc@(L(mmu)),%a0
- .long 0xf0106200 | pmove %psr,%a0@
- clrl %d7
- movew %a0@,%d7
- putn %d7
-
- putc '\n'
- moveml %sp@+,%a0/%d7
- rts
-#endif /* 0 */
__INITDATA
.align 4
+m68k_init_mapped_size:
+ .long 0
+
#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
L(custom):
@@ -3825,19 +3753,18 @@ L(iobase):
.long 0
#endif
-#if defined(CONSOLE)
+#ifdef CONSOLE_DEBUG
L(console_globals):
.long 0 /* cursor column */
.long 0 /* cursor row */
.long 0 /* max num columns */
.long 0 /* max num rows */
.long 0 /* left edge */
- .long 0 /* mac putc */
L(console_font):
.long 0 /* pointer to console font (struct font_desc) */
L(console_font_data):
.long 0 /* pointer to console font data */
-#endif /* CONSOLE */
+#endif /* CONSOLE_DEBUG */
#if defined(MMU_PRINT)
L(mmu_print_data):
@@ -3877,7 +3804,9 @@ M167_CYIER = 0xfff45011
M167_CYLICR = 0xfff45026
M167_CYTEOIR = 0xfff45085
M167_CYTDR = 0xfff450f8
+M167_PCSCCMICR = 0xfff4201d
M167_PCSCCTICR = 0xfff4201e
+M167_PCSCCRICR = 0xfff4201f
M167_PCTPIACKR = 0xfff42025
#endif
@@ -3887,8 +3816,6 @@ BVME_SCC_DATA_A = 0xffb0000f
#endif
#if defined(CONFIG_MAC)
-L(mac_booter_data):
- .long 0
L(mac_videobase):
.long 0
L(mac_videodepth):
@@ -3897,10 +3824,8 @@ L(mac_dimensions):
.long 0
L(mac_rowbytes):
.long 0
-#ifdef SERIAL_DEBUG
L(mac_sccbase):
.long 0
-#endif
#endif /* CONFIG_MAC */
#if defined (CONFIG_APOLLO)
diff --git a/arch/m68k/kernel/init_task.c b/arch/m68k/kernel/init_task.c
deleted file mode 100644
index c744cfc6bfa..00000000000
--- a/arch/m68k/kernel/init_task.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/init_task.c
- */
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/init_task.h>
-#include <linux/fs.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-
-static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
-static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
-/*
- * Initial task structure.
- *
- * All other task structs will be allocated on slabs in fork.c
- */
-struct task_struct init_task = INIT_TASK(init_task);
-
-EXPORT_SYMBOL(init_task);
-
-/*
- * Initial thread structure.
- *
- * We need to make sure that this is THREAD size aligned due to the
- * way process stacks are handled. This is done by having a special
- * "init_task" linker map entry..
- */
-union thread_union init_thread_union __init_task_data =
- { INIT_THREAD_INFO(init_task) };
-
diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
index 74fefac0089..5b8d66fbf38 100644
--- a/arch/m68k/kernel/ints.c
+++ b/arch/m68k/kernel/ints.c
@@ -10,12 +10,11 @@
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/init.h>
+#include <linux/irq.h>
#include <asm/setup.h>
-#include <asm/system.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/page.h>
@@ -59,12 +58,6 @@ void __init init_IRQ(void)
{
int i;
- /* assembly irq entry code relies on this... */
- if (HARDIRQ_MASK != 0x00ff0000) {
- extern void hardirq_mask_is_broken(void);
- hardirq_mask_is_broken();
- }
-
for (i = IRQ_AUTO_1; i <= IRQ_AUTO_7; i++)
irq_set_chip_and_handler(i, &auto_irq_chip, handle_simple_irq);
@@ -102,7 +95,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt)
BUG_ON(IRQ_USER + cnt > NR_IRQS);
m68k_first_user_vec = vec;
for (i = 0; i < cnt; i++)
- irq_set_chip(IRQ_USER + i, &user_irq_chip);
+ irq_set_chip_and_handler(i, &user_irq_chip, handle_simple_irq);
*user_irqvec_fixup = vec - IRQ_USER;
flush_icache();
}
diff --git a/arch/m68k/kernel/irq.c b/arch/m68k/kernel/irq.c
index c73988cfa90..9ab4f550342 100644
--- a/arch/m68k/kernel/irq.c
+++ b/arch/m68k/kernel/irq.c
@@ -15,7 +15,6 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
-#include <asm/system.h>
#include <asm/traps.h>
asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
diff --git a/arch/m68k/kernel/machine_kexec.c b/arch/m68k/kernel/machine_kexec.c
new file mode 100644
index 00000000000..d4affc917d9
--- /dev/null
+++ b/arch/m68k/kernel/machine_kexec.c
@@ -0,0 +1,58 @@
+/*
+ * machine_kexec.c - handle transition of Linux booting another kernel
+ */
+#include <linux/compiler.h>
+#include <linux/kexec.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+extern const unsigned char relocate_new_kernel[];
+extern const size_t relocate_new_kernel_size;
+
+int machine_kexec_prepare(struct kimage *kimage)
+{
+ return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+}
+
+void machine_shutdown(void)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+typedef void (*relocate_kernel_t)(unsigned long ptr,
+ unsigned long start,
+ unsigned long cpu_mmu_flags) __noreturn;
+
+void machine_kexec(struct kimage *image)
+{
+ void *reboot_code_buffer;
+ unsigned long cpu_mmu_flags;
+
+ reboot_code_buffer = page_address(image->control_code_page);
+
+ memcpy(reboot_code_buffer, relocate_new_kernel,
+ relocate_new_kernel_size);
+
+ /*
+ * we do not want to be bothered.
+ */
+ local_irq_disable();
+
+ pr_info("Will call new kernel at 0x%08lx. Bye...\n", image->start);
+ __flush_cache_all();
+ cpu_mmu_flags = m68k_cputype | m68k_mmutype << 8;
+ ((relocate_kernel_t) reboot_code_buffer)(image->head & PAGE_MASK,
+ image->start,
+ cpu_mmu_flags);
+}
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c
index 34849c4c6e3..eb46fd6038c 100644
--- a/arch/m68k/kernel/module.c
+++ b/arch/m68k/kernel/module.c
@@ -47,7 +47,7 @@ int apply_relocate(Elf32_Shdr *sechdrs,
*location += sym->st_value;
break;
case R_68K_PC32:
- /* Add the value, subtract its postition */
+ /* Add the value, subtract its position */
*location += sym->st_value - (uint32_t)location;
break;
default:
@@ -87,7 +87,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
*location = rel[i].r_addend + sym->st_value;
break;
case R_68K_PC32:
- /* Add the value, subtract its postition */
+ /* Add the value, subtract its position */
*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
break;
default:
diff --git a/arch/m68k/kernel/pcibios.c b/arch/m68k/kernel/pcibios.c
new file mode 100644
index 00000000000..931a31ff59d
--- /dev/null
+++ b/arch/m68k/kernel/pcibios.c
@@ -0,0 +1,104 @@
+/*
+ * pci.c -- basic PCI support code
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * (C) Copyright 2011, Greg Ungerer <gerg@uclinux.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+
+/*
+ * From arch/i386/kernel/pci-i386.c:
+ *
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might be mirrored at 0x0100-0x03ff..
+ */
+resource_size_t pcibios_align_resource(void *data, const struct resource *res,
+ resource_size_t size, resource_size_t align)
+{
+ resource_size_t start = res->start;
+
+ if ((res->flags & IORESOURCE_IO) && (start & 0x300))
+ start = (start + 0x3ff) & ~0x3ff;
+
+ start = (start + align - 1) & ~(align - 1);
+
+ return start;
+}
+
+/*
+ * This is taken from the ARM code for this.
+ */
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+ struct resource *r;
+ u16 cmd, newcmd;
+ int idx;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ newcmd = cmd;
+
+ for (idx = 0; idx < 6; idx++) {
+ /* Only set up the requested stuff */
+ if (!(mask & (1 << idx)))
+ continue;
+
+ r = dev->resource + idx;
+ if (!r->start && r->end) {
+ pr_err(KERN_ERR "PCI: Device %s not available because of resource collisions\n",
+ pci_name(dev));
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ newcmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ newcmd |= PCI_COMMAND_MEMORY;
+ }
+
+ /*
+ * Bridges (eg, cardbus bridges) need to be fully enabled
+ */
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
+ newcmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
+
+
+ if (newcmd != cmd) {
+ pr_info("PCI: enabling device %s (0x%04x -> 0x%04x)\n",
+ pci_name(dev), cmd, newcmd);
+ pci_write_config_word(dev, PCI_COMMAND, newcmd);
+ }
+ return 0;
+}
+
+void pcibios_fixup_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
+ }
+}
+
+char *pcibios_setup(char *str)
+{
+ return str;
+}
+
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index 6cf4bd6e34f..c55ff719fa7 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -1,5 +1,277 @@
-#ifdef CONFIG_MMU
-#include "process_mm.c"
+/*
+ * linux/arch/m68k/kernel/process.c
+ *
+ * Copyright (C) 1995 Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/reboot.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+#include <linux/rcupdate.h>
+
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/machdep.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+
+
+asmlinkage void ret_from_fork(void);
+asmlinkage void ret_from_kernel_thread(void);
+
+
+/*
+ * Return saved PC from a blocked thread
+ */
+unsigned long thread_saved_pc(struct task_struct *tsk)
+{
+ struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
+ /* Check whether the thread is blocked in resume() */
+ if (in_sched_functions(sw->retpc))
+ return ((unsigned long *)sw->a6)[1];
+ else
+ return sw->retpc;
+}
+
+void arch_cpu_idle(void)
+{
+#if defined(MACH_ATARI_ONLY)
+ /* block out HSYNC on the atari (falcon) */
+ __asm__("stop #0x2200" : : : "cc");
#else
-#include "process_no.c"
+ __asm__("stop #0x2000" : : : "cc");
#endif
+}
+
+void machine_restart(char * __unused)
+{
+ if (mach_reset)
+ mach_reset();
+ for (;;);
+}
+
+void machine_halt(void)
+{
+ if (mach_halt)
+ mach_halt();
+ for (;;);
+}
+
+void machine_power_off(void)
+{
+ if (mach_power_off)
+ mach_power_off();
+ for (;;);
+}
+
+void (*pm_power_off)(void) = machine_power_off;
+EXPORT_SYMBOL(pm_power_off);
+
+void show_regs(struct pt_regs * regs)
+{
+ printk("\n");
+ printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
+ regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
+ printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
+ regs->orig_d0, regs->d0, regs->a2, regs->a1);
+ printk("A0: %08lx D5: %08lx D4: %08lx\n",
+ regs->a0, regs->d5, regs->d4);
+ printk("D3: %08lx D2: %08lx D1: %08lx\n",
+ regs->d3, regs->d2, regs->d1);
+ if (!(regs->sr & PS_S))
+ printk("USP: %08lx\n", rdusp());
+}
+
+void flush_thread(void)
+{
+ current->thread.fs = __USER_DS;
+#ifdef CONFIG_FPU
+ if (!FPU_IS_EMU) {
+ unsigned long zero = 0;
+ asm volatile("frestore %0": :"m" (zero));
+ }
+#endif
+}
+
+/*
+ * Why not generic sys_clone, you ask? m68k passes all arguments on stack.
+ * And we need all registers saved, which means a bunch of stuff pushed
+ * on top of pt_regs, which means that sys_clone() arguments would be
+ * buried. We could, of course, copy them, but it's too costly for no
+ * good reason - generic clone() would have to copy them *again* for
+ * do_fork() anyway. So in this case it's actually better to pass pt_regs *
+ * and extract arguments for do_fork() from there. Eventually we might
+ * go for calling do_fork() directly from the wrapper, but only after we
+ * are finished with do_fork() prototype conversion.
+ */
+asmlinkage int m68k_clone(struct pt_regs *regs)
+{
+ /* regs will be equal to current_pt_regs() */
+ return do_fork(regs->d1, regs->d2, 0,
+ (int __user *)regs->d3, (int __user *)regs->d4);
+}
+
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+ unsigned long arg, struct task_struct *p)
+{
+ struct fork_frame {
+ struct switch_stack sw;
+ struct pt_regs regs;
+ } *frame;
+
+ frame = (struct fork_frame *) (task_stack_page(p) + THREAD_SIZE) - 1;
+
+ p->thread.ksp = (unsigned long)frame;
+ p->thread.esp0 = (unsigned long)&frame->regs;
+
+ /*
+ * Must save the current SFC/DFC value, NOT the value when
+ * the parent was last descheduled - RGH 10-08-96
+ */
+ p->thread.fs = get_fs().seg;
+
+ if (unlikely(p->flags & PF_KTHREAD)) {
+ /* kernel thread */
+ memset(frame, 0, sizeof(struct fork_frame));
+ frame->regs.sr = PS_S;
+ frame->sw.a3 = usp; /* function */
+ frame->sw.d7 = arg;
+ frame->sw.retpc = (unsigned long)ret_from_kernel_thread;
+ p->thread.usp = 0;
+ return 0;
+ }
+ memcpy(frame, container_of(current_pt_regs(), struct fork_frame, regs),
+ sizeof(struct fork_frame));
+ frame->regs.d0 = 0;
+ frame->sw.retpc = (unsigned long)ret_from_fork;
+ p->thread.usp = usp ?: rdusp();
+
+ if (clone_flags & CLONE_SETTLS)
+ task_thread_info(p)->tp_value = frame->regs.d5;
+
+#ifdef CONFIG_FPU
+ if (!FPU_IS_EMU) {
+ /* Copy the current fpu state */
+ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
+
+ if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
+ if (CPU_IS_COLDFIRE) {
+ asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
+ "fmovel %/fpiar,%1\n\t"
+ "fmovel %/fpcr,%2\n\t"
+ "fmovel %/fpsr,%3"
+ :
+ : "m" (p->thread.fp[0]),
+ "m" (p->thread.fpcntl[0]),
+ "m" (p->thread.fpcntl[1]),
+ "m" (p->thread.fpcntl[2])
+ : "memory");
+ } else {
+ asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
+ "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
+ :
+ : "m" (p->thread.fp[0]),
+ "m" (p->thread.fpcntl[0])
+ : "memory");
+ }
+ }
+
+ /* Restore the state in case the fpu was busy */
+ asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
+ }
+#endif /* CONFIG_FPU */
+
+ return 0;
+}
+
+/* Fill in the fpu structure for a core dump. */
+#ifdef CONFIG_FPU
+int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
+{
+ char fpustate[216];
+
+ if (FPU_IS_EMU) {
+ int i;
+
+ memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
+ memcpy(fpu->fpregs, current->thread.fp, 96);
+ /* Convert internal fpu reg representation
+ * into long double format
+ */
+ for (i = 0; i < 24; i += 3)
+ fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
+ ((fpu->fpregs[i] & 0x0000ffff) << 16);
+ return 1;
+ }
+
+ /* First dump the fpu context to avoid protocol violation. */
+ asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
+ if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
+ return 0;
+
+ if (CPU_IS_COLDFIRE) {
+ asm volatile ("fmovel %/fpiar,%0\n\t"
+ "fmovel %/fpcr,%1\n\t"
+ "fmovel %/fpsr,%2\n\t"
+ "fmovemd %/fp0-%/fp7,%3"
+ :
+ : "m" (fpu->fpcntl[0]),
+ "m" (fpu->fpcntl[1]),
+ "m" (fpu->fpcntl[2]),
+ "m" (fpu->fpregs[0])
+ : "memory");
+ } else {
+ asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
+ :
+ : "m" (fpu->fpcntl[0])
+ : "memory");
+ asm volatile ("fmovemx %/fp0-%/fp7,%0"
+ :
+ : "m" (fpu->fpregs[0])
+ : "memory");
+ }
+
+ return 1;
+}
+EXPORT_SYMBOL(dump_fpu);
+#endif /* CONFIG_FPU */
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)task_stack_page(p);
+ fp = ((struct switch_stack *)p->thread.ksp)->a6;
+ do {
+ if (fp < stack_page+sizeof(struct thread_info) ||
+ fp >= 8184+stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ if (!in_sched_functions(pc))
+ return pc;
+ fp = *(unsigned long *) fp;
+ } while (count++ < 16);
+ return 0;
+}
diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c
deleted file mode 100644
index 099283ee1a8..00000000000
--- a/arch/m68k/kernel/process_mm.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * linux/arch/m68k/kernel/process.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/reboot.h>
-#include <linux/init_task.h>
-#include <linux/mqueue.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#include <asm/pgtable.h>
-
-
-asmlinkage void ret_from_fork(void);
-
-
-/*
- * Return saved PC from a blocked thread
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
- struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
- /* Check whether the thread is blocked in resume() */
- if (in_sched_functions(sw->retpc))
- return ((unsigned long *)sw->a6)[1];
- else
- return sw->retpc;
-}
-
-/*
- * The idle loop on an m68k..
- */
-static void default_idle(void)
-{
- if (!need_resched())
-#if defined(MACH_ATARI_ONLY)
- /* block out HSYNC on the atari (falcon) */
- __asm__("stop #0x2200" : : : "cc");
-#else
- __asm__("stop #0x2000" : : : "cc");
-#endif
-}
-
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
- /* endless idle loop with no priority at all */
- while (1) {
- while (!need_resched())
- idle();
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
-}
-
-void machine_restart(char * __unused)
-{
- if (mach_reset)
- mach_reset();
- for (;;);
-}
-
-void machine_halt(void)
-{
- if (mach_halt)
- mach_halt();
- for (;;);
-}
-
-void machine_power_off(void)
-{
- if (mach_power_off)
- mach_power_off();
- for (;;);
-}
-
-void (*pm_power_off)(void) = machine_power_off;
-EXPORT_SYMBOL(pm_power_off);
-
-void show_regs(struct pt_regs * regs)
-{
- printk("\n");
- printk("Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
- regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
- printk("ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
- regs->orig_d0, regs->d0, regs->a2, regs->a1);
- printk("A0: %08lx D5: %08lx D4: %08lx\n",
- regs->a0, regs->d5, regs->d4);
- printk("D3: %08lx D2: %08lx D1: %08lx\n",
- regs->d3, regs->d2, regs->d1);
- if (!(regs->sr & PS_S))
- printk("USP: %08lx\n", rdusp());
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- int pid;
- mm_segment_t fs;
-
- fs = get_fs();
- set_fs (KERNEL_DS);
-
- {
- register long retval __asm__ ("d0");
- register long clone_arg __asm__ ("d1") = flags | CLONE_VM | CLONE_UNTRACED;
-
- retval = __NR_clone;
- __asm__ __volatile__
- ("clrl %%d2\n\t"
- "trap #0\n\t" /* Linux/m68k system call */
- "tstl %0\n\t" /* child or parent */
- "jne 1f\n\t" /* parent - jump */
- "lea %%sp@(%c7),%6\n\t" /* reload current */
- "movel %6@,%6\n\t"
- "movel %3,%%sp@-\n\t" /* push argument */
- "jsr %4@\n\t" /* call fn */
- "movel %0,%%d1\n\t" /* pass exit value */
- "movel %2,%%d0\n\t" /* exit */
- "trap #0\n"
- "1:"
- : "+d" (retval)
- : "i" (__NR_clone), "i" (__NR_exit),
- "r" (arg), "a" (fn), "d" (clone_arg), "r" (current),
- "i" (-THREAD_SIZE)
- : "d2");
-
- pid = retval;
- }
-
- set_fs (fs);
- return pid;
-}
-EXPORT_SYMBOL(kernel_thread);
-
-void flush_thread(void)
-{
- unsigned long zero = 0;
-
- current->thread.fs = __USER_DS;
- if (!FPU_IS_EMU)
- asm volatile("frestore %0": :"m" (zero));
-}
-
-/*
- * "m68k_fork()".. By the time we get here, the
- * non-volatile registers have also been saved on the
- * stack. We do some ugly pointer stuff here.. (see
- * also copy_thread)
- */
-
-asmlinkage int m68k_fork(struct pt_regs *regs)
-{
- return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
-}
-
-asmlinkage int m68k_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0,
- NULL, NULL);
-}
-
-asmlinkage int m68k_clone(struct pt_regs *regs)
-{
- unsigned long clone_flags;
- unsigned long newsp;
- int __user *parent_tidptr, *child_tidptr;
-
- /* syscall2 puts clone_flags in d1 and usp in d2 */
- clone_flags = regs->d1;
- newsp = regs->d2;
- parent_tidptr = (int __user *)regs->d3;
- child_tidptr = (int __user *)regs->d4;
- if (!newsp)
- newsp = rdusp();
- return do_fork(clone_flags, newsp, regs, 0,
- parent_tidptr, child_tidptr);
-}
-
-int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long unused,
- struct task_struct * p, struct pt_regs * regs)
-{
- struct pt_regs * childregs;
- struct switch_stack * childstack, *stack;
- unsigned long *retp;
-
- childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-
- *childregs = *regs;
- childregs->d0 = 0;
-
- retp = ((unsigned long *) regs);
- stack = ((struct switch_stack *) retp) - 1;
-
- childstack = ((struct switch_stack *) childregs) - 1;
- *childstack = *stack;
- childstack->retpc = (unsigned long)ret_from_fork;
-
- p->thread.usp = usp;
- p->thread.ksp = (unsigned long)childstack;
-
- if (clone_flags & CLONE_SETTLS)
- task_thread_info(p)->tp_value = regs->d5;
-
- /*
- * Must save the current SFC/DFC value, NOT the value when
- * the parent was last descheduled - RGH 10-08-96
- */
- p->thread.fs = get_fs().seg;
-
- if (!FPU_IS_EMU) {
- /* Copy the current fpu state */
- asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
-
- if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
- if (CPU_IS_COLDFIRE) {
- asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
- "fmovel %/fpiar,%1\n\t"
- "fmovel %/fpcr,%2\n\t"
- "fmovel %/fpsr,%3"
- :
- : "m" (p->thread.fp[0]),
- "m" (p->thread.fpcntl[0]),
- "m" (p->thread.fpcntl[1]),
- "m" (p->thread.fpcntl[2])
- : "memory");
- } else {
- asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
- "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
- :
- : "m" (p->thread.fp[0]),
- "m" (p->thread.fpcntl[0])
- : "memory");
- }
- }
-
- /* Restore the state in case the fpu was busy */
- asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
- }
-
- return 0;
-}
-
-/* Fill in the fpu structure for a core dump. */
-
-int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
-{
- char fpustate[216];
-
- if (FPU_IS_EMU) {
- int i;
-
- memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
- memcpy(fpu->fpregs, current->thread.fp, 96);
- /* Convert internal fpu reg representation
- * into long double format
- */
- for (i = 0; i < 24; i += 3)
- fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
- ((fpu->fpregs[i] & 0x0000ffff) << 16);
- return 1;
- }
-
- /* First dump the fpu context to avoid protocol violation. */
- asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
- if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
- return 0;
-
- if (CPU_IS_COLDFIRE) {
- asm volatile ("fmovel %/fpiar,%0\n\t"
- "fmovel %/fpcr,%1\n\t"
- "fmovel %/fpsr,%2\n\t"
- "fmovemd %/fp0-%/fp7,%3"
- :
- : "m" (fpu->fpcntl[0]),
- "m" (fpu->fpcntl[1]),
- "m" (fpu->fpcntl[2]),
- "m" (fpu->fpregs[0])
- : "memory");
- } else {
- asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
- :
- : "m" (fpu->fpcntl[0])
- : "memory");
- asm volatile ("fmovemx %/fp0-%/fp7,%0"
- :
- : "m" (fpu->fpregs[0])
- : "memory");
- }
-
- return 1;
-}
-EXPORT_SYMBOL(dump_fpu);
-
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char __user *name,
- const char __user *const __user *argv,
- const char __user *const __user *envp)
-{
- int error;
- char * filename;
- struct pt_regs *regs = (struct pt_regs *) &name;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
-unsigned long get_wchan(struct task_struct *p)
-{
- unsigned long fp, pc;
- unsigned long stack_page;
- int count = 0;
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
-
- stack_page = (unsigned long)task_stack_page(p);
- fp = ((struct switch_stack *)p->thread.ksp)->a6;
- do {
- if (fp < stack_page+sizeof(struct thread_info) ||
- fp >= 8184+stack_page)
- return 0;
- pc = ((unsigned long *)fp)[1];
- if (!in_sched_functions(pc))
- return pc;
- fp = *(unsigned long *) fp;
- } while (count++ < 16);
- return 0;
-}
diff --git a/arch/m68k/kernel/process_no.c b/arch/m68k/kernel/process_no.c
deleted file mode 100644
index 5e1078cabe0..00000000000
--- a/arch/m68k/kernel/process_no.c
+++ /dev/null
@@ -1,406 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/process.c
- *
- * Copyright (C) 1995 Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- *
- * uClinux changes
- * Copyright (C) 2000-2002, David McCullough <davidm@snapgear.com>
- */
-
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/interrupt.h>
-#include <linux/reboot.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/traps.h>
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#include <asm/pgtable.h>
-
-asmlinkage void ret_from_fork(void);
-
-/*
- * The following aren't currently used.
- */
-void (*pm_idle)(void);
-EXPORT_SYMBOL(pm_idle);
-
-void (*pm_power_off)(void);
-EXPORT_SYMBOL(pm_power_off);
-
-/*
- * The idle loop on an m68knommu..
- */
-static void default_idle(void)
-{
- local_irq_disable();
- while (!need_resched()) {
- /* This stop will re-enable interrupts */
- __asm__("stop #0x2000" : : : "cc");
- local_irq_disable();
- }
- local_irq_enable();
-}
-
-void (*idle)(void) = default_idle;
-
-/*
- * The idle thread. There's no useful work to be
- * done, so just try to conserve power and have a
- * low exit latency (ie sit in a loop waiting for
- * somebody to say that they'd like to reschedule)
- */
-void cpu_idle(void)
-{
- /* endless idle loop with no priority at all */
- while (1) {
- idle();
- preempt_enable_no_resched();
- schedule();
- preempt_disable();
- }
-}
-
-void machine_restart(char * __unused)
-{
- if (mach_reset)
- mach_reset();
- for (;;);
-}
-
-void machine_halt(void)
-{
- if (mach_halt)
- mach_halt();
- for (;;);
-}
-
-void machine_power_off(void)
-{
- if (mach_power_off)
- mach_power_off();
- for (;;);
-}
-
-void show_regs(struct pt_regs * regs)
-{
- printk(KERN_NOTICE "\n");
- printk(KERN_NOTICE "Format %02x Vector: %04x PC: %08lx Status: %04x %s\n",
- regs->format, regs->vector, regs->pc, regs->sr, print_tainted());
- printk(KERN_NOTICE "ORIG_D0: %08lx D0: %08lx A2: %08lx A1: %08lx\n",
- regs->orig_d0, regs->d0, regs->a2, regs->a1);
- printk(KERN_NOTICE "A0: %08lx D5: %08lx D4: %08lx\n",
- regs->a0, regs->d5, regs->d4);
- printk(KERN_NOTICE "D3: %08lx D2: %08lx D1: %08lx\n",
- regs->d3, regs->d2, regs->d1);
- if (!(regs->sr & PS_S))
- printk(KERN_NOTICE "USP: %08lx\n", rdusp());
-}
-
-/*
- * Create a kernel thread
- */
-int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
- int retval;
- long clone_arg = flags | CLONE_VM;
- mm_segment_t fs;
-
- fs = get_fs();
- set_fs(KERNEL_DS);
-
- __asm__ __volatile__ (
- "movel %%sp, %%d2\n\t"
- "movel %5, %%d1\n\t"
- "movel %1, %%d0\n\t"
- "trap #0\n\t"
- "cmpl %%sp, %%d2\n\t"
- "jeq 1f\n\t"
- "movel %3, %%sp@-\n\t"
- "jsr %4@\n\t"
- "movel %2, %%d0\n\t"
- "trap #0\n"
- "1:\n\t"
- "movel %%d0, %0\n"
- : "=d" (retval)
- : "i" (__NR_clone),
- "i" (__NR_exit),
- "a" (arg),
- "a" (fn),
- "a" (clone_arg)
- : "cc", "%d0", "%d1", "%d2");
-
- set_fs(fs);
- return retval;
-}
-EXPORT_SYMBOL(kernel_thread);
-
-void flush_thread(void)
-{
-#ifdef CONFIG_FPU
- unsigned long zero = 0;
-#endif
-
- current->thread.fs = __USER_DS;
-#ifdef CONFIG_FPU
- if (!FPU_IS_EMU)
- asm volatile (".chip 68k/68881\n\t"
- "frestore %0\n\t"
- ".chip 68k" : : "m" (zero));
-#endif
-}
-
-/*
- * "m68k_fork()".. By the time we get here, the
- * non-volatile registers have also been saved on the
- * stack. We do some ugly pointer stuff here.. (see
- * also copy_thread)
- */
-
-asmlinkage int m68k_fork(struct pt_regs *regs)
-{
- /* fork almost works, enough to trick you into looking elsewhere :-( */
- return(-EINVAL);
-}
-
-asmlinkage int m68k_vfork(struct pt_regs *regs)
-{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0, NULL, NULL);
-}
-
-asmlinkage int m68k_clone(struct pt_regs *regs)
-{
- unsigned long clone_flags;
- unsigned long newsp;
-
- /* syscall2 puts clone_flags in d1 and usp in d2 */
- clone_flags = regs->d1;
- newsp = regs->d2;
- if (!newsp)
- newsp = rdusp();
- return do_fork(clone_flags, newsp, regs, 0, NULL, NULL);
-}
-
-int copy_thread(unsigned long clone_flags,
- unsigned long usp, unsigned long topstk,
- struct task_struct * p, struct pt_regs * regs)
-{
- struct pt_regs * childregs;
- struct switch_stack * childstack, *stack;
- unsigned long *retp;
-
- childregs = (struct pt_regs *) (task_stack_page(p) + THREAD_SIZE) - 1;
-
- *childregs = *regs;
- childregs->d0 = 0;
-
- retp = ((unsigned long *) regs);
- stack = ((struct switch_stack *) retp) - 1;
-
- childstack = ((struct switch_stack *) childregs) - 1;
- *childstack = *stack;
- childstack->retpc = (unsigned long)ret_from_fork;
-
- p->thread.usp = usp;
- p->thread.ksp = (unsigned long)childstack;
-
- if (clone_flags & CLONE_SETTLS)
- task_thread_info(p)->tp_value = regs->d5;
-
- /*
- * Must save the current SFC/DFC value, NOT the value when
- * the parent was last descheduled - RGH 10-08-96
- */
- p->thread.fs = get_fs().seg;
-
-#ifdef CONFIG_FPU
- if (!FPU_IS_EMU) {
- /* Copy the current fpu state */
- asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
-
- if (p->thread.fpstate[0])
- asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
- "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
- : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
- : "memory");
- /* Restore the state in case the fpu was busy */
- asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
- }
-#endif
-
- return 0;
-}
-
-/* Fill in the fpu structure for a core dump. */
-
-int dump_fpu(struct pt_regs *regs, struct user_m68kfp_struct *fpu)
-{
-#ifdef CONFIG_FPU
- char fpustate[216];
-
- if (FPU_IS_EMU) {
- int i;
-
- memcpy(fpu->fpcntl, current->thread.fpcntl, 12);
- memcpy(fpu->fpregs, current->thread.fp, 96);
- /* Convert internal fpu reg representation
- * into long double format
- */
- for (i = 0; i < 24; i += 3)
- fpu->fpregs[i] = ((fpu->fpregs[i] & 0xffff0000) << 15) |
- ((fpu->fpregs[i] & 0x0000ffff) << 16);
- return 1;
- }
-
- /* First dump the fpu context to avoid protocol violation. */
- asm volatile ("fsave %0" :: "m" (fpustate[0]) : "memory");
- if (!fpustate[0])
- return 0;
-
- asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
- :: "m" (fpu->fpcntl[0])
- : "memory");
- asm volatile ("fmovemx %/fp0-%/fp7,%0"
- :: "m" (fpu->fpregs[0])
- : "memory");
-#endif
- return 1;
-}
-EXPORT_SYMBOL(dump_fpu);
-
-/*
- * Generic dumping code. Used for panic and debug.
- */
-void dump(struct pt_regs *fp)
-{
- unsigned long *sp;
- unsigned char *tp;
- int i;
-
- printk(KERN_EMERG "\nCURRENT PROCESS:\n\n");
- printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid);
-
- if (current->mm) {
- printk(KERN_EMERG "TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n",
- (int) current->mm->start_code,
- (int) current->mm->end_code,
- (int) current->mm->start_data,
- (int) current->mm->end_data,
- (int) current->mm->end_data,
- (int) current->mm->brk);
- printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n\n",
- (int) current->mm->start_stack,
- (int)(((unsigned long) current) + THREAD_SIZE));
- }
-
- printk(KERN_EMERG "PC: %08lx\n", fp->pc);
- printk(KERN_EMERG "SR: %08lx SP: %08lx\n", (long) fp->sr, (long) fp);
- printk(KERN_EMERG "d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
- fp->d0, fp->d1, fp->d2, fp->d3);
- printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
- fp->d4, fp->d5, fp->a0, fp->a1);
- printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %p\n",
- (unsigned int) rdusp(), fp);
-
- printk(KERN_EMERG "\nCODE:");
- tp = ((unsigned char *) fp->pc) - 0x20;
- for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
- if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
- printk("%08x ", (int) *sp++);
- }
- printk(KERN_EMERG "\n");
-
- printk(KERN_EMERG "KERNEL STACK:");
- tp = ((unsigned char *) fp) - 0x40;
- for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
- if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
- printk("%08x ", (int) *sp++);
- }
- printk(KERN_EMERG "\n");
-
- printk(KERN_EMERG "USER STACK:");
- tp = (unsigned char *) (rdusp() - 0x10);
- for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
- if ((i % 0x10) == 0)
- printk(KERN_EMERG "%p: ", tp + i);
- printk("%08x ", (int) *sp++);
- }
- printk(KERN_EMERG "\n");
-}
-
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage int sys_execve(const char *name,
- const char *const *argv,
- const char *const *envp)
-{
- int error;
- char * filename;
- struct pt_regs *regs = (struct pt_regs *) &name;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
-unsigned long get_wchan(struct task_struct *p)
-{
- unsigned long fp, pc;
- unsigned long stack_page;
- int count = 0;
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
-
- stack_page = (unsigned long)p;
- fp = ((struct switch_stack *)p->thread.ksp)->a6;
- do {
- if (fp < stack_page+sizeof(struct thread_info) ||
- fp >= THREAD_SIZE-8+stack_page)
- return 0;
- pc = ((unsigned long *)fp)[1];
- if (!in_sched_functions(pc))
- return pc;
- fp = *(unsigned long *) fp;
- } while (count++ < 16);
- return 0;
-}
-
-/*
- * Return saved PC of a blocked thread.
- */
-unsigned long thread_saved_pc(struct task_struct *tsk)
-{
- struct switch_stack *sw = (struct switch_stack *)tsk->thread.ksp;
-
- /* Check whether the thread is blocked in resume() */
- if (in_sched_functions(sw->retpc))
- return ((unsigned long *)sw->a6)[1];
- else
- return sw->retpc;
-}
-
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index 07a417550e9..1bc10e62b9a 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -1,5 +1,304 @@
+/*
+ * linux/arch/m68k/kernel/ptrace.c
+ *
+ * Copyright (C) 1994 by Hamish Macdonald
+ * Taken from linux/kernel/ptrace.c and modified for M680x0.
+ * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of
+ * this archive for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/signal.h>
+#include <linux/tracehook.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* determines which bits in the SR the user has access to. */
+/* 1 = access 0 = no access */
+#define SR_MASK 0x001f
+
+/* sets the trace bits. */
+#define TRACE_BITS 0xC000
+#define T1_BIT 0x8000
+#define T0_BIT 0x4000
+
+/* Find the stack offset for a register, relative to thread.esp0. */
+#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
+#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
+ - sizeof(struct switch_stack))
+/* Mapping from PT_xxx to the stack offset at which the register is
+ saved. Notice that usp has no stack-slot and needs to be treated
+ specially (see get_reg/put_reg below). */
+static const int regoff[] = {
+ [0] = PT_REG(d1),
+ [1] = PT_REG(d2),
+ [2] = PT_REG(d3),
+ [3] = PT_REG(d4),
+ [4] = PT_REG(d5),
+ [5] = SW_REG(d6),
+ [6] = SW_REG(d7),
+ [7] = PT_REG(a0),
+ [8] = PT_REG(a1),
+ [9] = PT_REG(a2),
+ [10] = SW_REG(a3),
+ [11] = SW_REG(a4),
+ [12] = SW_REG(a5),
+ [13] = SW_REG(a6),
+ [14] = PT_REG(d0),
+ [15] = -1,
+ [16] = PT_REG(orig_d0),
+ [17] = PT_REG(sr),
+ [18] = PT_REG(pc),
+};
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+ unsigned long *addr;
+
+ if (regno == PT_USP)
+ addr = &task->thread.usp;
+ else if (regno < ARRAY_SIZE(regoff))
+ addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+ else
+ return 0;
+ /* Need to take stkadj into account. */
+ if (regno == PT_SR || regno == PT_PC) {
+ long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
+ addr = (unsigned long *) ((unsigned long)addr + stkadj);
+ /* The sr is actually a 16 bit register. */
+ if (regno == PT_SR)
+ return *(unsigned short *)addr;
+ }
+ return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task, int regno,
+ unsigned long data)
+{
+ unsigned long *addr;
+
+ if (regno == PT_USP)
+ addr = &task->thread.usp;
+ else if (regno < ARRAY_SIZE(regoff))
+ addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
+ else
+ return -1;
+ /* Need to take stkadj into account. */
+ if (regno == PT_SR || regno == PT_PC) {
+ long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
+ addr = (unsigned long *) ((unsigned long)addr + stkadj);
+ /* The sr is actually a 16 bit register. */
+ if (regno == PT_SR) {
+ *(unsigned short *)addr = data;
+ return 0;
+ }
+ }
+ *addr = data;
+ return 0;
+}
+
+/*
+ * Make sure the single step bit is not set.
+ */
+static inline void singlestep_disable(struct task_struct *child)
+{
+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+ put_reg(child, PT_SR, tmp);
+ clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ singlestep_disable(child);
+}
+
+void user_enable_single_step(struct task_struct *child)
+{
+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+ put_reg(child, PT_SR, tmp | T1_BIT);
+ set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
+}
+
#ifdef CONFIG_MMU
-#include "ptrace_mm.c"
-#else
-#include "ptrace_no.c"
+void user_enable_block_step(struct task_struct *child)
+{
+ unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
+ put_reg(child, PT_SR, tmp | T0_BIT);
+}
#endif
+
+void user_disable_single_step(struct task_struct *child)
+{
+ singlestep_disable(child);
+}
+
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ unsigned long tmp;
+ int i, ret = 0;
+ int regno = addr >> 2; /* temporary hack. */
+ unsigned long __user *datap = (unsigned long __user *) data;
+
+ switch (request) {
+ /* read the word at location addr in the USER area. */
+ case PTRACE_PEEKUSR:
+ if (addr & 3)
+ goto out_eio;
+
+ if (regno >= 0 && regno < 19) {
+ tmp = get_reg(child, regno);
+ } else if (regno >= 21 && regno < 49) {
+ tmp = child->thread.fp[regno - 21];
+ /* Convert internal fpu reg representation
+ * into long double format
+ */
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
+ tmp = ((tmp & 0xffff0000) << 15) |
+ ((tmp & 0x0000ffff) << 16);
+#ifndef CONFIG_MMU
+ } else if (regno == 49) {
+ tmp = child->mm->start_code;
+ } else if (regno == 50) {
+ tmp = child->mm->start_data;
+ } else if (regno == 51) {
+ tmp = child->mm->end_code;
+#endif
+ } else
+ goto out_eio;
+ ret = put_user(tmp, datap);
+ break;
+
+ case PTRACE_POKEUSR:
+ /* write the word at location addr in the USER area */
+ if (addr & 3)
+ goto out_eio;
+
+ if (regno == PT_SR) {
+ data &= SR_MASK;
+ data |= get_reg(child, PT_SR) & ~SR_MASK;
+ }
+ if (regno >= 0 && regno < 19) {
+ if (put_reg(child, regno, data))
+ goto out_eio;
+ } else if (regno >= 21 && regno < 48) {
+ /* Convert long double format
+ * into internal fpu reg representation
+ */
+ if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
+ data <<= 15;
+ data = (data & 0xffff0000) |
+ ((data & 0x0000ffff) >> 1);
+ }
+ child->thread.fp[regno - 21] = data;
+ } else
+ goto out_eio;
+ break;
+
+ case PTRACE_GETREGS: /* Get all gp regs from the child. */
+ for (i = 0; i < 19; i++) {
+ tmp = get_reg(child, i);
+ ret = put_user(tmp, datap);
+ if (ret)
+ break;
+ datap++;
+ }
+ break;
+
+ case PTRACE_SETREGS: /* Set all gp regs in the child. */
+ for (i = 0; i < 19; i++) {
+ ret = get_user(tmp, datap);
+ if (ret)
+ break;
+ if (i == PT_SR) {
+ tmp &= SR_MASK;
+ tmp |= get_reg(child, PT_SR) & ~SR_MASK;
+ }
+ put_reg(child, i, tmp);
+ datap++;
+ }
+ break;
+
+ case PTRACE_GETFPREGS: /* Get the child FPU state. */
+ if (copy_to_user(datap, &child->thread.fp,
+ sizeof(struct user_m68kfp_struct)))
+ ret = -EFAULT;
+ break;
+
+ case PTRACE_SETFPREGS: /* Set the child FPU state. */
+ if (copy_from_user(&child->thread.fp, datap,
+ sizeof(struct user_m68kfp_struct)))
+ ret = -EFAULT;
+ break;
+
+ case PTRACE_GET_THREAD_AREA:
+ ret = put_user(task_thread_info(child)->tp_value, datap);
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+out_eio:
+ return -EIO;
+}
+
+asmlinkage void syscall_trace(void)
+{
+ 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) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
+
+#if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU)
+asmlinkage int syscall_trace_enter(void)
+{
+ int ret = 0;
+
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ ret = tracehook_report_syscall_entry(task_pt_regs(current));
+ return ret;
+}
+
+asmlinkage void syscall_trace_leave(void)
+{
+ if (test_thread_flag(TIF_SYSCALL_TRACE))
+ tracehook_report_syscall_exit(task_pt_regs(current), 0);
+}
+#endif /* CONFIG_COLDFIRE */
diff --git a/arch/m68k/kernel/ptrace_mm.c b/arch/m68k/kernel/ptrace_mm.c
deleted file mode 100644
index 7bc999b7352..00000000000
--- a/arch/m68k/kernel/ptrace_mm.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * linux/arch/m68k/kernel/ptrace.c
- *
- * Copyright (C) 1994 by Hamish Macdonald
- * Taken from linux/kernel/ptrace.c and modified for M680x0.
- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of
- * this archive for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/signal.h>
-#include <linux/tracehook.h>
-
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-
-/*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
- */
-
-/* determines which bits in the SR the user has access to. */
-/* 1 = access 0 = no access */
-#define SR_MASK 0x001f
-
-/* sets the trace bits. */
-#define TRACE_BITS 0xC000
-#define T1_BIT 0x8000
-#define T0_BIT 0x4000
-
-/* Find the stack offset for a register, relative to thread.esp0. */
-#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
-#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- - sizeof(struct switch_stack))
-/* Mapping from PT_xxx to the stack offset at which the register is
- saved. Notice that usp has no stack-slot and needs to be treated
- specially (see get_reg/put_reg below). */
-static const int regoff[] = {
- [0] = PT_REG(d1),
- [1] = PT_REG(d2),
- [2] = PT_REG(d3),
- [3] = PT_REG(d4),
- [4] = PT_REG(d5),
- [5] = SW_REG(d6),
- [6] = SW_REG(d7),
- [7] = PT_REG(a0),
- [8] = PT_REG(a1),
- [9] = PT_REG(a2),
- [10] = SW_REG(a3),
- [11] = SW_REG(a4),
- [12] = SW_REG(a5),
- [13] = SW_REG(a6),
- [14] = PT_REG(d0),
- [15] = -1,
- [16] = PT_REG(orig_d0),
- [17] = PT_REG(sr),
- [18] = PT_REG(pc),
-};
-
-/*
- * Get contents of register REGNO in task TASK.
- */
-static inline long get_reg(struct task_struct *task, int regno)
-{
- unsigned long *addr;
-
- if (regno == PT_USP)
- addr = &task->thread.usp;
- else if (regno < ARRAY_SIZE(regoff))
- addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
- else
- return 0;
- /* Need to take stkadj into account. */
- if (regno == PT_SR || regno == PT_PC) {
- long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
- addr = (unsigned long *) ((unsigned long)addr + stkadj);
- /* The sr is actually a 16 bit register. */
- if (regno == PT_SR)
- return *(unsigned short *)addr;
- }
- return *addr;
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- */
-static inline int put_reg(struct task_struct *task, int regno,
- unsigned long data)
-{
- unsigned long *addr;
-
- if (regno == PT_USP)
- addr = &task->thread.usp;
- else if (regno < ARRAY_SIZE(regoff))
- addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
- else
- return -1;
- /* Need to take stkadj into account. */
- if (regno == PT_SR || regno == PT_PC) {
- long stkadj = *(long *)(task->thread.esp0 + PT_REG(stkadj));
- addr = (unsigned long *) ((unsigned long)addr + stkadj);
- /* The sr is actually a 16 bit register. */
- if (regno == PT_SR) {
- *(unsigned short *)addr = data;
- return 0;
- }
- }
- *addr = data;
- return 0;
-}
-
-/*
- * Make sure the single step bit is not set.
- */
-static inline void singlestep_disable(struct task_struct *child)
-{
- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
- put_reg(child, PT_SR, tmp);
- clear_tsk_thread_flag(child, TIF_DELAYED_TRACE);
-}
-
-/*
- * Called by kernel/ptrace.c when detaching..
- */
-void ptrace_disable(struct task_struct *child)
-{
- singlestep_disable(child);
-}
-
-void user_enable_single_step(struct task_struct *child)
-{
- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
- put_reg(child, PT_SR, tmp | T1_BIT);
- set_tsk_thread_flag(child, TIF_DELAYED_TRACE);
-}
-
-void user_enable_block_step(struct task_struct *child)
-{
- unsigned long tmp = get_reg(child, PT_SR) & ~TRACE_BITS;
- put_reg(child, PT_SR, tmp | T0_BIT);
-}
-
-void user_disable_single_step(struct task_struct *child)
-{
- singlestep_disable(child);
-}
-
-long arch_ptrace(struct task_struct *child, long request,
- unsigned long addr, unsigned long data)
-{
- unsigned long tmp;
- int i, ret = 0;
- int regno = addr >> 2; /* temporary hack. */
- unsigned long __user *datap = (unsigned long __user *) data;
-
- switch (request) {
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR:
- if (addr & 3)
- goto out_eio;
-
- if (regno >= 0 && regno < 19) {
- tmp = get_reg(child, regno);
- } else if (regno >= 21 && regno < 49) {
- tmp = child->thread.fp[regno - 21];
- /* Convert internal fpu reg representation
- * into long double format
- */
- if (FPU_IS_EMU && (regno < 45) && !(regno % 3))
- tmp = ((tmp & 0xffff0000) << 15) |
- ((tmp & 0x0000ffff) << 16);
- } else
- goto out_eio;
- ret = put_user(tmp, datap);
- break;
-
- case PTRACE_POKEUSR:
- /* write the word at location addr in the USER area */
- if (addr & 3)
- goto out_eio;
-
- if (regno == PT_SR) {
- data &= SR_MASK;
- data |= get_reg(child, PT_SR) & ~SR_MASK;
- }
- if (regno >= 0 && regno < 19) {
- if (put_reg(child, regno, data))
- goto out_eio;
- } else if (regno >= 21 && regno < 48) {
- /* Convert long double format
- * into internal fpu reg representation
- */
- if (FPU_IS_EMU && (regno < 45) && !(regno % 3)) {
- data <<= 15;
- data = (data & 0xffff0000) |
- ((data & 0x0000ffff) >> 1);
- }
- child->thread.fp[regno - 21] = data;
- } else
- goto out_eio;
- break;
-
- case PTRACE_GETREGS: /* Get all gp regs from the child. */
- for (i = 0; i < 19; i++) {
- tmp = get_reg(child, i);
- ret = put_user(tmp, datap);
- if (ret)
- break;
- datap++;
- }
- break;
-
- case PTRACE_SETREGS: /* Set all gp regs in the child. */
- for (i = 0; i < 19; i++) {
- ret = get_user(tmp, datap);
- if (ret)
- break;
- if (i == PT_SR) {
- tmp &= SR_MASK;
- tmp |= get_reg(child, PT_SR) & ~SR_MASK;
- }
- put_reg(child, i, tmp);
- datap++;
- }
- break;
-
- case PTRACE_GETFPREGS: /* Get the child FPU state. */
- if (copy_to_user(datap, &child->thread.fp,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
-
- case PTRACE_SETFPREGS: /* Set the child FPU state. */
- if (copy_from_user(&child->thread.fp, datap,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
-
- case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value, datap);
- break;
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
-
- return ret;
-out_eio:
- return -EIO;
-}
-
-asmlinkage void syscall_trace(void)
-{
- 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) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
-}
-
-#ifdef CONFIG_COLDFIRE
-asmlinkage int syscall_trace_enter(void)
-{
- int ret = 0;
-
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- ret = tracehook_report_syscall_entry(task_pt_regs(current));
- return ret;
-}
-
-asmlinkage void syscall_trace_leave(void)
-{
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(task_pt_regs(current), 0);
-}
-#endif /* CONFIG_COLDFIRE */
diff --git a/arch/m68k/kernel/ptrace_no.c b/arch/m68k/kernel/ptrace_no.c
deleted file mode 100644
index 6709fb70733..00000000000
--- a/arch/m68k/kernel/ptrace_no.c
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/ptrace.c
- *
- * Copyright (C) 1994 by Hamish Macdonald
- * Taken from linux/kernel/ptrace.c and modified for M680x0.
- * linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General
- * Public License. See the file COPYING in the main directory of
- * this archive for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/errno.h>
-#include <linux/ptrace.h>
-#include <linux/user.h>
-#include <linux/signal.h>
-#include <linux/tracehook.h>
-
-#include <asm/uaccess.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/system.h>
-#include <asm/processor.h>
-
-/*
- * does not yet catch signals sent when the child dies.
- * in exit.c or in signal.c.
- */
-
-/* determines which bits in the SR the user has access to. */
-/* 1 = access 0 = no access */
-#define SR_MASK 0x001f
-
-/* sets the trace bits. */
-#define TRACE_BITS 0x8000
-
-/* Find the stack offset for a register, relative to thread.esp0. */
-#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg)
-#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \
- - sizeof(struct switch_stack))
-/* Mapping from PT_xxx to the stack offset at which the register is
- saved. Notice that usp has no stack-slot and needs to be treated
- specially (see get_reg/put_reg below). */
-static int regoff[] = {
- PT_REG(d1), PT_REG(d2), PT_REG(d3), PT_REG(d4),
- PT_REG(d5), SW_REG(d6), SW_REG(d7), PT_REG(a0),
- PT_REG(a1), PT_REG(a2), SW_REG(a3), SW_REG(a4),
- SW_REG(a5), SW_REG(a6), PT_REG(d0), -1,
- PT_REG(orig_d0), PT_REG(sr), PT_REG(pc),
-};
-
-/*
- * Get contents of register REGNO in task TASK.
- */
-static inline long get_reg(struct task_struct *task, int regno)
-{
- unsigned long *addr;
-
- if (regno == PT_USP)
- addr = &task->thread.usp;
- else if (regno < ARRAY_SIZE(regoff))
- addr = (unsigned long *)(task->thread.esp0 + regoff[regno]);
- else
- return 0;
- return *addr;
-}
-
-/*
- * Write contents of register REGNO in task TASK.
- */
-static inline int put_reg(struct task_struct *task, int regno,
- unsigned long data)
-{
- unsigned long *addr;
-
- if (regno == PT_USP)
- addr = &task->thread.usp;
- else if (regno < ARRAY_SIZE(regoff))
- addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
- else
- return -1;
- *addr = data;
- return 0;
-}
-
-void user_enable_single_step(struct task_struct *task)
-{
- unsigned long srflags;
- srflags = get_reg(task, PT_SR) | (TRACE_BITS << 16);
- put_reg(task, PT_SR, srflags);
-}
-
-void user_disable_single_step(struct task_struct *task)
-{
- unsigned long srflags;
- srflags = get_reg(task, PT_SR) & ~(TRACE_BITS << 16);
- put_reg(task, PT_SR, srflags);
-}
-
-/*
- * Called by kernel/ptrace.c when detaching..
- *
- * Make sure the single step bit is not set.
- */
-void ptrace_disable(struct task_struct *child)
-{
- /* make sure the single step bit is not set. */
- user_disable_single_step(child);
-}
-
-long arch_ptrace(struct task_struct *child, long request,
- unsigned long addr, unsigned long data)
-{
- int ret;
- int regno = addr >> 2;
- unsigned long __user *datap = (unsigned long __user *) data;
-
- switch (request) {
- /* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long tmp;
-
- ret = -EIO;
- if ((addr & 3) || addr > sizeof(struct user) - 3)
- break;
-
- tmp = 0; /* Default return condition */
- ret = -EIO;
- if (regno < 19) {
- tmp = get_reg(child, regno);
- if (regno == PT_SR)
- tmp >>= 16;
- } else if (regno >= 21 && regno < 49) {
- tmp = child->thread.fp[regno - 21];
- } else if (regno == 49) {
- tmp = child->mm->start_code;
- } else if (regno == 50) {
- tmp = child->mm->start_data;
- } else if (regno == 51) {
- tmp = child->mm->end_code;
- } else
- break;
- ret = put_user(tmp, datap);
- break;
- }
-
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = -EIO;
- if ((addr & 3) || addr > sizeof(struct user) - 3)
- break;
-
- if (regno == PT_SR) {
- data &= SR_MASK;
- data <<= 16;
- data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
- }
- if (regno < 19) {
- if (put_reg(child, regno, data))
- break;
- ret = 0;
- break;
- }
- if (regno >= 21 && regno < 48)
- {
- child->thread.fp[regno - 21] = data;
- ret = 0;
- }
- break;
-
- case PTRACE_GETREGS: { /* Get all gp regs from the child. */
- int i;
- unsigned long tmp;
- for (i = 0; i < 19; i++) {
- tmp = get_reg(child, i);
- if (i == PT_SR)
- tmp >>= 16;
- if (put_user(tmp, datap)) {
- ret = -EFAULT;
- break;
- }
- datap++;
- }
- ret = 0;
- break;
- }
-
- case PTRACE_SETREGS: { /* Set all gp regs in the child. */
- int i;
- unsigned long tmp;
- for (i = 0; i < 19; i++) {
- if (get_user(tmp, datap)) {
- ret = -EFAULT;
- break;
- }
- if (i == PT_SR) {
- tmp &= SR_MASK;
- tmp <<= 16;
- tmp |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
- }
- put_reg(child, i, tmp);
- datap++;
- }
- ret = 0;
- break;
- }
-
-#ifdef PTRACE_GETFPREGS
- case PTRACE_GETFPREGS: { /* Get the child FPU state. */
- ret = 0;
- if (copy_to_user(datap, &child->thread.fp,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
- }
-#endif
-
-#ifdef PTRACE_SETFPREGS
- case PTRACE_SETFPREGS: { /* Set the child FPU state. */
- ret = 0;
- if (copy_from_user(&child->thread.fp, datap,
- sizeof(struct user_m68kfp_struct)))
- ret = -EFAULT;
- break;
- }
-#endif
-
- case PTRACE_GET_THREAD_AREA:
- ret = put_user(task_thread_info(child)->tp_value, datap);
- break;
-
- default:
- ret = ptrace_request(child, request, addr, data);
- break;
- }
- return ret;
-}
-
-asmlinkage int syscall_trace_enter(void)
-{
- int ret = 0;
-
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- ret = tracehook_report_syscall_entry(task_pt_regs(current));
- return ret;
-}
-
-asmlinkage void syscall_trace_leave(void)
-{
- if (test_thread_flag(TIF_SYSCALL_TRACE))
- tracehook_report_syscall_exit(task_pt_regs(current), 0);
-}
diff --git a/arch/m68k/kernel/relocate_kernel.S b/arch/m68k/kernel/relocate_kernel.S
new file mode 100644
index 00000000000..3e09a89067a
--- /dev/null
+++ b/arch/m68k/kernel/relocate_kernel.S
@@ -0,0 +1,159 @@
+#include <linux/linkage.h>
+
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+
+
+#define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */
+
+.text
+
+ENTRY(relocate_new_kernel)
+ movel %sp@(4),%a0 /* a0 = ptr */
+ movel %sp@(8),%a1 /* a1 = start */
+ movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */
+ movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */
+
+ /* Disable MMU */
+
+ btst #MMU_BASE + MMUB_68851,%d1
+ jeq 3f
+
+1: /* 68851 or 68030 */
+
+ lea %pc@(.Lcopy),%a4
+2: addl #0x00000000,%a4 /* virt_to_phys() */
+
+ .section ".m68k_fixup","aw"
+ .long M68K_FIXUP_MEMOFFSET, 2b+2
+ .previous
+
+ .chip 68030
+ pmove %tc,%d0 /* Disable MMU */
+ bclr #7,%d0
+ pmove %d0,%tc
+ jmp %a4@ /* Jump to physical .Lcopy */
+ .chip 68k
+
+3:
+ btst #MMU_BASE + MMUB_68030,%d1
+ jne 1b
+
+ btst #MMU_BASE + MMUB_68040,%d1
+ jeq 6f
+
+4: /* 68040 or 68060 */
+
+ lea %pc@(.Lcont040),%a4
+5: addl #0x00000000,%a4 /* virt_to_phys() */
+
+ .section ".m68k_fixup","aw"
+ .long M68K_FIXUP_MEMOFFSET, 5b+2
+ .previous
+
+ movel %a4,%d0
+ andl #0xff000000,%d0
+ orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */
+ .chip 68040
+ movec %d0,%itt0
+ movec %d0,%dtt0
+ .chip 68k
+ jmp %a4@ /* Jump to physical .Lcont040 */
+
+.Lcont040:
+ moveq #0,%d0
+ .chip 68040
+ movec %d0,%tc /* Disable MMU */
+ movec %d0,%itt0
+ movec %d0,%itt1
+ movec %d0,%dtt0
+ movec %d0,%dtt1
+ .chip 68k
+ jra .Lcopy
+
+6:
+ btst #MMU_BASE + MMUB_68060,%d1
+ jne 4b
+
+.Lcopy:
+ movel %a0@+,%d0 /* d0 = entry = *ptr */
+ jeq .Lflush
+
+ btst #2,%d0 /* entry & IND_DONE? */
+ jne .Lflush
+
+ btst #1,%d0 /* entry & IND_INDIRECTION? */
+ jeq 1f
+ andw %d2,%d0
+ movel %d0,%a0 /* ptr = entry & PAGE_MASK */
+ jra .Lcopy
+
+1:
+ btst #0,%d0 /* entry & IND_DESTINATION? */
+ jeq 2f
+ andw %d2,%d0
+ movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */
+ jra .Lcopy
+
+2:
+ btst #3,%d0 /* entry & IND_SOURCE? */
+ jeq .Lcopy
+
+ andw %d2,%d0
+ movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */
+ movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */
+3:
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ movel %a3@+,%a2@+ /* *dst++ = *src++ */
+ dbf %d0, 3b
+ jra .Lcopy
+
+.Lflush:
+ /* Flush all caches */
+
+ btst #CPUB_68020,%d1
+ jeq 2f
+
+1: /* 68020 or 68030 */
+ .chip 68030
+ movec %cacr,%d0
+ orw #0x808,%d0
+ movec %d0,%cacr
+ .chip 68k
+ jra .Lreincarnate
+
+2:
+ btst #CPUB_68030,%d1
+ jne 1b
+
+ btst #CPUB_68040,%d1
+ jeq 4f
+
+3: /* 68040 or 68060 */
+ .chip 68040
+ nop
+ cpusha %bc
+ nop
+ cinva %bc
+ nop
+ .chip 68k
+ jra .Lreincarnate
+
+4:
+ btst #CPUB_68060,%d1
+ jne 3b
+
+.Lreincarnate:
+ jmp %a1@
+
+relocate_new_kernel_end:
+
+ENTRY(relocate_new_kernel_size)
+ .long relocate_new_kernel_end - relocate_new_kernel
diff --git a/arch/m68k/kernel/setup_mm.c b/arch/m68k/kernel/setup_mm.c
index d872ce4807c..5b8ec4d5f8e 100644
--- a/arch/m68k/kernel/setup_mm.c
+++ b/arch/m68k/kernel/setup_mm.c
@@ -26,6 +26,7 @@
#include <linux/initrd.h>
#include <asm/bootinfo.h>
+#include <asm/byteorder.h>
#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/fpu.h>
@@ -71,12 +72,12 @@ EXPORT_SYMBOL(m68k_num_memory);
int m68k_realnum_memory;
EXPORT_SYMBOL(m68k_realnum_memory);
unsigned long m68k_memoffset;
-struct mem_info m68k_memory[NUM_MEMINFO];
+struct m68k_mem_info m68k_memory[NUM_MEMINFO];
EXPORT_SYMBOL(m68k_memory);
-struct mem_info m68k_ramdisk;
+static struct m68k_mem_info m68k_ramdisk __initdata;
-static char m68k_command_line[CL_SIZE];
+static char m68k_command_line[CL_SIZE] __initdata;
void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
/* machine dependent irq functions */
@@ -84,7 +85,6 @@ void (*mach_init_IRQ) (void) __initdata = NULL;
void (*mach_get_model) (char *model);
void (*mach_get_hardware_list) (struct seq_file *m);
/* machine dependent timer functions */
-unsigned long (*mach_gettimeoffset) (void);
int (*mach_hwclk) (int, struct rtc_time*);
EXPORT_SYMBOL(mach_hwclk);
int (*mach_set_clock_mmss) (unsigned long);
@@ -144,11 +144,16 @@ extern void paging_init(void);
static void __init m68k_parse_bootinfo(const struct bi_record *record)
{
- while (record->tag != BI_LAST) {
+ uint16_t tag;
+
+ save_bootinfo(record);
+
+ while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
int unknown = 0;
- const unsigned long *data = record->data;
+ const void *data = record->data;
+ uint16_t size = be16_to_cpu(record->size);
- switch (record->tag) {
+ switch (tag) {
case BI_MACHTYPE:
case BI_CPUTYPE:
case BI_FPUTYPE:
@@ -158,20 +163,27 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
case BI_MEMCHUNK:
if (m68k_num_memory < NUM_MEMINFO) {
- m68k_memory[m68k_num_memory].addr = data[0];
- m68k_memory[m68k_num_memory].size = data[1];
+ const struct mem_info *m = data;
+ m68k_memory[m68k_num_memory].addr =
+ be32_to_cpu(m->addr);
+ m68k_memory[m68k_num_memory].size =
+ be32_to_cpu(m->size);
m68k_num_memory++;
} else
- printk("m68k_parse_bootinfo: too many memory chunks\n");
+ pr_warn("%s: too many memory chunks\n",
+ __func__);
break;
case BI_RAMDISK:
- m68k_ramdisk.addr = data[0];
- m68k_ramdisk.size = data[1];
+ {
+ const struct mem_info *m = data;
+ m68k_ramdisk.addr = be32_to_cpu(m->addr);
+ m68k_ramdisk.size = be32_to_cpu(m->size);
+ }
break;
case BI_COMMAND_LINE:
- strlcpy(m68k_command_line, (const char *)data,
+ strlcpy(m68k_command_line, data,
sizeof(m68k_command_line));
break;
@@ -198,17 +210,16 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
unknown = 1;
}
if (unknown)
- printk("m68k_parse_bootinfo: unknown tag 0x%04x ignored\n",
- record->tag);
- record = (struct bi_record *)((unsigned long)record +
- record->size);
+ pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
+ tag);
+ record = (struct bi_record *)((unsigned long)record + size);
}
m68k_realnum_memory = m68k_num_memory;
#ifdef CONFIG_SINGLE_MEMORY_CHUNK
if (m68k_num_memory > 1) {
- printk("Ignoring last %i chunks of physical memory\n",
- (m68k_num_memory - 1));
+ pr_warn("%s: ignoring last %i chunks of physical memory\n",
+ __func__, (m68k_num_memory - 1));
m68k_num_memory = 1;
}
#endif
@@ -220,7 +231,7 @@ void __init setup_arch(char **cmdline_p)
int i;
#endif
- /* The bootinfo is located right after the kernel bss */
+ /* The bootinfo is located right after the kernel */
if (!CPU_IS_COLDFIRE)
m68k_parse_bootinfo((const struct bi_record *)_end);
@@ -248,7 +259,7 @@ void __init setup_arch(char **cmdline_p)
asm (".chip 68060; movec %%pcr,%0; .chip 68k"
: "=d" (pcr));
if (((pcr >> 8) & 0xff) <= 5) {
- printk("Enabling workaround for errata I14\n");
+ pr_warn("Enabling workaround for errata I14\n");
asm (".chip 68060; movec %0,%%pcr; .chip 68k"
: : "d" (pcr | 0x20));
}
@@ -337,12 +348,12 @@ void __init setup_arch(char **cmdline_p)
panic("No configuration setup");
}
+ paging_init();
+
#ifdef CONFIG_NATFEAT
nf_init();
#endif
- paging_init();
-
#ifndef CONFIG_SUN3
for (i = 1; i < m68k_num_memory; i++)
free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
@@ -354,7 +365,7 @@ void __init setup_arch(char **cmdline_p)
BOOTMEM_DEFAULT);
initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
initrd_end = initrd_start + m68k_ramdisk.size;
- printk("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
+ pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
}
#endif
@@ -382,6 +393,12 @@ void __init setup_arch(char **cmdline_p)
isa_sex = 1;
}
#endif
+#ifdef CONFIG_ATARI_ROM_ISA
+ if (MACH_IS_ATARI) {
+ isa_type = ISA_TYPE_ENEC;
+ isa_sex = 0;
+ }
+#endif
#endif
}
@@ -533,9 +550,9 @@ void check_bugs(void)
{
#ifndef CONFIG_M68KFPU_EMU
if (m68k_fputype == 0) {
- printk(KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
+ pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
"WHICH IS REQUIRED BY LINUX/M68K ***\n");
- printk(KERN_EMERG "Upgrade your hardware or join the FPU "
+ pr_emerg("Upgrade your hardware or join the FPU "
"emulation project\n");
panic("no FPU");
}
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c
index ca3df0dc7e8..88c27d94a72 100644
--- a/arch/m68k/kernel/setup_no.c
+++ b/arch/m68k/kernel/setup_no.c
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/initrd.h>
#include <linux/root_dev.h>
+#include <linux/rtc.h>
#include <asm/setup.h>
#include <asm/irq.h>
@@ -47,22 +48,26 @@ EXPORT_SYMBOL(memory_end);
char __initdata command_line[COMMAND_LINE_SIZE];
/* machine dependent timer functions */
+void (*mach_sched_init)(irq_handler_t handler) __initdata = NULL;
int (*mach_set_clock_mmss)(unsigned long);
+int (*mach_hwclk) (int, struct rtc_time*);
/* machine dependent reboot functions */
void (*mach_reset)(void);
void (*mach_halt)(void);
void (*mach_power_off)(void);
-#ifdef CONFIG_M68328
+#ifdef CONFIG_M68000
+#if defined(CONFIG_M68328)
#define CPU_NAME "MC68328"
-#endif
-#ifdef CONFIG_M68EZ328
+#elif defined(CONFIG_M68EZ328)
#define CPU_NAME "MC68EZ328"
-#endif
-#ifdef CONFIG_M68VZ328
+#elif defined(CONFIG_M68VZ328)
#define CPU_NAME "MC68VZ328"
+#else
+#define CPU_NAME "MC68000"
#endif
+#endif /* CONFIG_M68000 */
#ifdef CONFIG_M68360
#define CPU_NAME "MC68360"
#endif
@@ -112,7 +117,7 @@ void (*mach_power_off)(void);
*
* Returns:
*/
-void parse_uboot_commandline(char *commandp, int size)
+static void __init parse_uboot_commandline(char *commandp, int size)
{
extern unsigned long _init_sp;
unsigned long *sp;
@@ -215,13 +220,10 @@ void __init setup_arch(char **cmdline_p)
printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n");
#endif
- pr_debug("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x "
- "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext,
- (int) &_sdata, (int) &_edata,
- (int) &_sbss, (int) &_ebss);
- pr_debug("MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ",
- (int) &_ebss, (int) memory_start,
- (int) memory_start, (int) memory_end);
+ pr_debug("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n",
+ _stext, _etext, _sdata, _edata, __bss_start, __bss_stop);
+ pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ",
+ __bss_stop, memory_start, memory_start, memory_end);
/* Keep a copy of command line */
*cmdline_p = &command_line[0];
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 2e25713e2ea..57fd286e4b0 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -1,5 +1,1140 @@
+/*
+ * linux/arch/m68k/kernel/signal.c
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
+ *
+ * mathemu support by Roman Zippel
+ * (Note: fpstate in the signal context is completely ignored for the emulator
+ * and the internal floating point format is put on stack)
+ */
+
+/*
+ * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
+ * Atari :-) Current limitation: Only one sigstack can be active at one time.
+ * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
+ * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
+ * signal handlers!
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/syscalls.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/tty.h>
+#include <linux/binfmts.h>
+#include <linux/module.h>
+#include <linux/tracehook.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/traps.h>
+#include <asm/ucontext.h>
+#include <asm/cacheflush.h>
+
#ifdef CONFIG_MMU
-#include "signal_mm.c"
+
+/*
+ * Handle the slight differences in classic 68k and ColdFire trap frames.
+ */
+#ifdef CONFIG_COLDFIRE
+#define FORMAT 4
+#define FMT4SIZE 0
#else
-#include "signal_no.c"
+#define FORMAT 0
+#define FMT4SIZE sizeof(((struct frame *)0)->un.fmt4)
#endif
+
+static const int frame_size_change[16] = {
+ [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
+ [2] = sizeof(((struct frame *)0)->un.fmt2),
+ [3] = sizeof(((struct frame *)0)->un.fmt3),
+ [4] = FMT4SIZE,
+ [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
+ [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
+ [7] = sizeof(((struct frame *)0)->un.fmt7),
+ [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */
+ [9] = sizeof(((struct frame *)0)->un.fmt9),
+ [10] = sizeof(((struct frame *)0)->un.fmta),
+ [11] = sizeof(((struct frame *)0)->un.fmtb),
+ [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */
+ [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */
+ [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */
+ [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */
+};
+
+static inline int frame_extra_sizes(int f)
+{
+ return frame_size_change[f];
+}
+
+int handle_kernel_fault(struct pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+ struct pt_regs *tregs;
+
+ /* Are we prepared to handle this kernel fault? */
+ fixup = search_exception_tables(regs->pc);
+ if (!fixup)
+ return 0;
+
+ /* Create a new four word stack frame, discarding the old one. */
+ regs->stkadj = frame_extra_sizes(regs->format);
+ tregs = (struct pt_regs *)((long)regs + regs->stkadj);
+ tregs->vector = regs->vector;
+ tregs->format = FORMAT;
+ tregs->pc = fixup->fixup;
+ tregs->sr = regs->sr;
+
+ return 1;
+}
+
+void ptrace_signal_deliver(void)
+{
+ struct pt_regs *regs = signal_pt_regs();
+ if (regs->orig_d0 < 0)
+ return;
+ switch (regs->d0) {
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ regs->d0 = regs->orig_d0;
+ regs->orig_d0 = -1;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+static inline void push_cache (unsigned long vaddr)
+{
+ /*
+ * Using the old cache_push_v() was really a big waste.
+ *
+ * What we are trying to do is to flush 8 bytes to ram.
+ * Flushing 2 cache lines of 16 bytes is much cheaper than
+ * flushing 1 or 2 pages, as previously done in
+ * cache_push_v().
+ * Jes
+ */
+ if (CPU_IS_040) {
+ unsigned long temp;
+
+ __asm__ __volatile__ (".chip 68040\n\t"
+ "nop\n\t"
+ "ptestr (%1)\n\t"
+ "movec %%mmusr,%0\n\t"
+ ".chip 68k"
+ : "=r" (temp)
+ : "a" (vaddr));
+
+ temp &= PAGE_MASK;
+ temp |= vaddr & ~PAGE_MASK;
+
+ __asm__ __volatile__ (".chip 68040\n\t"
+ "nop\n\t"
+ "cpushl %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (temp));
+ }
+ else if (CPU_IS_060) {
+ unsigned long temp;
+ __asm__ __volatile__ (".chip 68060\n\t"
+ "plpar (%0)\n\t"
+ ".chip 68k"
+ : "=a" (temp)
+ : "0" (vaddr));
+ __asm__ __volatile__ (".chip 68060\n\t"
+ "cpushl %%bc,(%0)\n\t"
+ ".chip 68k"
+ : : "a" (temp));
+ } else if (!CPU_IS_COLDFIRE) {
+ /*
+ * 68030/68020 have no writeback cache;
+ * still need to clear icache.
+ * Note that vaddr is guaranteed to be long word aligned.
+ */
+ unsigned long temp;
+ asm volatile ("movec %%cacr,%0" : "=r" (temp));
+ temp += 4;
+ asm volatile ("movec %0,%%caar\n\t"
+ "movec %1,%%cacr"
+ : : "r" (vaddr), "r" (temp));
+ asm volatile ("movec %0,%%caar\n\t"
+ "movec %1,%%cacr"
+ : : "r" (vaddr + 4), "r" (temp));
+ } else {
+ /* CPU_IS_COLDFIRE */
+#if defined(CONFIG_CACHE_COPYBACK)
+ flush_cf_dcache(0, DCACHE_MAX_ADDR);
+#endif
+ /* Invalidate instruction cache for the pushed bytes */
+ clear_cf_icache(vaddr, vaddr + 8);
+ }
+}
+
+static inline void adjustformat(struct pt_regs *regs)
+{
+}
+
+static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+}
+
+#else /* CONFIG_MMU */
+
+void ret_from_user_signal(void);
+void ret_from_user_rt_signal(void);
+
+static inline int frame_extra_sizes(int f)
+{
+ /* No frame size adjustments required on non-MMU CPUs */
+ return 0;
+}
+
+static inline void adjustformat(struct pt_regs *regs)
+{
+ ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
+ /*
+ * set format byte to make stack appear modulo 4, which it will
+ * be when doing the rte
+ */
+ regs->format = 0x4;
+}
+
+static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+ sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
+}
+
+static inline void push_cache(unsigned long vaddr)
+{
+}
+
+#endif /* CONFIG_MMU */
+
+/*
+ * Do a signal return; undo the signal stack.
+ *
+ * Keep the return code on the stack quadword aligned!
+ * That makes the cache flush below easier.
+ */
+
+struct sigframe
+{
+ char __user *pretcode;
+ int sig;
+ int code;
+ struct sigcontext __user *psc;
+ char retcode[8];
+ unsigned long extramask[_NSIG_WORDS-1];
+ struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+ char __user *pretcode;
+ int sig;
+ struct siginfo __user *pinfo;
+ void __user *puc;
+ char retcode[8];
+ struct siginfo info;
+ struct ucontext uc;
+};
+
+#define FPCONTEXT_SIZE 216
+#define uc_fpstate uc_filler[0]
+#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
+#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
+
+#ifdef CONFIG_FPU
+
+static unsigned char fpu_version; /* version number of fpu, set by setup_frame */
+
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+ int err = 1;
+
+ if (FPU_IS_EMU) {
+ /* restore registers */
+ memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
+ memcpy(current->thread.fp, sc->sc_fpregs, 24);
+ return 0;
+ }
+
+ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+ /* Verify the frame format. */
+ if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
+ (sc->sc_fpstate[0] != fpu_version))
+ goto out;
+ if (CPU_IS_020_OR_030) {
+ if (m68k_fputype & FPU_68881 &&
+ !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
+ goto out;
+ if (m68k_fputype & FPU_68882 &&
+ !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
+ goto out;
+ } else if (CPU_IS_040) {
+ if (!(sc->sc_fpstate[1] == 0x00 ||
+ sc->sc_fpstate[1] == 0x28 ||
+ sc->sc_fpstate[1] == 0x60))
+ goto out;
+ } else if (CPU_IS_060) {
+ if (!(sc->sc_fpstate[3] == 0x00 ||
+ sc->sc_fpstate[3] == 0x60 ||
+ sc->sc_fpstate[3] == 0xe0))
+ goto out;
+ } else if (CPU_IS_COLDFIRE) {
+ if (!(sc->sc_fpstate[0] == 0x00 ||
+ sc->sc_fpstate[0] == 0x05 ||
+ sc->sc_fpstate[0] == 0xe5))
+ goto out;
+ } else
+ goto out;
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
+ "fmovel %1,%%fpcr\n\t"
+ "fmovel %2,%%fpsr\n\t"
+ "fmovel %3,%%fpiar"
+ : /* no outputs */
+ : "m" (sc->sc_fpregs[0]),
+ "m" (sc->sc_fpcntl[0]),
+ "m" (sc->sc_fpcntl[1]),
+ "m" (sc->sc_fpcntl[2]));
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fmovemx %0,%%fp0-%%fp1\n\t"
+ "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
+ ".chip 68k"
+ : /* no outputs */
+ : "m" (*sc->sc_fpregs),
+ "m" (*sc->sc_fpcntl));
+ }
+ }
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "frestore %0\n\t"
+ ".chip 68k"
+ : : "m" (*sc->sc_fpstate));
+ }
+ err = 0;
+
+out:
+ return err;
+}
+
+static inline int rt_restore_fpu_state(struct ucontext __user *uc)
+{
+ unsigned char fpstate[FPCONTEXT_SIZE];
+ int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
+ fpregset_t fpregs;
+ int err = 1;
+
+ if (FPU_IS_EMU) {
+ /* restore fpu control register */
+ if (__copy_from_user(current->thread.fpcntl,
+ uc->uc_mcontext.fpregs.f_fpcntl, 12))
+ goto out;
+ /* restore all other fpu register */
+ if (__copy_from_user(current->thread.fp,
+ uc->uc_mcontext.fpregs.f_fpregs, 96))
+ goto out;
+ return 0;
+ }
+
+ if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
+ goto out;
+ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+ if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
+ context_size = fpstate[1];
+ /* Verify the frame format. */
+ if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
+ (fpstate[0] != fpu_version))
+ goto out;
+ if (CPU_IS_020_OR_030) {
+ if (m68k_fputype & FPU_68881 &&
+ !(context_size == 0x18 || context_size == 0xb4))
+ goto out;
+ if (m68k_fputype & FPU_68882 &&
+ !(context_size == 0x38 || context_size == 0xd4))
+ goto out;
+ } else if (CPU_IS_040) {
+ if (!(context_size == 0x00 ||
+ context_size == 0x28 ||
+ context_size == 0x60))
+ goto out;
+ } else if (CPU_IS_060) {
+ if (!(fpstate[3] == 0x00 ||
+ fpstate[3] == 0x60 ||
+ fpstate[3] == 0xe0))
+ goto out;
+ } else if (CPU_IS_COLDFIRE) {
+ if (!(fpstate[3] == 0x00 ||
+ fpstate[3] == 0x05 ||
+ fpstate[3] == 0xe5))
+ goto out;
+ } else
+ goto out;
+ if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
+ sizeof(fpregs)))
+ goto out;
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t"
+ "fmovel %1,%%fpcr\n\t"
+ "fmovel %2,%%fpsr\n\t"
+ "fmovel %3,%%fpiar"
+ : /* no outputs */
+ : "m" (fpregs.f_fpregs[0]),
+ "m" (fpregs.f_fpcntl[0]),
+ "m" (fpregs.f_fpcntl[1]),
+ "m" (fpregs.f_fpcntl[2]));
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fmovemx %0,%%fp0-%%fp7\n\t"
+ "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
+ ".chip 68k"
+ : /* no outputs */
+ : "m" (*fpregs.f_fpregs),
+ "m" (*fpregs.f_fpcntl));
+ }
+ }
+ if (context_size &&
+ __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
+ context_size))
+ goto out;
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("frestore %0" : : "m" (*fpstate));
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "frestore %0\n\t"
+ ".chip 68k"
+ : : "m" (*fpstate));
+ }
+ err = 0;
+
+out:
+ return err;
+}
+
+/*
+ * Set up a signal frame.
+ */
+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+ if (FPU_IS_EMU) {
+ /* save registers */
+ memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
+ memcpy(sc->sc_fpregs, current->thread.fp, 24);
+ return;
+ }
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fsave %0"
+ : : "m" (*sc->sc_fpstate) : "memory");
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fsave %0\n\t"
+ ".chip 68k"
+ : : "m" (*sc->sc_fpstate) : "memory");
+ }
+
+ if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
+ fpu_version = sc->sc_fpstate[0];
+ if (CPU_IS_020_OR_030 &&
+ regs->vector >= (VEC_FPBRUC * 4) &&
+ regs->vector <= (VEC_FPNAN * 4)) {
+ /* Clear pending exception in 68882 idle frame */
+ if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
+ sc->sc_fpstate[0x38] |= 1 << 3;
+ }
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t"
+ "fmovel %%fpcr,%1\n\t"
+ "fmovel %%fpsr,%2\n\t"
+ "fmovel %%fpiar,%3"
+ : "=m" (sc->sc_fpregs[0]),
+ "=m" (sc->sc_fpcntl[0]),
+ "=m" (sc->sc_fpcntl[1]),
+ "=m" (sc->sc_fpcntl[2])
+ : /* no inputs */
+ : "memory");
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fmovemx %%fp0-%%fp1,%0\n\t"
+ "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
+ ".chip 68k"
+ : "=m" (*sc->sc_fpregs),
+ "=m" (*sc->sc_fpcntl)
+ : /* no inputs */
+ : "memory");
+ }
+ }
+}
+
+static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
+{
+ unsigned char fpstate[FPCONTEXT_SIZE];
+ int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
+ int err = 0;
+
+ if (FPU_IS_EMU) {
+ /* save fpu control register */
+ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
+ current->thread.fpcntl, 12);
+ /* save all other fpu register */
+ err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
+ current->thread.fp, 96);
+ return err;
+ }
+
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory");
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fsave %0\n\t"
+ ".chip 68k"
+ : : "m" (*fpstate) : "memory");
+ }
+
+ err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
+ if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
+ fpregset_t fpregs;
+ if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
+ context_size = fpstate[1];
+ fpu_version = fpstate[0];
+ if (CPU_IS_020_OR_030 &&
+ regs->vector >= (VEC_FPBRUC * 4) &&
+ regs->vector <= (VEC_FPNAN * 4)) {
+ /* Clear pending exception in 68882 idle frame */
+ if (*(unsigned short *) fpstate == 0x1f38)
+ fpstate[0x38] |= 1 << 3;
+ }
+ if (CPU_IS_COLDFIRE) {
+ __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t"
+ "fmovel %%fpcr,%1\n\t"
+ "fmovel %%fpsr,%2\n\t"
+ "fmovel %%fpiar,%3"
+ : "=m" (fpregs.f_fpregs[0]),
+ "=m" (fpregs.f_fpcntl[0]),
+ "=m" (fpregs.f_fpcntl[1]),
+ "=m" (fpregs.f_fpcntl[2])
+ : /* no inputs */
+ : "memory");
+ } else {
+ __asm__ volatile (".chip 68k/68881\n\t"
+ "fmovemx %%fp0-%%fp7,%0\n\t"
+ "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
+ ".chip 68k"
+ : "=m" (*fpregs.f_fpregs),
+ "=m" (*fpregs.f_fpcntl)
+ : /* no inputs */
+ : "memory");
+ }
+ err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
+ sizeof(fpregs));
+ }
+ if (context_size)
+ err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
+ context_size);
+ return err;
+}
+
+#else /* CONFIG_FPU */
+
+/*
+ * For the case with no FPU configured these all do nothing.
+ */
+static inline int restore_fpu_state(struct sigcontext *sc)
+{
+ return 0;
+}
+
+static inline int rt_restore_fpu_state(struct ucontext __user *uc)
+{
+ return 0;
+}
+
+static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
+{
+}
+
+static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
+{
+ return 0;
+}
+
+#endif /* CONFIG_FPU */
+
+static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
+ void __user *fp)
+{
+ int fsize = frame_extra_sizes(formatvec >> 12);
+ if (fsize < 0) {
+ /*
+ * user process trying to return with weird frame format
+ */
+#ifdef DEBUG
+ printk("user process returning with weird frame format\n");
+#endif
+ return 1;
+ }
+ if (!fsize) {
+ regs->format = formatvec >> 12;
+ regs->vector = formatvec & 0xfff;
+ } else {
+ struct switch_stack *sw = (struct switch_stack *)regs - 1;
+ unsigned long buf[fsize / 2]; /* yes, twice as much */
+
+ /* that'll make sure that expansion won't crap over data */
+ if (copy_from_user(buf + fsize / 4, fp, fsize))
+ return 1;
+
+ /* point of no return */
+ regs->format = formatvec >> 12;
+ regs->vector = formatvec & 0xfff;
+#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
+ __asm__ __volatile__ (
+#ifdef CONFIG_COLDFIRE
+ " movel %0,%/sp\n\t"
+ " bra ret_from_signal\n"
+#else
+ " movel %0,%/a0\n\t"
+ " subl %1,%/a0\n\t" /* make room on stack */
+ " movel %/a0,%/sp\n\t" /* set stack pointer */
+ /* move switch_stack and pt_regs */
+ "1: movel %0@+,%/a0@+\n\t"
+ " dbra %2,1b\n\t"
+ " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
+ " lsrl #2,%1\n\t"
+ " subql #1,%1\n\t"
+ /* copy to the gap we'd made */
+ "2: movel %4@+,%/a0@+\n\t"
+ " dbra %1,2b\n\t"
+ " bral ret_from_signal\n"
+#endif
+ : /* no outputs, it doesn't ever return */
+ : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
+ "n" (frame_offset), "a" (buf + fsize/4)
+ : "a0");
+#undef frame_offset
+ }
+ return 0;
+}
+
+static inline int
+restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)
+{
+ int formatvec;
+ struct sigcontext context;
+ int err = 0;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ /* get previous context */
+ if (copy_from_user(&context, usc, sizeof(context)))
+ goto badframe;
+
+ /* restore passed registers */
+ regs->d0 = context.sc_d0;
+ regs->d1 = context.sc_d1;
+ regs->a0 = context.sc_a0;
+ regs->a1 = context.sc_a1;
+ regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
+ regs->pc = context.sc_pc;
+ regs->orig_d0 = -1; /* disable syscall checks */
+ wrusp(context.sc_usp);
+ formatvec = context.sc_formatvec;
+
+ err = restore_fpu_state(&context);
+
+ if (err || mangle_kernel_stack(regs, formatvec, fp))
+ goto badframe;
+
+ return 0;
+
+badframe:
+ return 1;
+}
+
+static inline int
+rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
+ struct ucontext __user *uc)
+{
+ int temp;
+ greg_t __user *gregs = uc->uc_mcontext.gregs;
+ unsigned long usp;
+ int err;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ err = __get_user(temp, &uc->uc_mcontext.version);
+ if (temp != MCONTEXT_VERSION)
+ goto badframe;
+ /* restore passed registers */
+ err |= __get_user(regs->d0, &gregs[0]);
+ err |= __get_user(regs->d1, &gregs[1]);
+ err |= __get_user(regs->d2, &gregs[2]);
+ err |= __get_user(regs->d3, &gregs[3]);
+ err |= __get_user(regs->d4, &gregs[4]);
+ err |= __get_user(regs->d5, &gregs[5]);
+ err |= __get_user(sw->d6, &gregs[6]);
+ err |= __get_user(sw->d7, &gregs[7]);
+ err |= __get_user(regs->a0, &gregs[8]);
+ err |= __get_user(regs->a1, &gregs[9]);
+ err |= __get_user(regs->a2, &gregs[10]);
+ err |= __get_user(sw->a3, &gregs[11]);
+ err |= __get_user(sw->a4, &gregs[12]);
+ err |= __get_user(sw->a5, &gregs[13]);
+ err |= __get_user(sw->a6, &gregs[14]);
+ err |= __get_user(usp, &gregs[15]);
+ wrusp(usp);
+ err |= __get_user(regs->pc, &gregs[16]);
+ err |= __get_user(temp, &gregs[17]);
+ regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
+ regs->orig_d0 = -1; /* disable syscall checks */
+ err |= __get_user(temp, &uc->uc_formatvec);
+
+ err |= rt_restore_fpu_state(uc);
+ err |= restore_altstack(&uc->uc_stack);
+
+ if (err)
+ goto badframe;
+
+ if (mangle_kernel_stack(regs, temp, &uc->uc_extra))
+ goto badframe;
+
+ return 0;
+
+badframe:
+ return 1;
+}
+
+asmlinkage int do_sigreturn(unsigned long __unused)
+{
+ struct switch_stack *sw = (struct switch_stack *) &__unused;
+ struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+ unsigned long usp = rdusp();
+ struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
+ sigset_t set;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
+ (_NSIG_WORDS > 1 &&
+ __copy_from_user(&set.sig[1], &frame->extramask,
+ sizeof(frame->extramask))))
+ goto badframe;
+
+ set_current_blocked(&set);
+
+ if (restore_sigcontext(regs, &frame->sc, frame + 1))
+ goto badframe;
+ return regs->d0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+asmlinkage int do_rt_sigreturn(unsigned long __unused)
+{
+ struct switch_stack *sw = (struct switch_stack *) &__unused;
+ struct pt_regs *regs = (struct pt_regs *) (sw + 1);
+ unsigned long usp = rdusp();
+ struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
+ sigset_t set;
+
+ 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 (rt_restore_ucontext(regs, sw, &frame->uc))
+ goto badframe;
+ return regs->d0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ sc->sc_mask = mask;
+ sc->sc_usp = rdusp();
+ sc->sc_d0 = regs->d0;
+ sc->sc_d1 = regs->d1;
+ sc->sc_a0 = regs->a0;
+ sc->sc_a1 = regs->a1;
+ sc->sc_sr = regs->sr;
+ sc->sc_pc = regs->pc;
+ sc->sc_formatvec = regs->format << 12 | regs->vector;
+ save_a5_state(sc, regs);
+ save_fpu_state(sc, regs);
+}
+
+static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
+{
+ struct switch_stack *sw = (struct switch_stack *)regs - 1;
+ greg_t __user *gregs = uc->uc_mcontext.gregs;
+ int err = 0;
+
+ err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
+ err |= __put_user(regs->d0, &gregs[0]);
+ err |= __put_user(regs->d1, &gregs[1]);
+ err |= __put_user(regs->d2, &gregs[2]);
+ err |= __put_user(regs->d3, &gregs[3]);
+ err |= __put_user(regs->d4, &gregs[4]);
+ err |= __put_user(regs->d5, &gregs[5]);
+ err |= __put_user(sw->d6, &gregs[6]);
+ err |= __put_user(sw->d7, &gregs[7]);
+ err |= __put_user(regs->a0, &gregs[8]);
+ err |= __put_user(regs->a1, &gregs[9]);
+ err |= __put_user(regs->a2, &gregs[10]);
+ err |= __put_user(sw->a3, &gregs[11]);
+ err |= __put_user(sw->a4, &gregs[12]);
+ err |= __put_user(sw->a5, &gregs[13]);
+ err |= __put_user(sw->a6, &gregs[14]);
+ err |= __put_user(rdusp(), &gregs[15]);
+ err |= __put_user(regs->pc, &gregs[16]);
+ err |= __put_user(regs->sr, &gregs[17]);
+ err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
+ err |= rt_save_fpu_state(uc, regs);
+ return err;
+}
+
+static inline void __user *
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+{
+ unsigned long usp;
+
+ /* Default to using normal stack. */
+ usp = rdusp();
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (!sas_ss_flags(usp))
+ usp = current->sas_ss_sp + current->sas_ss_size;
+ }
+ return (void __user *)((usp - frame_size) & -8UL);
+}
+
+static int setup_frame (int sig, struct k_sigaction *ka,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct sigframe __user *frame;
+ int fsize = frame_extra_sizes(regs->format);
+ struct sigcontext context;
+ int err = 0;
+
+ if (fsize < 0) {
+#ifdef DEBUG
+ printk ("setup_frame: Unknown frame format %#x\n",
+ regs->format);
+#endif
+ goto give_sigsegv;
+ }
+
+ frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
+
+ if (fsize)
+ err |= copy_to_user (frame + 1, regs + 1, fsize);
+
+ err |= __put_user((current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig),
+ &frame->sig);
+
+ err |= __put_user(regs->vector, &frame->code);
+ err |= __put_user(&frame->sc, &frame->psc);
+
+ if (_NSIG_WORDS > 1)
+ err |= copy_to_user(frame->extramask, &set->sig[1],
+ sizeof(frame->extramask));
+
+ setup_sigcontext(&context, regs, set->sig[0]);
+ err |= copy_to_user (&frame->sc, &context, sizeof(context));
+
+ /* Set up to return from userspace. */
+#ifdef CONFIG_MMU
+ err |= __put_user(frame->retcode, &frame->pretcode);
+ /* moveq #,d0; trap #0 */
+ err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
+ (long __user *)(frame->retcode));
+#else
+ err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
+#endif
+
+ if (err)
+ goto give_sigsegv;
+
+ push_cache ((unsigned long) &frame->retcode);
+
+ /*
+ * Set up registers for signal handler. All the state we are about
+ * to destroy is successfully copied to sigframe.
+ */
+ wrusp ((unsigned long) frame);
+ regs->pc = (unsigned long) ka->sa.sa_handler;
+ adjustformat(regs);
+
+ /*
+ * This is subtle; if we build more than one sigframe, all but the
+ * first one will see frame format 0 and have fsize == 0, so we won't
+ * screw stkadj.
+ */
+ if (fsize)
+ regs->stkadj = fsize;
+
+ /* Prepare to skip over the extra stuff in the exception frame. */
+ if (regs->stkadj) {
+ struct pt_regs *tregs =
+ (struct pt_regs *)((ulong)regs + regs->stkadj);
+#ifdef DEBUG
+ printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+ /* This must be copied with decreasing addresses to
+ handle overlaps. */
+ tregs->vector = 0;
+ tregs->format = 0;
+ tregs->pc = regs->pc;
+ tregs->sr = regs->sr;
+ }
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(sig, current);
+ return err;
+}
+
+static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame;
+ int fsize = frame_extra_sizes(regs->format);
+ int err = 0;
+
+ if (fsize < 0) {
+#ifdef DEBUG
+ printk ("setup_frame: Unknown frame format %#x\n",
+ regs->format);
+#endif
+ goto give_sigsegv;
+ }
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (fsize)
+ err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
+
+ err |= __put_user((current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig),
+ &frame->sig);
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Create 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, rdusp());
+ err |= rt_setup_ucontext(&frame->uc, regs);
+ err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace. */
+#ifdef CONFIG_MMU
+ err |= __put_user(frame->retcode, &frame->pretcode);
+#ifdef __mcoldfire__
+ /* movel #__NR_rt_sigreturn,d0; trap #0 */
+ err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));
+ err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),
+ (long __user *)(frame->retcode + 4));
+#else
+ /* moveq #,d0; notb d0; trap #0 */
+ err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+ (long __user *)(frame->retcode + 0));
+ err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
+#endif
+#else
+ err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
+#endif /* CONFIG_MMU */
+
+ if (err)
+ goto give_sigsegv;
+
+ push_cache ((unsigned long) &frame->retcode);
+
+ /*
+ * Set up registers for signal handler. All the state we are about
+ * to destroy is successfully copied to sigframe.
+ */
+ wrusp ((unsigned long) frame);
+ regs->pc = (unsigned long) ka->sa.sa_handler;
+ adjustformat(regs);
+
+ /*
+ * This is subtle; if we build more than one sigframe, all but the
+ * first one will see frame format 0 and have fsize == 0, so we won't
+ * screw stkadj.
+ */
+ if (fsize)
+ regs->stkadj = fsize;
+
+ /* Prepare to skip over the extra stuff in the exception frame. */
+ if (regs->stkadj) {
+ struct pt_regs *tregs =
+ (struct pt_regs *)((ulong)regs + regs->stkadj);
+#ifdef DEBUG
+ printk("Performing stackadjust=%04x\n", regs->stkadj);
+#endif
+ /* This must be copied with decreasing addresses to
+ handle overlaps. */
+ tregs->vector = 0;
+ tregs->format = 0;
+ tregs->pc = regs->pc;
+ tregs->sr = regs->sr;
+ }
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(sig, current);
+ return err;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->d0) {
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->d0 = -EINTR;
+ break;
+
+ case -ERESTART_RESTARTBLOCK:
+ if (!has_handler) {
+ regs->d0 = __NR_restart_syscall;
+ regs->pc -= 2;
+ break;
+ }
+ regs->d0 = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->d0 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ do_restart:
+ regs->d0 = regs->orig_d0;
+ regs->pc -= 2;
+ break;
+ }
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+static void
+handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
+ struct pt_regs *regs)
+{
+ sigset_t *oldset = sigmask_to_save();
+ int err;
+ /* are we from a system call? */
+ if (regs->orig_d0 >= 0)
+ /* If so, check system call restarting.. */
+ handle_restart(regs, ka, 1);
+
+ /* set up the stack frame */
+ if (ka->sa.sa_flags & SA_SIGINFO)
+ err = setup_rt_frame(sig, ka, info, oldset, regs);
+ else
+ err = setup_frame(sig, ka, oldset, regs);
+
+ if (err)
+ return;
+
+ signal_delivered(sig, info, ka, regs, 0);
+
+ if (test_thread_flag(TIF_DELAYED_TRACE)) {
+ regs->sr &= ~0x8000;
+ send_sig(SIGTRAP, current, 1);
+ }
+}
+
+/*
+ * 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)
+{
+ siginfo_t info;
+ struct k_sigaction ka;
+ int signr;
+
+ current->thread.esp0 = (unsigned long) regs;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ handle_signal(signr, &ka, &info, regs);
+ return;
+ }
+
+ /* Did we come from a system call? */
+ if (regs->orig_d0 >= 0)
+ /* Restart the system call - no handlers present */
+ handle_restart(regs, NULL, 0);
+
+ /* If there's no signal to deliver, we just restore the saved mask. */
+ restore_saved_sigmask();
+}
+
+void do_notify_resume(struct pt_regs *regs)
+{
+ if (test_thread_flag(TIF_SIGPENDING))
+ do_signal(regs);
+
+ if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME))
+ tracehook_notify_resume(regs);
+}
diff --git a/arch/m68k/kernel/signal_mm.c b/arch/m68k/kernel/signal_mm.c
deleted file mode 100644
index cb856f9da65..00000000000
--- a/arch/m68k/kernel/signal_mm.c
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * linux/arch/m68k/kernel/signal.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/*
- * Linux/m68k support by Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- *
- * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
- *
- * mathemu support by Roman Zippel
- * (Note: fpstate in the signal context is completely ignored for the emulator
- * and the internal floating point format is put on stack)
- */
-
-/*
- * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
- * Atari :-) Current limitation: Only one sigstack can be active at one time.
- * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
- * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
- * signal handlers!
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/syscalls.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/highuid.h>
-#include <linux/personality.h>
-#include <linux/tty.h>
-#include <linux/binfmts.h>
-#include <linux/module.h>
-
-#include <asm/setup.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/traps.h>
-#include <asm/ucontext.h>
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-static const int frame_extra_sizes[16] = {
- [1] = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
- [2] = sizeof(((struct frame *)0)->un.fmt2),
- [3] = sizeof(((struct frame *)0)->un.fmt3),
-#ifdef CONFIG_COLDFIRE
- [4] = 0,
-#else
- [4] = sizeof(((struct frame *)0)->un.fmt4),
-#endif
- [5] = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
- [6] = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
- [7] = sizeof(((struct frame *)0)->un.fmt7),
- [8] = -1, /* sizeof(((struct frame *)0)->un.fmt8), */
- [9] = sizeof(((struct frame *)0)->un.fmt9),
- [10] = sizeof(((struct frame *)0)->un.fmta),
- [11] = sizeof(((struct frame *)0)->un.fmtb),
- [12] = -1, /* sizeof(((struct frame *)0)->un.fmtc), */
- [13] = -1, /* sizeof(((struct frame *)0)->un.fmtd), */
- [14] = -1, /* sizeof(((struct frame *)0)->un.fmte), */
- [15] = -1, /* sizeof(((struct frame *)0)->un.fmtf), */
-};
-
-int handle_kernel_fault(struct pt_regs *regs)
-{
- const struct exception_table_entry *fixup;
- struct pt_regs *tregs;
-
- /* Are we prepared to handle this kernel fault? */
- fixup = search_exception_tables(regs->pc);
- if (!fixup)
- return 0;
-
- /* Create a new four word stack frame, discarding the old one. */
- regs->stkadj = frame_extra_sizes[regs->format];
- tregs = (struct pt_regs *)((long)regs + regs->stkadj);
- tregs->vector = regs->vector;
-#ifdef CONFIG_COLDFIRE
- tregs->format = 4;
-#else
- tregs->format = 0;
-#endif
- tregs->pc = fixup->fixup;
- tregs->sr = regs->sr;
-
- return 1;
-}
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
-{
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- current->saved_sigmask = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_restore_sigmask();
-
- return -ERESTARTNOHAND;
-}
-
-asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
- __get_user(mask, &act->sa_mask))
- return -EFAULT;
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
- return -EFAULT;
- }
-
- return ret;
-}
-
-asmlinkage int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
-{
- return do_sigaltstack(uss, uoss, rdusp());
-}
-
-
-/*
- * Do a signal return; undo the signal stack.
- *
- * Keep the return code on the stack quadword aligned!
- * That makes the cache flush below easier.
- */
-
-struct sigframe
-{
- char __user *pretcode;
- int sig;
- int code;
- struct sigcontext __user *psc;
- char retcode[8];
- unsigned long extramask[_NSIG_WORDS-1];
- struct sigcontext sc;
-};
-
-struct rt_sigframe
-{
- char __user *pretcode;
- int sig;
- struct siginfo __user *pinfo;
- void __user *puc;
- char retcode[8];
- struct siginfo info;
- struct ucontext uc;
-};
-
-
-static unsigned char fpu_version; /* version number of fpu, set by setup_frame */
-
-static inline int restore_fpu_state(struct sigcontext *sc)
-{
- int err = 1;
-
- if (FPU_IS_EMU) {
- /* restore registers */
- memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
- memcpy(current->thread.fp, sc->sc_fpregs, 24);
- return 0;
- }
-
- if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
- /* Verify the frame format. */
- if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
- (sc->sc_fpstate[0] != fpu_version))
- goto out;
- if (CPU_IS_020_OR_030) {
- if (m68k_fputype & FPU_68881 &&
- !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
- goto out;
- if (m68k_fputype & FPU_68882 &&
- !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
- goto out;
- } else if (CPU_IS_040) {
- if (!(sc->sc_fpstate[1] == 0x00 ||
- sc->sc_fpstate[1] == 0x28 ||
- sc->sc_fpstate[1] == 0x60))
- goto out;
- } else if (CPU_IS_060) {
- if (!(sc->sc_fpstate[3] == 0x00 ||
- sc->sc_fpstate[3] == 0x60 ||
- sc->sc_fpstate[3] == 0xe0))
- goto out;
- } else if (CPU_IS_COLDFIRE) {
- if (!(sc->sc_fpstate[0] == 0x00 ||
- sc->sc_fpstate[0] == 0x05 ||
- sc->sc_fpstate[0] == 0xe5))
- goto out;
- } else
- goto out;
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
- "fmovel %1,%%fpcr\n\t"
- "fmovel %2,%%fpsr\n\t"
- "fmovel %3,%%fpiar"
- : /* no outputs */
- : "m" (sc->sc_fpregs[0]),
- "m" (sc->sc_fpcntl[0]),
- "m" (sc->sc_fpcntl[1]),
- "m" (sc->sc_fpcntl[2]));
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %0,%%fp0-%%fp1\n\t"
- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
- ".chip 68k"
- : /* no outputs */
- : "m" (*sc->sc_fpregs),
- "m" (*sc->sc_fpcntl));
- }
- }
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "frestore %0\n\t"
- ".chip 68k"
- : : "m" (*sc->sc_fpstate));
- }
- err = 0;
-
-out:
- return err;
-}
-
-#define FPCONTEXT_SIZE 216
-#define uc_fpstate uc_filler[0]
-#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
-#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
-
-static inline int rt_restore_fpu_state(struct ucontext __user *uc)
-{
- unsigned char fpstate[FPCONTEXT_SIZE];
- int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
- fpregset_t fpregs;
- int err = 1;
-
- if (FPU_IS_EMU) {
- /* restore fpu control register */
- if (__copy_from_user(current->thread.fpcntl,
- uc->uc_mcontext.fpregs.f_fpcntl, 12))
- goto out;
- /* restore all other fpu register */
- if (__copy_from_user(current->thread.fp,
- uc->uc_mcontext.fpregs.f_fpregs, 96))
- goto out;
- return 0;
- }
-
- if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
- goto out;
- if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
- if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
- context_size = fpstate[1];
- /* Verify the frame format. */
- if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
- (fpstate[0] != fpu_version))
- goto out;
- if (CPU_IS_020_OR_030) {
- if (m68k_fputype & FPU_68881 &&
- !(context_size == 0x18 || context_size == 0xb4))
- goto out;
- if (m68k_fputype & FPU_68882 &&
- !(context_size == 0x38 || context_size == 0xd4))
- goto out;
- } else if (CPU_IS_040) {
- if (!(context_size == 0x00 ||
- context_size == 0x28 ||
- context_size == 0x60))
- goto out;
- } else if (CPU_IS_060) {
- if (!(fpstate[3] == 0x00 ||
- fpstate[3] == 0x60 ||
- fpstate[3] == 0xe0))
- goto out;
- } else if (CPU_IS_COLDFIRE) {
- if (!(fpstate[3] == 0x00 ||
- fpstate[3] == 0x05 ||
- fpstate[3] == 0xe5))
- goto out;
- } else
- goto out;
- if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
- sizeof(fpregs)))
- goto out;
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t"
- "fmovel %1,%%fpcr\n\t"
- "fmovel %2,%%fpsr\n\t"
- "fmovel %3,%%fpiar"
- : /* no outputs */
- : "m" (fpregs.f_fpregs[0]),
- "m" (fpregs.f_fpcntl[0]),
- "m" (fpregs.f_fpcntl[1]),
- "m" (fpregs.f_fpcntl[2]));
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %0,%%fp0-%%fp7\n\t"
- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
- ".chip 68k"
- : /* no outputs */
- : "m" (*fpregs.f_fpregs),
- "m" (*fpregs.f_fpcntl));
- }
- }
- if (context_size &&
- __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
- context_size))
- goto out;
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("frestore %0" : : "m" (*fpstate));
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "frestore %0\n\t"
- ".chip 68k"
- : : "m" (*fpstate));
- }
- err = 0;
-
-out:
- return err;
-}
-
-static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
- void __user *fp)
-{
- int fsize = frame_extra_sizes[formatvec >> 12];
- if (fsize < 0) {
- /*
- * user process trying to return with weird frame format
- */
-#ifdef DEBUG
- printk("user process returning with weird frame format\n");
-#endif
- return 1;
- }
- if (!fsize) {
- regs->format = formatvec >> 12;
- regs->vector = formatvec & 0xfff;
- } else {
- struct switch_stack *sw = (struct switch_stack *)regs - 1;
- unsigned long buf[fsize / 2]; /* yes, twice as much */
-
- /* that'll make sure that expansion won't crap over data */
- if (copy_from_user(buf + fsize / 4, fp, fsize))
- return 1;
-
- /* point of no return */
- regs->format = formatvec >> 12;
- regs->vector = formatvec & 0xfff;
-#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
- __asm__ __volatile__ (
-#ifdef CONFIG_COLDFIRE
- " movel %0,%/sp\n\t"
- " bra ret_from_signal\n"
-#else
- " movel %0,%/a0\n\t"
- " subl %1,%/a0\n\t" /* make room on stack */
- " movel %/a0,%/sp\n\t" /* set stack pointer */
- /* move switch_stack and pt_regs */
- "1: movel %0@+,%/a0@+\n\t"
- " dbra %2,1b\n\t"
- " lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
- " lsrl #2,%1\n\t"
- " subql #1,%1\n\t"
- /* copy to the gap we'd made */
- "2: movel %4@+,%/a0@+\n\t"
- " dbra %1,2b\n\t"
- " bral ret_from_signal\n"
-#endif
- : /* no outputs, it doesn't ever return */
- : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
- "n" (frame_offset), "a" (buf + fsize/4)
- : "a0");
-#undef frame_offset
- }
- return 0;
-}
-
-static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)
-{
- int formatvec;
- struct sigcontext context;
- int err;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- /* get previous context */
- if (copy_from_user(&context, usc, sizeof(context)))
- goto badframe;
-
- /* restore passed registers */
- regs->d0 = context.sc_d0;
- regs->d1 = context.sc_d1;
- regs->a0 = context.sc_a0;
- regs->a1 = context.sc_a1;
- regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
- regs->pc = context.sc_pc;
- regs->orig_d0 = -1; /* disable syscall checks */
- wrusp(context.sc_usp);
- formatvec = context.sc_formatvec;
-
- err = restore_fpu_state(&context);
-
- if (err || mangle_kernel_stack(regs, formatvec, fp))
- goto badframe;
-
- return 0;
-
-badframe:
- return 1;
-}
-
-static inline int
-rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
- struct ucontext __user *uc)
-{
- int temp;
- greg_t __user *gregs = uc->uc_mcontext.gregs;
- unsigned long usp;
- int err;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- err = __get_user(temp, &uc->uc_mcontext.version);
- if (temp != MCONTEXT_VERSION)
- goto badframe;
- /* restore passed registers */
- err |= __get_user(regs->d0, &gregs[0]);
- err |= __get_user(regs->d1, &gregs[1]);
- err |= __get_user(regs->d2, &gregs[2]);
- err |= __get_user(regs->d3, &gregs[3]);
- err |= __get_user(regs->d4, &gregs[4]);
- err |= __get_user(regs->d5, &gregs[5]);
- err |= __get_user(sw->d6, &gregs[6]);
- err |= __get_user(sw->d7, &gregs[7]);
- err |= __get_user(regs->a0, &gregs[8]);
- err |= __get_user(regs->a1, &gregs[9]);
- err |= __get_user(regs->a2, &gregs[10]);
- err |= __get_user(sw->a3, &gregs[11]);
- err |= __get_user(sw->a4, &gregs[12]);
- err |= __get_user(sw->a5, &gregs[13]);
- err |= __get_user(sw->a6, &gregs[14]);
- err |= __get_user(usp, &gregs[15]);
- wrusp(usp);
- err |= __get_user(regs->pc, &gregs[16]);
- err |= __get_user(temp, &gregs[17]);
- regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
- regs->orig_d0 = -1; /* disable syscall checks */
- err |= __get_user(temp, &uc->uc_formatvec);
-
- err |= rt_restore_fpu_state(uc);
-
- if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
- goto badframe;
-
- if (mangle_kernel_stack(regs, temp, &uc->uc_extra))
- goto badframe;
-
- return 0;
-
-badframe:
- return 1;
-}
-
-asmlinkage int do_sigreturn(unsigned long __unused)
-{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
- unsigned long usp = rdusp();
- struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
- sigset_t set;
-
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
- (_NSIG_WORDS > 1 &&
- __copy_from_user(&set.sig[1], &frame->extramask,
- sizeof(frame->extramask))))
- goto badframe;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- current->blocked = set;
- recalc_sigpending();
-
- if (restore_sigcontext(regs, &frame->sc, frame + 1))
- goto badframe;
- return regs->d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-asmlinkage int do_rt_sigreturn(unsigned long __unused)
-{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
- unsigned long usp = rdusp();
- struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
- sigset_t set;
-
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
- goto badframe;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- current->blocked = set;
- recalc_sigpending();
-
- if (rt_restore_ucontext(regs, sw, &frame->uc))
- goto badframe;
- return regs->d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-/*
- * Set up a signal frame.
- */
-
-static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
-{
- if (FPU_IS_EMU) {
- /* save registers */
- memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
- memcpy(sc->sc_fpregs, current->thread.fp, 24);
- return;
- }
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fsave %0"
- : : "m" (*sc->sc_fpstate) : "memory");
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fsave %0\n\t"
- ".chip 68k"
- : : "m" (*sc->sc_fpstate) : "memory");
- }
-
- if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
- fpu_version = sc->sc_fpstate[0];
- if (CPU_IS_020_OR_030 &&
- regs->vector >= (VEC_FPBRUC * 4) &&
- regs->vector <= (VEC_FPNAN * 4)) {
- /* Clear pending exception in 68882 idle frame */
- if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
- sc->sc_fpstate[0x38] |= 1 << 3;
- }
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t"
- "fmovel %%fpcr,%1\n\t"
- "fmovel %%fpsr,%2\n\t"
- "fmovel %%fpiar,%3"
- : "=m" (sc->sc_fpregs[0]),
- "=m" (sc->sc_fpcntl[0]),
- "=m" (sc->sc_fpcntl[1]),
- "=m" (sc->sc_fpcntl[2])
- : /* no inputs */
- : "memory");
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %%fp0-%%fp1,%0\n\t"
- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
- ".chip 68k"
- : "=m" (*sc->sc_fpregs),
- "=m" (*sc->sc_fpcntl)
- : /* no inputs */
- : "memory");
- }
- }
-}
-
-static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
-{
- unsigned char fpstate[FPCONTEXT_SIZE];
- int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
- int err = 0;
-
- if (FPU_IS_EMU) {
- /* save fpu control register */
- err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
- current->thread.fpcntl, 12);
- /* save all other fpu register */
- err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
- current->thread.fp, 96);
- return err;
- }
-
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory");
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fsave %0\n\t"
- ".chip 68k"
- : : "m" (*fpstate) : "memory");
- }
-
- err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
- if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
- fpregset_t fpregs;
- if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
- context_size = fpstate[1];
- fpu_version = fpstate[0];
- if (CPU_IS_020_OR_030 &&
- regs->vector >= (VEC_FPBRUC * 4) &&
- regs->vector <= (VEC_FPNAN * 4)) {
- /* Clear pending exception in 68882 idle frame */
- if (*(unsigned short *) fpstate == 0x1f38)
- fpstate[0x38] |= 1 << 3;
- }
- if (CPU_IS_COLDFIRE) {
- __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t"
- "fmovel %%fpcr,%1\n\t"
- "fmovel %%fpsr,%2\n\t"
- "fmovel %%fpiar,%3"
- : "=m" (fpregs.f_fpregs[0]),
- "=m" (fpregs.f_fpcntl[0]),
- "=m" (fpregs.f_fpcntl[1]),
- "=m" (fpregs.f_fpcntl[2])
- : /* no inputs */
- : "memory");
- } else {
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %%fp0-%%fp7,%0\n\t"
- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
- ".chip 68k"
- : "=m" (*fpregs.f_fpregs),
- "=m" (*fpregs.f_fpcntl)
- : /* no inputs */
- : "memory");
- }
- err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
- sizeof(fpregs));
- }
- if (context_size)
- err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
- context_size);
- return err;
-}
-
-static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
- unsigned long mask)
-{
- sc->sc_mask = mask;
- sc->sc_usp = rdusp();
- sc->sc_d0 = regs->d0;
- sc->sc_d1 = regs->d1;
- sc->sc_a0 = regs->a0;
- sc->sc_a1 = regs->a1;
- sc->sc_sr = regs->sr;
- sc->sc_pc = regs->pc;
- sc->sc_formatvec = regs->format << 12 | regs->vector;
- save_fpu_state(sc, regs);
-}
-
-static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *)regs - 1;
- greg_t __user *gregs = uc->uc_mcontext.gregs;
- int err = 0;
-
- err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
- err |= __put_user(regs->d0, &gregs[0]);
- err |= __put_user(regs->d1, &gregs[1]);
- err |= __put_user(regs->d2, &gregs[2]);
- err |= __put_user(regs->d3, &gregs[3]);
- err |= __put_user(regs->d4, &gregs[4]);
- err |= __put_user(regs->d5, &gregs[5]);
- err |= __put_user(sw->d6, &gregs[6]);
- err |= __put_user(sw->d7, &gregs[7]);
- err |= __put_user(regs->a0, &gregs[8]);
- err |= __put_user(regs->a1, &gregs[9]);
- err |= __put_user(regs->a2, &gregs[10]);
- err |= __put_user(sw->a3, &gregs[11]);
- err |= __put_user(sw->a4, &gregs[12]);
- err |= __put_user(sw->a5, &gregs[13]);
- err |= __put_user(sw->a6, &gregs[14]);
- err |= __put_user(rdusp(), &gregs[15]);
- err |= __put_user(regs->pc, &gregs[16]);
- err |= __put_user(regs->sr, &gregs[17]);
- err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
- err |= rt_save_fpu_state(uc, regs);
- return err;
-}
-
-static inline void push_cache (unsigned long vaddr)
-{
- /*
- * Using the old cache_push_v() was really a big waste.
- *
- * What we are trying to do is to flush 8 bytes to ram.
- * Flushing 2 cache lines of 16 bytes is much cheaper than
- * flushing 1 or 2 pages, as previously done in
- * cache_push_v().
- * Jes
- */
- if (CPU_IS_040) {
- unsigned long temp;
-
- __asm__ __volatile__ (".chip 68040\n\t"
- "nop\n\t"
- "ptestr (%1)\n\t"
- "movec %%mmusr,%0\n\t"
- ".chip 68k"
- : "=r" (temp)
- : "a" (vaddr));
-
- temp &= PAGE_MASK;
- temp |= vaddr & ~PAGE_MASK;
-
- __asm__ __volatile__ (".chip 68040\n\t"
- "nop\n\t"
- "cpushl %%bc,(%0)\n\t"
- ".chip 68k"
- : : "a" (temp));
- }
- else if (CPU_IS_060) {
- unsigned long temp;
- __asm__ __volatile__ (".chip 68060\n\t"
- "plpar (%0)\n\t"
- ".chip 68k"
- : "=a" (temp)
- : "0" (vaddr));
- __asm__ __volatile__ (".chip 68060\n\t"
- "cpushl %%bc,(%0)\n\t"
- ".chip 68k"
- : : "a" (temp));
- } else if (!CPU_IS_COLDFIRE) {
- /*
- * 68030/68020 have no writeback cache;
- * still need to clear icache.
- * Note that vaddr is guaranteed to be long word aligned.
- */
- unsigned long temp;
- asm volatile ("movec %%cacr,%0" : "=r" (temp));
- temp += 4;
- asm volatile ("movec %0,%%caar\n\t"
- "movec %1,%%cacr"
- : : "r" (vaddr), "r" (temp));
- asm volatile ("movec %0,%%caar\n\t"
- "movec %1,%%cacr"
- : : "r" (vaddr + 4), "r" (temp));
- }
-}
-
-static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
-{
- unsigned long usp;
-
- /* Default to using normal stack. */
- usp = rdusp();
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!sas_ss_flags(usp))
- usp = current->sas_ss_sp + current->sas_ss_size;
- }
- return (void __user *)((usp - frame_size) & -8UL);
-}
-
-static int setup_frame (int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
-{
- struct sigframe __user *frame;
- int fsize = frame_extra_sizes[regs->format];
- struct sigcontext context;
- int err = 0;
-
- if (fsize < 0) {
-#ifdef DEBUG
- printk ("setup_frame: Unknown frame format %#x\n",
- regs->format);
-#endif
- goto give_sigsegv;
- }
-
- frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
-
- if (fsize)
- err |= copy_to_user (frame + 1, regs + 1, fsize);
-
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
-
- err |= __put_user(regs->vector, &frame->code);
- err |= __put_user(&frame->sc, &frame->psc);
-
- if (_NSIG_WORDS > 1)
- err |= copy_to_user(frame->extramask, &set->sig[1],
- sizeof(frame->extramask));
-
- setup_sigcontext(&context, regs, set->sig[0]);
- err |= copy_to_user (&frame->sc, &context, sizeof(context));
-
- /* Set up to return from userspace. */
- err |= __put_user(frame->retcode, &frame->pretcode);
- /* moveq #,d0; trap #0 */
- err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
- (long __user *)(frame->retcode));
-
- if (err)
- goto give_sigsegv;
-
- push_cache ((unsigned long) &frame->retcode);
-
- /*
- * Set up registers for signal handler. All the state we are about
- * to destroy is successfully copied to sigframe.
- */
- wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
-
- /*
- * This is subtle; if we build more than one sigframe, all but the
- * first one will see frame format 0 and have fsize == 0, so we won't
- * screw stkadj.
- */
- if (fsize)
- regs->stkadj = fsize;
-
- /* Prepare to skip over the extra stuff in the exception frame. */
- if (regs->stkadj) {
- struct pt_regs *tregs =
- (struct pt_regs *)((ulong)regs + regs->stkadj);
-#ifdef DEBUG
- printk("Performing stackadjust=%04x\n", regs->stkadj);
-#endif
- /* This must be copied with decreasing addresses to
- handle overlaps. */
- tregs->vector = 0;
- tregs->format = 0;
- tregs->pc = regs->pc;
- tregs->sr = regs->sr;
- }
- return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return err;
-}
-
-static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
-{
- struct rt_sigframe __user *frame;
- int fsize = frame_extra_sizes[regs->format];
- int err = 0;
-
- if (fsize < 0) {
-#ifdef DEBUG
- printk ("setup_frame: Unknown frame format %#x\n",
- regs->format);
-#endif
- goto give_sigsegv;
- }
-
- frame = get_sigframe(ka, regs, sizeof(*frame));
-
- if (fsize)
- err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
-
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
- err |= __put_user(&frame->info, &frame->pinfo);
- err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
-
- /* Create the ucontext. */
- err |= __put_user(0, &frame->uc.uc_flags);
- err |= __put_user(NULL, &frame->uc.uc_link);
- err |= __put_user((void __user *)current->sas_ss_sp,
- &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(rdusp()),
- &frame->uc.uc_stack.ss_flags);
- err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= rt_setup_ucontext(&frame->uc, regs);
- err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
-
- /* Set up to return from userspace. */
- err |= __put_user(frame->retcode, &frame->pretcode);
-#ifdef __mcoldfire__
- /* movel #__NR_rt_sigreturn,d0; trap #0 */
- err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));
- err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),
- (long __user *)(frame->retcode + 4));
-#else
- /* moveq #,d0; notb d0; trap #0 */
- err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
- (long __user *)(frame->retcode + 0));
- err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
-#endif
-
- if (err)
- goto give_sigsegv;
-
- push_cache ((unsigned long) &frame->retcode);
-
- /*
- * Set up registers for signal handler. All the state we are about
- * to destroy is successfully copied to sigframe.
- */
- wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
-
- /*
- * This is subtle; if we build more than one sigframe, all but the
- * first one will see frame format 0 and have fsize == 0, so we won't
- * screw stkadj.
- */
- if (fsize)
- regs->stkadj = fsize;
-
- /* Prepare to skip over the extra stuff in the exception frame. */
- if (regs->stkadj) {
- struct pt_regs *tregs =
- (struct pt_regs *)((ulong)regs + regs->stkadj);
-#ifdef DEBUG
- printk("Performing stackadjust=%04x\n", regs->stkadj);
-#endif
- /* This must be copied with decreasing addresses to
- handle overlaps. */
- tregs->vector = 0;
- tregs->format = 0;
- tregs->pc = regs->pc;
- tregs->sr = regs->sr;
- }
- return 0;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- return err;
-}
-
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
- switch (regs->d0) {
- case -ERESTARTNOHAND:
- if (!has_handler)
- goto do_restart;
- regs->d0 = -EINTR;
- break;
-
- case -ERESTART_RESTARTBLOCK:
- if (!has_handler) {
- regs->d0 = __NR_restart_syscall;
- regs->pc -= 2;
- break;
- }
- regs->d0 = -EINTR;
- break;
-
- case -ERESTARTSYS:
- if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
- regs->d0 = -EINTR;
- break;
- }
- /* fallthrough */
- case -ERESTARTNOINTR:
- do_restart:
- regs->d0 = regs->orig_d0;
- regs->pc -= 2;
- break;
- }
-}
-
-void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
-{
- if (regs->orig_d0 < 0)
- return;
- switch (regs->d0) {
- case -ERESTARTNOHAND:
- case -ERESTARTSYS:
- case -ERESTARTNOINTR:
- regs->d0 = regs->orig_d0;
- regs->orig_d0 = -1;
- regs->pc -= 2;
- break;
- }
-}
-
-/*
- * OK, we're invoking a handler
- */
-static void
-handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *oldset, struct pt_regs *regs)
-{
- int err;
- /* are we from a system call? */
- if (regs->orig_d0 >= 0)
- /* If so, check system call restarting.. */
- handle_restart(regs, ka, 1);
-
- /* set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- err = setup_rt_frame(sig, ka, info, oldset, regs);
- else
- err = setup_frame(sig, ka, oldset, regs);
-
- if (err)
- return;
-
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked,sig);
- recalc_sigpending();
-
- if (test_thread_flag(TIF_DELAYED_TRACE)) {
- regs->sr &= ~0x8000;
- send_sig(SIGTRAP, current, 1);
- }
-
- clear_thread_flag(TIF_RESTORE_SIGMASK);
-}
-
-/*
- * 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.
- */
-asmlinkage void do_signal(struct pt_regs *regs)
-{
- siginfo_t info;
- struct k_sigaction ka;
- int signr;
- sigset_t *oldset;
-
- current->thread.esp0 = (unsigned long) regs;
-
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- /* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, oldset, regs);
- return;
- }
-
- /* Did we come from a system call? */
- if (regs->orig_d0 >= 0)
- /* Restart the system call - no handlers present */
- handle_restart(regs, NULL, 0);
-
- /* If there's no signal to deliver, we just restore the saved mask. */
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
- }
-}
diff --git a/arch/m68k/kernel/signal_no.c b/arch/m68k/kernel/signal_no.c
deleted file mode 100644
index 36a81bb6835..00000000000
--- a/arch/m68k/kernel/signal_no.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/signal.c
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-/*
- * Linux/m68k support by Hamish Macdonald
- *
- * 68060 fixes by Jesper Skov
- *
- * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab
- *
- * mathemu support by Roman Zippel
- * (Note: fpstate in the signal context is completely ignored for the emulator
- * and the internal floating point format is put on stack)
- */
-
-/*
- * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
- * Atari :-) Current limitation: Only one sigstack can be active at one time.
- * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
- * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
- * signal handlers!
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/syscalls.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
-#include <linux/unistd.h>
-#include <linux/stddef.h>
-#include <linux/highuid.h>
-#include <linux/tty.h>
-#include <linux/personality.h>
-#include <linux/binfmts.h>
-
-#include <asm/setup.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/traps.h>
-#include <asm/ucontext.h>
-
-#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-
-void ret_from_user_signal(void);
-void ret_from_user_rt_signal(void);
-
-/*
- * Atomically swap in the new signal mask, and wait for a signal.
- */
-asmlinkage int
-sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
-{
- mask &= _BLOCKABLE;
- spin_lock_irq(&current->sighand->siglock);
- current->saved_sigmask = current->blocked;
- siginitset(&current->blocked, mask);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule();
- set_restore_sigmask();
-
- return -ERESTARTNOHAND;
-}
-
-asmlinkage int
-sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
- __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
- __get_user(mask, &act->sa_mask))
- return -EFAULT;
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
- return -EFAULT;
- }
-
- return ret;
-}
-
-asmlinkage int
-sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
-{
- return do_sigaltstack(uss, uoss, rdusp());
-}
-
-
-/*
- * Do a signal return; undo the signal stack.
- *
- * Keep the return code on the stack quadword aligned!
- * That makes the cache flush below easier.
- */
-
-struct sigframe
-{
- char __user *pretcode;
- int sig;
- int code;
- struct sigcontext __user *psc;
- char retcode[8];
- unsigned long extramask[_NSIG_WORDS-1];
- struct sigcontext sc;
-};
-
-struct rt_sigframe
-{
- char __user *pretcode;
- int sig;
- struct siginfo __user *pinfo;
- void __user *puc;
- char retcode[8];
- struct siginfo info;
- struct ucontext uc;
-};
-
-#ifdef CONFIG_FPU
-
-static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */
-
-static inline int restore_fpu_state(struct sigcontext *sc)
-{
- int err = 1;
-
- if (FPU_IS_EMU) {
- /* restore registers */
- memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
- memcpy(current->thread.fp, sc->sc_fpregs, 24);
- return 0;
- }
-
- if (sc->sc_fpstate[0]) {
- /* Verify the frame format. */
- if (sc->sc_fpstate[0] != fpu_version)
- goto out;
-
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %0,%%fp0-%%fp1\n\t"
- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
- ".chip 68k"
- : /* no outputs */
- : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
- }
- __asm__ volatile (".chip 68k/68881\n\t"
- "frestore %0\n\t"
- ".chip 68k" : : "m" (*sc->sc_fpstate));
- err = 0;
-
-out:
- return err;
-}
-
-#define FPCONTEXT_SIZE 216
-#define uc_fpstate uc_filler[0]
-#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4]
-#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1]
-
-static inline int rt_restore_fpu_state(struct ucontext __user *uc)
-{
- unsigned char fpstate[FPCONTEXT_SIZE];
- int context_size = 0;
- fpregset_t fpregs;
- int err = 1;
-
- if (FPU_IS_EMU) {
- /* restore fpu control register */
- if (__copy_from_user(current->thread.fpcntl,
- uc->uc_mcontext.fpregs.f_fpcntl, 12))
- goto out;
- /* restore all other fpu register */
- if (__copy_from_user(current->thread.fp,
- uc->uc_mcontext.fpregs.f_fpregs, 96))
- goto out;
- return 0;
- }
-
- if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
- goto out;
- if (fpstate[0]) {
- context_size = fpstate[1];
-
- /* Verify the frame format. */
- if (fpstate[0] != fpu_version)
- goto out;
- if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
- sizeof(fpregs)))
- goto out;
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %0,%%fp0-%%fp7\n\t"
- "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
- ".chip 68k"
- : /* no outputs */
- : "m" (*fpregs.f_fpregs),
- "m" (*fpregs.f_fpcntl));
- }
- if (context_size &&
- __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
- context_size))
- goto out;
- __asm__ volatile (".chip 68k/68881\n\t"
- "frestore %0\n\t"
- ".chip 68k" : : "m" (*fpstate));
- err = 0;
-
-out:
- return err;
-}
-
-#endif
-
-static inline int
-restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp,
- int *pd0)
-{
- int formatvec;
- struct sigcontext context;
- int err = 0;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- /* get previous context */
- if (copy_from_user(&context, usc, sizeof(context)))
- goto badframe;
-
- /* restore passed registers */
- regs->d1 = context.sc_d1;
- regs->a0 = context.sc_a0;
- regs->a1 = context.sc_a1;
- ((struct switch_stack *)regs - 1)->a5 = context.sc_a5;
- regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
- regs->pc = context.sc_pc;
- regs->orig_d0 = -1; /* disable syscall checks */
- wrusp(context.sc_usp);
- formatvec = context.sc_formatvec;
- regs->format = formatvec >> 12;
- regs->vector = formatvec & 0xfff;
-
-#ifdef CONFIG_FPU
- err = restore_fpu_state(&context);
-#endif
-
- *pd0 = context.sc_d0;
- return err;
-
-badframe:
- return 1;
-}
-
-static inline int
-rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
- struct ucontext __user *uc, int *pd0)
-{
- int temp;
- greg_t __user *gregs = uc->uc_mcontext.gregs;
- unsigned long usp;
- int err;
-
- /* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
-
- err = __get_user(temp, &uc->uc_mcontext.version);
- if (temp != MCONTEXT_VERSION)
- goto badframe;
- /* restore passed registers */
- err |= __get_user(regs->d0, &gregs[0]);
- err |= __get_user(regs->d1, &gregs[1]);
- err |= __get_user(regs->d2, &gregs[2]);
- err |= __get_user(regs->d3, &gregs[3]);
- err |= __get_user(regs->d4, &gregs[4]);
- err |= __get_user(regs->d5, &gregs[5]);
- err |= __get_user(sw->d6, &gregs[6]);
- err |= __get_user(sw->d7, &gregs[7]);
- err |= __get_user(regs->a0, &gregs[8]);
- err |= __get_user(regs->a1, &gregs[9]);
- err |= __get_user(regs->a2, &gregs[10]);
- err |= __get_user(sw->a3, &gregs[11]);
- err |= __get_user(sw->a4, &gregs[12]);
- err |= __get_user(sw->a5, &gregs[13]);
- err |= __get_user(sw->a6, &gregs[14]);
- err |= __get_user(usp, &gregs[15]);
- wrusp(usp);
- err |= __get_user(regs->pc, &gregs[16]);
- err |= __get_user(temp, &gregs[17]);
- regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
- regs->orig_d0 = -1; /* disable syscall checks */
- regs->format = temp >> 12;
- regs->vector = temp & 0xfff;
-
- if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
- goto badframe;
-
- *pd0 = regs->d0;
- return err;
-
-badframe:
- return 1;
-}
-
-asmlinkage int do_sigreturn(unsigned long __unused)
-{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
- unsigned long usp = rdusp();
- struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
- sigset_t set;
- int d0;
-
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
- (_NSIG_WORDS > 1 &&
- __copy_from_user(&set.sig[1], &frame->extramask,
- sizeof(frame->extramask))))
- goto badframe;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0))
- goto badframe;
- return d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-asmlinkage int do_rt_sigreturn(unsigned long __unused)
-{
- struct switch_stack *sw = (struct switch_stack *) &__unused;
- struct pt_regs *regs = (struct pt_regs *) (sw + 1);
- unsigned long usp = rdusp();
- struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
- sigset_t set;
- int d0;
-
- if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
- goto badframe;
- if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
- goto badframe;
-
- sigdelsetmask(&set, ~_BLOCKABLE);
- spin_lock_irq(&current->sighand->siglock);
- current->blocked = set;
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- if (rt_restore_ucontext(regs, sw, &frame->uc, &d0))
- goto badframe;
- return d0;
-
-badframe:
- force_sig(SIGSEGV, current);
- return 0;
-}
-
-#ifdef CONFIG_FPU
-/*
- * Set up a signal frame.
- */
-
-static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
-{
- if (FPU_IS_EMU) {
- /* save registers */
- memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
- memcpy(sc->sc_fpregs, current->thread.fp, 24);
- return;
- }
-
- __asm__ volatile (".chip 68k/68881\n\t"
- "fsave %0\n\t"
- ".chip 68k"
- : : "m" (*sc->sc_fpstate) : "memory");
-
- if (sc->sc_fpstate[0]) {
- fpu_version = sc->sc_fpstate[0];
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %%fp0-%%fp1,%0\n\t"
- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
- ".chip 68k"
- : "=m" (*sc->sc_fpregs),
- "=m" (*sc->sc_fpcntl)
- : /* no inputs */
- : "memory");
- }
-}
-
-static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
-{
- unsigned char fpstate[FPCONTEXT_SIZE];
- int context_size = 0;
- int err = 0;
-
- if (FPU_IS_EMU) {
- /* save fpu control register */
- err |= copy_to_user(uc->uc_mcontext.fpregs.f_pcntl,
- current->thread.fpcntl, 12);
- /* save all other fpu register */
- err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
- current->thread.fp, 96);
- return err;
- }
-
- __asm__ volatile (".chip 68k/68881\n\t"
- "fsave %0\n\t"
- ".chip 68k"
- : : "m" (*fpstate) : "memory");
-
- err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
- if (fpstate[0]) {
- fpregset_t fpregs;
- context_size = fpstate[1];
- fpu_version = fpstate[0];
- __asm__ volatile (".chip 68k/68881\n\t"
- "fmovemx %%fp0-%%fp7,%0\n\t"
- "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
- ".chip 68k"
- : "=m" (*fpregs.f_fpregs),
- "=m" (*fpregs.f_fpcntl)
- : /* no inputs */
- : "memory");
- err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
- sizeof(fpregs));
- }
- if (context_size)
- err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
- context_size);
- return err;
-}
-
-#endif
-
-static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
- unsigned long mask)
-{
- sc->sc_mask = mask;
- sc->sc_usp = rdusp();
- sc->sc_d0 = regs->d0;
- sc->sc_d1 = regs->d1;
- sc->sc_a0 = regs->a0;
- sc->sc_a1 = regs->a1;
- sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
- sc->sc_sr = regs->sr;
- sc->sc_pc = regs->pc;
- sc->sc_formatvec = regs->format << 12 | regs->vector;
-#ifdef CONFIG_FPU
- save_fpu_state(sc, regs);
-#endif
-}
-
-static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
-{
- struct switch_stack *sw = (struct switch_stack *)regs - 1;
- greg_t __user *gregs = uc->uc_mcontext.gregs;
- int err = 0;
-
- err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
- err |= __put_user(regs->d0, &gregs[0]);
- err |= __put_user(regs->d1, &gregs[1]);
- err |= __put_user(regs->d2, &gregs[2]);
- err |= __put_user(regs->d3, &gregs[3]);
- err |= __put_user(regs->d4, &gregs[4]);
- err |= __put_user(regs->d5, &gregs[5]);
- err |= __put_user(sw->d6, &gregs[6]);
- err |= __put_user(sw->d7, &gregs[7]);
- err |= __put_user(regs->a0, &gregs[8]);
- err |= __put_user(regs->a1, &gregs[9]);
- err |= __put_user(regs->a2, &gregs[10]);
- err |= __put_user(sw->a3, &gregs[11]);
- err |= __put_user(sw->a4, &gregs[12]);
- err |= __put_user(sw->a5, &gregs[13]);
- err |= __put_user(sw->a6, &gregs[14]);
- err |= __put_user(rdusp(), &gregs[15]);
- err |= __put_user(regs->pc, &gregs[16]);
- err |= __put_user(regs->sr, &gregs[17]);
-#ifdef CONFIG_FPU
- err |= rt_save_fpu_state(uc, regs);
-#endif
- return err;
-}
-
-static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
-{
- unsigned long usp;
-
- /* Default to using normal stack. */
- usp = rdusp();
-
- /* This is the X/Open sanctioned signal stack switching. */
- if (ka->sa.sa_flags & SA_ONSTACK) {
- if (!sas_ss_flags(usp))
- usp = current->sas_ss_sp + current->sas_ss_size;
- }
- return (void __user *)((usp - frame_size) & -8UL);
-}
-
-static int setup_frame (int sig, struct k_sigaction *ka,
- sigset_t *set, struct pt_regs *regs)
-{
- struct sigframe __user *frame;
- struct sigcontext context;
- int err = 0;
-
- frame = get_sigframe(ka, regs, sizeof(*frame));
-
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
-
- err |= __put_user(regs->vector, &frame->code);
- err |= __put_user(&frame->sc, &frame->psc);
-
- if (_NSIG_WORDS > 1)
- err |= copy_to_user(frame->extramask, &set->sig[1],
- sizeof(frame->extramask));
-
- setup_sigcontext(&context, regs, set->sig[0]);
- err |= copy_to_user (&frame->sc, &context, sizeof(context));
-
- /* Set up to return from userspace. */
- err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
-
- if (err)
- goto give_sigsegv;
-
- /* Set up registers for signal handler */
- wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
- ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
- regs->format = 0x4; /*set format byte to make stack appear modulo 4
- which it will be when doing the rte */
-
-adjust_stack:
- /* Prepare to skip over the extra stuff in the exception frame. */
- if (regs->stkadj) {
- struct pt_regs *tregs =
- (struct pt_regs *)((ulong)regs + regs->stkadj);
-#if defined(DEBUG)
- printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
-#endif
- /* This must be copied with decreasing addresses to
- handle overlaps. */
- tregs->vector = 0;
- tregs->format = 0;
- tregs->pc = regs->pc;
- tregs->sr = regs->sr;
- }
- return err;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- goto adjust_stack;
-}
-
-static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *set, struct pt_regs *regs)
-{
- struct rt_sigframe __user *frame;
- int err = 0;
-
- frame = get_sigframe(ka, regs, sizeof(*frame));
-
- err |= __put_user((current_thread_info()->exec_domain
- && current_thread_info()->exec_domain->signal_invmap
- && sig < 32
- ? current_thread_info()->exec_domain->signal_invmap[sig]
- : sig),
- &frame->sig);
- err |= __put_user(&frame->info, &frame->pinfo);
- err |= __put_user(&frame->uc, &frame->puc);
- err |= copy_siginfo_to_user(&frame->info, info);
-
- /* Create the ucontext. */
- err |= __put_user(0, &frame->uc.uc_flags);
- err |= __put_user(NULL, &frame->uc.uc_link);
- err |= __put_user((void __user *)current->sas_ss_sp,
- &frame->uc.uc_stack.ss_sp);
- err |= __put_user(sas_ss_flags(rdusp()),
- &frame->uc.uc_stack.ss_flags);
- err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
- err |= rt_setup_ucontext(&frame->uc, regs);
- err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
-
- /* Set up to return from userspace. */
- err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
-
- if (err)
- goto give_sigsegv;
-
- /* Set up registers for signal handler */
- wrusp ((unsigned long) frame);
- regs->pc = (unsigned long) ka->sa.sa_handler;
- ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
- regs->format = 0x4; /*set format byte to make stack appear modulo 4
- which it will be when doing the rte */
-
-adjust_stack:
- /* Prepare to skip over the extra stuff in the exception frame. */
- if (regs->stkadj) {
- struct pt_regs *tregs =
- (struct pt_regs *)((ulong)regs + regs->stkadj);
-#if defined(DEBUG)
- printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj);
-#endif
- /* This must be copied with decreasing addresses to
- handle overlaps. */
- tregs->vector = 0;
- tregs->format = 0;
- tregs->pc = regs->pc;
- tregs->sr = regs->sr;
- }
- return err;
-
-give_sigsegv:
- force_sigsegv(sig, current);
- goto adjust_stack;
-}
-
-static inline void
-handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
-{
- switch (regs->d0) {
- case -ERESTARTNOHAND:
- if (!has_handler)
- goto do_restart;
- regs->d0 = -EINTR;
- break;
-
- case -ERESTART_RESTARTBLOCK:
- if (!has_handler) {
- regs->d0 = __NR_restart_syscall;
- regs->pc -= 2;
- break;
- }
- regs->d0 = -EINTR;
- break;
-
- case -ERESTARTSYS:
- if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
- regs->d0 = -EINTR;
- break;
- }
- /* fallthrough */
- case -ERESTARTNOINTR:
- do_restart:
- regs->d0 = regs->orig_d0;
- regs->pc -= 2;
- break;
- }
-}
-
-/*
- * OK, we're invoking a handler
- */
-static void
-handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
- sigset_t *oldset, struct pt_regs *regs)
-{
- int err;
- /* are we from a system call? */
- if (regs->orig_d0 >= 0)
- /* If so, check system call restarting.. */
- handle_restart(regs, ka, 1);
-
- /* set up the stack frame */
- if (ka->sa.sa_flags & SA_SIGINFO)
- err = setup_rt_frame(sig, ka, info, oldset, regs);
- else
- err = setup_frame(sig, ka, oldset, regs);
-
- if (err)
- return;
-
- spin_lock_irq(&current->sighand->siglock);
- sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
- if (!(ka->sa.sa_flags & SA_NODEFER))
- sigaddset(&current->blocked,sig);
- recalc_sigpending();
- spin_unlock_irq(&current->sighand->siglock);
-
- clear_thread_flag(TIF_RESTORE_SIGMASK);
-}
-
-/*
- * 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.
- */
-asmlinkage void do_signal(struct pt_regs *regs)
-{
- struct k_sigaction ka;
- siginfo_t info;
- int signr;
- sigset_t *oldset;
-
- /*
- * 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;
-
- if (test_thread_flag(TIF_RESTORE_SIGMASK))
- oldset = &current->saved_sigmask;
- else
- oldset = &current->blocked;
-
- signr = get_signal_to_deliver(&info, &ka, regs, NULL);
- if (signr > 0) {
- /* Whee! Actually deliver the signal. */
- handle_signal(signr, &ka, &info, oldset, regs);
- return;
- }
-
- /* Did we come from a system call? */
- if (regs->orig_d0 >= 0) {
- /* Restart the system call - no handlers present */
- handle_restart(regs, NULL, 0);
- }
-
- /* If there's no signal to deliver, we just restore the saved mask. */
- if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
- clear_thread_flag(TIF_RESTORE_SIGMASK);
- sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
- }
-}
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index 8623f8dc16f..3a480b3df0d 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -479,9 +479,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5,
goto bad_access;
}
- mem_value = *mem;
+ /*
+ * No need to check for EFAULT; we know that the page is
+ * present and writable.
+ */
+ __get_user(mem_value, mem);
if (mem_value == oldval)
- *mem = newval;
+ __put_user(newval, mem);
pte_unmap_unlock(pte, ptl);
up_read(&mm->mmap_sem);
@@ -545,23 +549,6 @@ asmlinkage int sys_getpagesize(void)
return PAGE_SIZE;
}
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
- const char *const argv[],
- const char *const envp[])
-{
- register long __res asm ("%d0") = __NR_execve;
- register long __a asm ("%d1") = (long)(filename);
- register long __b asm ("%d2") = (long)(argv);
- register long __c asm ("%d3") = (long)(envp);
- asm volatile ("trap #0" : "+d" (__res)
- : "d" (__a), "d" (__b), "d" (__c));
- return __res;
-}
-
asmlinkage unsigned long sys_get_thread_area(void)
{
return current_thread_info()->tp_value;
diff --git a/arch/m68k/kernel/syscalltable.S b/arch/m68k/kernel/syscalltable.S
index ce827b37611..501e1021278 100644
--- a/arch/m68k/kernel/syscalltable.S
+++ b/arch/m68k/kernel/syscalltable.S
@@ -22,7 +22,7 @@ ALIGN
ENTRY(sys_call_table)
.long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
.long sys_exit
- .long sys_fork
+ .long __sys_fork
.long sys_read
.long sys_write
.long sys_open /* 5 */
@@ -140,7 +140,7 @@ ENTRY(sys_call_table)
.long sys_ipc
.long sys_fsync
.long sys_sigreturn
- .long sys_clone /* 120 */
+ .long __sys_clone /* 120 */
.long sys_setdomainname
.long sys_newuname
.long sys_cacheflush /* modify_ldt for i386 */
@@ -210,7 +210,7 @@ ENTRY(sys_call_table)
.long sys_sendfile
.long sys_ni_syscall /* streams1 */
.long sys_ni_syscall /* streams2 */
- .long sys_vfork /* 190 */
+ .long __sys_vfork /* 190 */
.long sys_getrlimit
.long sys_mmap2
.long sys_truncate64
@@ -367,4 +367,9 @@ ENTRY(sys_call_table)
.long sys_setns
.long sys_process_vm_readv /* 345 */
.long sys_process_vm_writev
+ .long sys_kcmp
+ .long sys_finit_module
+ .long sys_sched_setattr
+ .long sys_sched_getattr /* 350 */
+ .long sys_renameat2
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 75ab79b3bde..3857737e395 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -1,5 +1,109 @@
-#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE)
-#include "time_mm.c"
-#else
-#include "time_no.c"
-#endif
+/*
+ * linux/arch/m68k/kernel/time.c
+ *
+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds
+ *
+ * This file contains the m68k-specific time handling details.
+ * Most of the stuff is located in the machine specific files.
+ *
+ * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
+ */
+
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/irq_regs.h>
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/profile.h>
+
+
+unsigned long (*mach_random_get_entropy)(void);
+EXPORT_SYMBOL_GPL(mach_random_get_entropy);
+
+
+/*
+ * timer_interrupt() needs to keep up the real-time clock,
+ * as well as call the "xtime_update()" routine every clocktick
+ */
+static irqreturn_t timer_interrupt(int irq, void *dummy)
+{
+ xtime_update(1);
+ update_process_times(user_mode(get_irq_regs()));
+ profile_tick(CPU_PROFILING);
+
+#ifdef CONFIG_HEARTBEAT
+ /* use power LED as a heartbeat instead -- much more useful
+ for debugging -- based on the version for PReP by Cort */
+ /* acts like an actual heart beat -- ie thump-thump-pause... */
+ if (mach_heartbeat) {
+ static unsigned cnt = 0, period = 0, dist = 0;
+
+ if (cnt == 0 || cnt == dist)
+ mach_heartbeat( 1 );
+ else if (cnt == 7 || cnt == dist+7)
+ mach_heartbeat( 0 );
+
+ if (++cnt > period) {
+ cnt = 0;
+ /* The hyperbolic function below modifies the heartbeat period
+ * length in dependency of the current (5min) load. It goes
+ * through the points f(0)=126, f(1)=86, f(5)=51,
+ * f(inf)->30. */
+ period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
+ dist = period / 4;
+ }
+ }
+#endif /* CONFIG_HEARTBEAT */
+ return IRQ_HANDLED;
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ struct rtc_time time;
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+
+ if (mach_hwclk) {
+ mach_hwclk(0, &time);
+
+ if ((time.tm_year += 1900) < 1970)
+ time.tm_year += 100;
+ ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
+ time.tm_hour, time.tm_min, time.tm_sec);
+ }
+}
+
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+
+static int __init rtc_init(void)
+{
+ struct platform_device *pdev;
+
+ if (!mach_hwclk)
+ return -ENODEV;
+
+ pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
+ return PTR_ERR_OR_ZERO(pdev);
+}
+
+module_init(rtc_init);
+
+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */
+
+void __init time_init(void)
+{
+ mach_sched_init(timer_interrupt);
+}
diff --git a/arch/m68k/kernel/time_mm.c b/arch/m68k/kernel/time_mm.c
deleted file mode 100644
index 18b34ee5db3..00000000000
--- a/arch/m68k/kernel/time_mm.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * linux/arch/m68k/kernel/time.c
- *
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- *
- * This file contains the m68k-specific time handling details.
- * Most of the stuff is located in the machine specific files.
- *
- * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
- * "A Kernel Model for Precision Timekeeping" by Dave Mills
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/irq_regs.h>
-
-#include <linux/time.h>
-#include <linux/timex.h>
-#include <linux/profile.h>
-
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- if (mach_set_clock_mmss)
- return mach_set_clock_mmss (nowtime);
- return -1;
-}
-
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "xtime_update()" routine every clocktick
- */
-static irqreturn_t timer_interrupt(int irq, void *dummy)
-{
- xtime_update(1);
- update_process_times(user_mode(get_irq_regs()));
- profile_tick(CPU_PROFILING);
-
-#ifdef CONFIG_HEARTBEAT
- /* use power LED as a heartbeat instead -- much more useful
- for debugging -- based on the version for PReP by Cort */
- /* acts like an actual heart beat -- ie thump-thump-pause... */
- if (mach_heartbeat) {
- static unsigned cnt = 0, period = 0, dist = 0;
-
- if (cnt == 0 || cnt == dist)
- mach_heartbeat( 1 );
- else if (cnt == 7 || cnt == dist+7)
- mach_heartbeat( 0 );
-
- if (++cnt > period) {
- cnt = 0;
- /* The hyperbolic function below modifies the heartbeat period
- * length in dependency of the current (5min) load. It goes
- * through the points f(0)=126, f(1)=86, f(5)=51,
- * f(inf)->30. */
- period = ((672<<FSHIFT)/(5*avenrun[0]+(7<<FSHIFT))) + 30;
- dist = period / 4;
- }
- }
-#endif /* CONFIG_HEARTBEAT */
- return IRQ_HANDLED;
-}
-
-void read_persistent_clock(struct timespec *ts)
-{
- struct rtc_time time;
- ts->tv_sec = 0;
- ts->tv_nsec = 0;
-
- if (mach_hwclk) {
- mach_hwclk(0, &time);
-
- if ((time.tm_year += 1900) < 1970)
- time.tm_year += 100;
- ts->tv_sec = mktime(time.tm_year, time.tm_mon, time.tm_mday,
- time.tm_hour, time.tm_min, time.tm_sec);
- }
-}
-
-void __init time_init(void)
-{
- mach_sched_init(timer_interrupt);
-}
-
-u32 arch_gettimeoffset(void)
-{
- return mach_gettimeoffset() * 1000;
-}
-
-static int __init rtc_init(void)
-{
- struct platform_device *pdev;
-
- if (!mach_hwclk)
- return -ENODEV;
-
- pdev = platform_device_register_simple("rtc-generic", -1, NULL, 0);
- if (IS_ERR(pdev))
- return PTR_ERR(pdev);
-
- return 0;
-}
-
-module_init(rtc_init);
diff --git a/arch/m68k/kernel/time_no.c b/arch/m68k/kernel/time_no.c
deleted file mode 100644
index 3ef0f7768dc..00000000000
--- a/arch/m68k/kernel/time_no.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/time.c
- *
- * Copyright (C) 1991, 1992, 1995 Linus Torvalds
- *
- * This file contains the m68k-specific time handling details.
- * Most of the stuff is located in the machine specific files.
- *
- * 1997-09-10 Updated NTP code according to technical memorandum Jan '96
- * "A Kernel Model for Precision Timekeeping" by Dave Mills
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/profile.h>
-#include <linux/time.h>
-#include <linux/timex.h>
-
-#include <asm/machdep.h>
-#include <asm/irq_regs.h>
-
-#define TICK_SIZE (tick_nsec / 1000)
-
-/* machine dependent timer functions */
-void (*mach_gettod)(int*, int*, int*, int*, int*, int*);
-
-static inline int set_rtc_mmss(unsigned long nowtime)
-{
- if (mach_set_clock_mmss)
- return mach_set_clock_mmss (nowtime);
- return -1;
-}
-
-#ifndef CONFIG_GENERIC_CLOCKEVENTS
-/*
- * timer_interrupt() needs to keep up the real-time clock,
- * as well as call the "xtime_update()" routine every clocktick
- */
-irqreturn_t arch_timer_interrupt(int irq, void *dummy)
-{
-
- if (current->pid)
- profile_tick(CPU_PROFILING);
-
- xtime_update(1);
-
- update_process_times(user_mode(get_irq_regs()));
-
- return(IRQ_HANDLED);
-}
-#endif
-
-static unsigned long read_rtc_mmss(void)
-{
- unsigned int year, mon, day, hour, min, sec;
-
- if (mach_gettod) {
- mach_gettod(&year, &mon, &day, &hour, &min, &sec);
- if ((year += 1900) < 1970)
- year += 100;
- } else {
- year = 1970;
- mon = day = 1;
- hour = min = sec = 0;
- }
-
-
- return mktime(year, mon, day, hour, min, sec);
-}
-
-void read_persistent_clock(struct timespec *ts)
-{
- ts->tv_sec = read_rtc_mmss();
- ts->tv_nsec = 0;
-}
-
-int update_persistent_clock(struct timespec now)
-{
- return set_rtc_mmss(now.tv_sec);
-}
-
-void time_init(void)
-{
- hw_timer_init();
-}
diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c
index daaa9187654..6c9ca24830e 100644
--- a/arch/m68k/kernel/traps.c
+++ b/arch/m68k/kernel/traps.c
@@ -32,7 +32,6 @@
#include <asm/setup.h>
#include <asm/fpu.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/traps.h>
#include <asm/pgalloc.h>
@@ -134,9 +133,7 @@ static inline void access_error060 (struct frame *fp)
{
unsigned long fslw = fp->un.fmt4.pc; /* is really FSLW for access error */
-#ifdef DEBUG
- printk("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
-#endif
+ pr_debug("fslw=%#lx, fa=%#lx\n", fslw, fp->un.fmt4.effaddr);
if (fslw & MMU060_BPE) {
/* branch prediction error -> clear branch cache */
@@ -163,9 +160,7 @@ static inline void access_error060 (struct frame *fp)
}
if (fslw & MMU060_W)
errorcode |= 2;
-#ifdef DEBUG
- printk("errorcode = %d\n", errorcode );
-#endif
+ pr_debug("errorcode = %ld\n", errorcode);
do_page_fault(&fp->ptregs, addr, errorcode);
} else if (fslw & (MMU060_SEE)){
/* Software Emulation Error.
@@ -174,8 +169,9 @@ static inline void access_error060 (struct frame *fp)
send_fault_sig(&fp->ptregs);
} else if (!(fslw & (MMU060_RE|MMU060_WE)) ||
send_fault_sig(&fp->ptregs) > 0) {
- printk("pc=%#lx, fa=%#lx\n", fp->ptregs.pc, fp->un.fmt4.effaddr);
- printk( "68060 access error, fslw=%lx\n", fslw );
+ pr_err("pc=%#lx, fa=%#lx\n", fp->ptregs.pc,
+ fp->un.fmt4.effaddr);
+ pr_err("68060 access error, fslw=%lx\n", fslw);
trap_c( fp );
}
}
@@ -226,9 +222,7 @@ static inline int do_040writeback1(unsigned short wbs, unsigned long wba,
set_fs(old_fs);
-#ifdef DEBUG
- printk("do_040writeback1, res=%d\n",res);
-#endif
+ pr_debug("do_040writeback1, res=%d\n", res);
return res;
}
@@ -250,7 +244,7 @@ static inline void do_040writebacks(struct frame *fp)
int res = 0;
#if 0
if (fp->un.fmt7.wb1s & WBV_040)
- printk("access_error040: cannot handle 1st writeback. oops.\n");
+ pr_err("access_error040: cannot handle 1st writeback. oops.\n");
#endif
if ((fp->un.fmt7.wb2s & WBV_040) &&
@@ -303,14 +297,12 @@ static inline void access_error040(struct frame *fp)
unsigned short ssw = fp->un.fmt7.ssw;
unsigned long mmusr;
-#ifdef DEBUG
- printk("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
- printk("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
+ pr_debug("ssw=%#x, fa=%#lx\n", ssw, fp->un.fmt7.faddr);
+ pr_debug("wb1s=%#x, wb2s=%#x, wb3s=%#x\n", fp->un.fmt7.wb1s,
fp->un.fmt7.wb2s, fp->un.fmt7.wb3s);
- printk ("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
+ pr_debug("wb2a=%lx, wb3a=%lx, wb2d=%lx, wb3d=%lx\n",
fp->un.fmt7.wb2a, fp->un.fmt7.wb3a,
fp->un.fmt7.wb2d, fp->un.fmt7.wb3d);
-#endif
if (ssw & ATC_040) {
unsigned long addr = fp->un.fmt7.faddr;
@@ -325,9 +317,7 @@ static inline void access_error040(struct frame *fp)
/* MMU error, get the MMUSR info for this access */
mmusr = probe040(!(ssw & RW_040), addr, ssw);
-#ifdef DEBUG
- printk("mmusr = %lx\n", mmusr);
-#endif
+ pr_debug("mmusr = %lx\n", mmusr);
errorcode = 1;
if (!(mmusr & MMU_R_040)) {
/* clear the invalid atc entry */
@@ -341,14 +331,10 @@ static inline void access_error040(struct frame *fp)
errorcode |= 2;
if (do_page_fault(&fp->ptregs, addr, errorcode)) {
-#ifdef DEBUG
- printk("do_page_fault() !=0\n");
-#endif
+ pr_debug("do_page_fault() !=0\n");
if (user_mode(&fp->ptregs)){
/* delay writebacks after signal delivery */
-#ifdef DEBUG
- printk(".. was usermode - return\n");
-#endif
+ pr_debug(".. was usermode - return\n");
return;
}
/* disable writeback into user space from kernel
@@ -356,9 +342,7 @@ static inline void access_error040(struct frame *fp)
* the writeback won't do good)
*/
disable_wb:
-#ifdef DEBUG
- printk(".. disabling wb2\n");
-#endif
+ pr_debug(".. disabling wb2\n");
if (fp->un.fmt7.wb2a == fp->un.fmt7.faddr)
fp->un.fmt7.wb2s &= ~WBV_040;
if (fp->un.fmt7.wb3a == fp->un.fmt7.faddr)
@@ -372,7 +356,7 @@ disable_wb:
current->thread.signo = SIGBUS;
current->thread.faddr = fp->un.fmt7.faddr;
if (send_fault_sig(&fp->ptregs) >= 0)
- printk("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
+ pr_err("68040 bus error (ssw=%x, faddr=%lx)\n", ssw,
fp->un.fmt7.faddr);
goto disable_wb;
}
@@ -395,19 +379,17 @@ static inline void bus_error030 (struct frame *fp)
unsigned short ssw = fp->un.fmtb.ssw;
extern unsigned long _sun3_map_test_start, _sun3_map_test_end;
-#ifdef DEBUG
if (ssw & (FC | FB))
- printk ("Instruction fault at %#010lx\n",
+ pr_debug("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+ pr_debug("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
-#endif
/*
* Check if this page should be demand-mapped. This needs to go before
@@ -430,7 +412,7 @@ static inline void bus_error030 (struct frame *fp)
return;
/* instruction fault or kernel data fault! */
if (ssw & (FC | FB))
- printk ("Instruction fault at %#010lx\n",
+ pr_err("Instruction fault at %#010lx\n",
fp->ptregs.pc);
if (ssw & DF) {
/* was this fault incurred testing bus mappings? */
@@ -440,12 +422,12 @@ static inline void bus_error030 (struct frame *fp)
return;
}
- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+ pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
}
- printk ("BAD KERNEL BUSERR\n");
+ pr_err("BAD KERNEL BUSERR\n");
die_if_kernel("Oops", &fp->ptregs,0);
force_sig(SIGKILL, current);
@@ -474,12 +456,11 @@ static inline void bus_error030 (struct frame *fp)
else if (buserr_type & SUN3_BUSERR_INVALID)
errorcode = 0x00;
else {
-#ifdef DEBUG
- printk ("*** unexpected busfault type=%#04x\n", buserr_type);
- printk ("invalid %s access at %#lx from pc %#lx\n",
- !(ssw & RW) ? "write" : "read", addr,
- fp->ptregs.pc);
-#endif
+ pr_debug("*** unexpected busfault type=%#04x\n",
+ buserr_type);
+ pr_debug("invalid %s access at %#lx from pc %#lx\n",
+ !(ssw & RW) ? "write" : "read", addr,
+ fp->ptregs.pc);
die_if_kernel ("Oops", &fp->ptregs, buserr_type);
force_sig (SIGBUS, current);
return;
@@ -507,12 +488,10 @@ static inline void bus_error030 (struct frame *fp)
addr -= 2;
if (buserr_type & SUN3_BUSERR_INVALID) {
- if (!mmu_emu_handle_fault (fp->un.fmtb.daddr, 1, 0))
+ if (!mmu_emu_handle_fault(addr, 1, 0))
do_page_fault (&fp->ptregs, addr, 0);
} else {
-#ifdef DEBUG
- printk ("protection fault on insn access (segv).\n");
-#endif
+ pr_debug("protection fault on insn access (segv).\n");
force_sig (SIGSEGV, current);
}
}
@@ -526,22 +505,22 @@ static inline void bus_error030 (struct frame *fp)
unsigned short ssw = fp->un.fmtb.ssw;
#ifdef DEBUG
unsigned long desc;
+#endif
- printk ("pid = %x ", current->pid);
- printk ("SSW=%#06x ", ssw);
+ pr_debug("pid = %x ", current->pid);
+ pr_debug("SSW=%#06x ", ssw);
if (ssw & (FC | FB))
- printk ("Instruction fault at %#010lx\n",
+ pr_debug("Instruction fault at %#010lx\n",
ssw & FC ?
fp->ptregs.format == 0xa ? fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2
:
fp->ptregs.format == 0xa ? fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+ pr_debug("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
-#endif
/* ++andreas: If a data fault and an instruction fault happen
at the same time map in both pages. */
@@ -555,27 +534,23 @@ static inline void bus_error030 (struct frame *fp)
"pmove %%psr,%1"
: "=a&" (desc), "=m" (temp)
: "a" (addr), "d" (ssw));
+ pr_debug("mmusr is %#x for addr %#lx in task %p\n",
+ temp, addr, current);
+ pr_debug("descriptor address is 0x%p, contents %#lx\n",
+ __va(desc), *(unsigned long *)__va(desc));
#else
asm volatile ("ptestr %2,%1@,#7\n\t"
"pmove %%psr,%0"
: "=m" (temp) : "a" (addr), "d" (ssw));
#endif
mmusr = temp;
-
-#ifdef DEBUG
- printk("mmusr is %#x for addr %#lx in task %p\n",
- mmusr, addr, current);
- printk("descriptor address is %#lx, contents %#lx\n",
- __va(desc), *(unsigned long *)__va(desc));
-#endif
-
errorcode = (mmusr & MMU_I) ? 0 : 1;
if (!(ssw & RW) || (ssw & RM))
errorcode |= 2;
if (mmusr & (MMU_I | MMU_WP)) {
if (ssw & 4) {
- printk("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+ pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr,
space_names[ssw & DFC], fp->ptregs.pc);
@@ -588,9 +563,10 @@ static inline void bus_error030 (struct frame *fp)
} else if (!(mmusr & MMU_I)) {
/* probably a 020 cas fault */
if (!(ssw & RM) && send_fault_sig(&fp->ptregs) > 0)
- printk("unexpected bus error (%#x,%#x)\n", ssw, mmusr);
+ pr_err("unexpected bus error (%#x,%#x)\n", ssw,
+ mmusr);
} else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
- printk("invalid %s access at %#lx from pc %#lx\n",
+ pr_err("invalid %s access at %#lx from pc %#lx\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc);
die_if_kernel("Oops",&fp->ptregs,mmusr);
@@ -601,7 +577,7 @@ static inline void bus_error030 (struct frame *fp)
static volatile long tlong;
#endif
- printk("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
+ pr_err("weird %s access at %#lx from pc %#lx (ssw is %#x)\n",
!(ssw & RW) ? "write" : "read", addr,
fp->ptregs.pc, ssw);
asm volatile ("ptestr #1,%1@,#0\n\t"
@@ -610,18 +586,16 @@ static inline void bus_error030 (struct frame *fp)
: "a" (addr));
mmusr = temp;
- printk ("level 0 mmusr is %#x\n", mmusr);
+ pr_err("level 0 mmusr is %#x\n", mmusr);
#if 0
asm volatile ("pmove %%tt0,%0"
: "=m" (tlong));
- printk("tt0 is %#lx, ", tlong);
+ pr_debug("tt0 is %#lx, ", tlong);
asm volatile ("pmove %%tt1,%0"
: "=m" (tlong));
- printk("tt1 is %#lx\n", tlong);
-#endif
-#ifdef DEBUG
- printk("Unknown SIGSEGV - 1\n");
+ pr_debug("tt1 is %#lx\n", tlong);
#endif
+ pr_debug("Unknown SIGSEGV - 1\n");
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
@@ -642,10 +616,9 @@ static inline void bus_error030 (struct frame *fp)
return;
if (fp->ptregs.sr & PS_S) {
- printk("Instruction fault at %#010lx\n",
- fp->ptregs.pc);
+ pr_err("Instruction fault at %#010lx\n", fp->ptregs.pc);
buserr:
- printk ("BAD KERNEL BUSERR\n");
+ pr_err("BAD KERNEL BUSERR\n");
die_if_kernel("Oops",&fp->ptregs,0);
force_sig(SIGKILL, current);
return;
@@ -669,28 +642,22 @@ static inline void bus_error030 (struct frame *fp)
"pmove %%psr,%1"
: "=a&" (desc), "=m" (temp)
: "a" (addr));
+ pr_debug("mmusr is %#x for addr %#lx in task %p\n",
+ temp, addr, current);
+ pr_debug("descriptor address is 0x%p, contents %#lx\n",
+ __va(desc), *(unsigned long *)__va(desc));
#else
asm volatile ("ptestr #1,%1@,#7\n\t"
"pmove %%psr,%0"
: "=m" (temp) : "a" (addr));
#endif
mmusr = temp;
-
-#ifdef DEBUG
- printk ("mmusr is %#x for addr %#lx in task %p\n",
- mmusr, addr, current);
- printk ("descriptor address is %#lx, contents %#lx\n",
- __va(desc), *(unsigned long *)__va(desc));
-#endif
-
if (mmusr & MMU_I)
do_page_fault (&fp->ptregs, addr, 0);
else if (mmusr & (MMU_B|MMU_L|MMU_S)) {
- printk ("invalid insn access at %#lx from pc %#lx\n",
+ pr_err("invalid insn access at %#lx from pc %#lx\n",
addr, fp->ptregs.pc);
-#ifdef DEBUG
- printk("Unknown SIGSEGV - 2\n");
-#endif
+ pr_debug("Unknown SIGSEGV - 2\n");
die_if_kernel("Oops",&fp->ptregs,mmusr);
force_sig(SIGSEGV, current);
return;
@@ -792,9 +759,7 @@ asmlinkage void buserr_c(struct frame *fp)
if (user_mode(&fp->ptregs))
current->thread.esp0 = (unsigned long) fp;
-#ifdef DEBUG
- printk ("*** Bus Error *** Format is %x\n", fp->ptregs.format);
-#endif
+ pr_debug("*** Bus Error *** Format is %x\n", fp->ptregs.format);
#if defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
if (CPU_IS_COLDFIRE) {
@@ -837,9 +802,7 @@ asmlinkage void buserr_c(struct frame *fp)
#endif
default:
die_if_kernel("bad frame format",&fp->ptregs,0);
-#ifdef DEBUG
- printk("Unknown SIGSEGV - 4\n");
-#endif
+ pr_debug("Unknown SIGSEGV - 4\n");
force_sig(SIGSEGV, current);
}
}
@@ -853,7 +816,7 @@ void show_trace(unsigned long *stack)
unsigned long addr;
int i;
- printk("Call Trace:");
+ pr_info("Call Trace:");
addr = (unsigned long)stack + THREAD_SIZE - 1;
endstack = (unsigned long *)(addr & -THREAD_SIZE);
i = 0;
@@ -870,13 +833,13 @@ void show_trace(unsigned long *stack)
if (__kernel_text_address(addr)) {
#ifndef CONFIG_KALLSYMS
if (i % 5 == 0)
- printk("\n ");
+ pr_cont("\n ");
#endif
- printk(" [<%08lx>] %pS\n", addr, (void *)addr);
+ pr_cont(" [<%08lx>] %pS\n", addr, (void *)addr);
i++;
}
}
- printk("\n");
+ pr_cont("\n");
}
void show_registers(struct pt_regs *regs)
@@ -888,81 +851,87 @@ void show_registers(struct pt_regs *regs)
int i;
print_modules();
- printk("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
- printk("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
- printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
+ pr_info("PC: [<%08lx>] %pS\n", regs->pc, (void *)regs->pc);
+ pr_info("SR: %04x SP: %p a2: %08lx\n", regs->sr, regs, regs->a2);
+ pr_info("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
regs->d0, regs->d1, regs->d2, regs->d3);
- printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
+ pr_info("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
regs->d4, regs->d5, regs->a0, regs->a1);
- printk("Process %s (pid: %d, task=%p)\n",
+ pr_info("Process %s (pid: %d, task=%p)\n",
current->comm, task_pid_nr(current), current);
addr = (unsigned long)&fp->un;
- printk("Frame format=%X ", regs->format);
+ pr_info("Frame format=%X ", regs->format);
switch (regs->format) {
case 0x2:
- printk("instr addr=%08lx\n", fp->un.fmt2.iaddr);
+ pr_cont("instr addr=%08lx\n", fp->un.fmt2.iaddr);
addr += sizeof(fp->un.fmt2);
break;
case 0x3:
- printk("eff addr=%08lx\n", fp->un.fmt3.effaddr);
+ pr_cont("eff addr=%08lx\n", fp->un.fmt3.effaddr);
addr += sizeof(fp->un.fmt3);
break;
case 0x4:
- printk((CPU_IS_060 ? "fault addr=%08lx fslw=%08lx\n"
- : "eff addr=%08lx pc=%08lx\n"),
- fp->un.fmt4.effaddr, fp->un.fmt4.pc);
+ if (CPU_IS_060)
+ pr_cont("fault addr=%08lx fslw=%08lx\n",
+ fp->un.fmt4.effaddr, fp->un.fmt4.pc);
+ else
+ pr_cont("eff addr=%08lx pc=%08lx\n",
+ fp->un.fmt4.effaddr, fp->un.fmt4.pc);
addr += sizeof(fp->un.fmt4);
break;
case 0x7:
- printk("eff addr=%08lx ssw=%04x faddr=%08lx\n",
+ pr_cont("eff addr=%08lx ssw=%04x faddr=%08lx\n",
fp->un.fmt7.effaddr, fp->un.fmt7.ssw, fp->un.fmt7.faddr);
- printk("wb 1 stat/addr/data: %04x %08lx %08lx\n",
+ pr_info("wb 1 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb1s, fp->un.fmt7.wb1a, fp->un.fmt7.wb1dpd0);
- printk("wb 2 stat/addr/data: %04x %08lx %08lx\n",
+ pr_info("wb 2 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb2s, fp->un.fmt7.wb2a, fp->un.fmt7.wb2d);
- printk("wb 3 stat/addr/data: %04x %08lx %08lx\n",
+ pr_info("wb 3 stat/addr/data: %04x %08lx %08lx\n",
fp->un.fmt7.wb3s, fp->un.fmt7.wb3a, fp->un.fmt7.wb3d);
- printk("push data: %08lx %08lx %08lx %08lx\n",
+ pr_info("push data: %08lx %08lx %08lx %08lx\n",
fp->un.fmt7.wb1dpd0, fp->un.fmt7.pd1, fp->un.fmt7.pd2,
fp->un.fmt7.pd3);
addr += sizeof(fp->un.fmt7);
break;
case 0x9:
- printk("instr addr=%08lx\n", fp->un.fmt9.iaddr);
+ pr_cont("instr addr=%08lx\n", fp->un.fmt9.iaddr);
addr += sizeof(fp->un.fmt9);
break;
case 0xa:
- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+ pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmta.ssw, fp->un.fmta.isc, fp->un.fmta.isb,
fp->un.fmta.daddr, fp->un.fmta.dobuf);
addr += sizeof(fp->un.fmta);
break;
case 0xb:
- printk("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
+ pr_cont("ssw=%04x isc=%04x isb=%04x daddr=%08lx dobuf=%08lx\n",
fp->un.fmtb.ssw, fp->un.fmtb.isc, fp->un.fmtb.isb,
fp->un.fmtb.daddr, fp->un.fmtb.dobuf);
- printk("baddr=%08lx dibuf=%08lx ver=%x\n",
+ pr_info("baddr=%08lx dibuf=%08lx ver=%x\n",
fp->un.fmtb.baddr, fp->un.fmtb.dibuf, fp->un.fmtb.ver);
addr += sizeof(fp->un.fmtb);
break;
default:
- printk("\n");
+ pr_cont("\n");
}
show_stack(NULL, (unsigned long *)addr);
- printk("Code:");
+ pr_info("Code:");
set_fs(KERNEL_DS);
cp = (u16 *)regs->pc;
for (i = -8; i < 16; i++) {
if (get_user(c, cp + i) && i >= 0) {
- printk(" Bad PC value.");
+ pr_cont(" Bad PC value.");
break;
}
- printk(i ? " %04x" : " <%04x>", c);
+ if (i)
+ pr_cont(" %04x", c);
+ else
+ pr_cont(" <%04x>", c);
}
set_fs(old_fs);
- printk ("\n");
+ pr_cont("\n");
}
void show_stack(struct task_struct *task, unsigned long *stack)
@@ -979,32 +948,20 @@ void show_stack(struct task_struct *task, unsigned long *stack)
}
endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1) & -THREAD_SIZE);
- printk("Stack from %08lx:", (unsigned long)stack);
+ pr_info("Stack from %08lx:", (unsigned long)stack);
p = stack;
for (i = 0; i < kstack_depth_to_print; i++) {
if (p + 1 > endstack)
break;
if (i % 8 == 0)
- printk("\n ");
- printk(" %08lx", *p++);
+ pr_cont("\n ");
+ pr_cont(" %08lx", *p++);
}
- printk("\n");
+ pr_cont("\n");
show_trace(stack);
}
/*
- * The architecture-independent backtrace generator
- */
-void dump_stack(void)
-{
- unsigned long stack;
-
- show_trace(&stack);
-}
-
-EXPORT_SYMBOL(dump_stack);
-
-/*
* The vector number returned in the frame pointer may also contain
* the "fs" (Fault Status) bits on ColdFire. These are in the bottom
* 2 bits, and upper 2 bits. So we need to mask out the real vector
@@ -1018,32 +975,32 @@ void bad_super_trap (struct frame *fp)
console_verbose();
if (vector < ARRAY_SIZE(vec_names))
- printk ("*** %s *** FORMAT=%X\n",
+ pr_err("*** %s *** FORMAT=%X\n",
vec_names[vector],
fp->ptregs.format);
else
- printk ("*** Exception %d *** FORMAT=%X\n",
+ pr_err("*** Exception %d *** FORMAT=%X\n",
vector, fp->ptregs.format);
if (vector == VEC_ADDRERR && CPU_IS_020_OR_030) {
unsigned short ssw = fp->un.fmtb.ssw;
- printk ("SSW=%#06x ", ssw);
+ pr_err("SSW=%#06x ", ssw);
if (ssw & RC)
- printk ("Pipe stage C instruction fault at %#010lx\n",
+ pr_err("Pipe stage C instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 2 : fp->un.fmtb.baddr - 2);
if (ssw & RB)
- printk ("Pipe stage B instruction fault at %#010lx\n",
+ pr_err("Pipe stage B instruction fault at %#010lx\n",
(fp->ptregs.format) == 0xA ?
fp->ptregs.pc + 4 : fp->un.fmtb.baddr);
if (ssw & DF)
- printk ("Data %s fault at %#010lx in %s (pc=%#lx)\n",
+ pr_err("Data %s fault at %#010lx in %s (pc=%#lx)\n",
ssw & RW ? "read" : "write",
fp->un.fmtb.daddr, space_names[ssw & DFC],
fp->ptregs.pc);
}
- printk ("Current process id is %d\n", task_pid_nr(current));
+ pr_err("Current process id is %d\n", task_pid_nr(current));
die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
}
@@ -1175,9 +1132,9 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
return;
console_verbose();
- printk("%s: %08x\n",str,nr);
+ pr_crit("%s: %08x\n", str, nr);
show_registers(fp);
- add_taint(TAINT_DIE);
+ add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
do_exit(SIGSEGV);
}
diff --git a/arch/m68k/kernel/vectors.c b/arch/m68k/kernel/vectors.c
index 147b03fbc71..322c977bb9e 100644
--- a/arch/m68k/kernel/vectors.c
+++ b/arch/m68k/kernel/vectors.c
@@ -25,7 +25,6 @@
#include <asm/setup.h>
#include <asm/fpu.h>
-#include <asm/system.h>
#include <asm/traps.h>
/* assembler routines */
diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds
index 8e66ccb0935..06a763f49fd 100644
--- a/arch/m68k/kernel/vmlinux-nommu.lds
+++ b/arch/m68k/kernel/vmlinux-nommu.lds
@@ -1,195 +1,91 @@
/*
* vmlinux.lds.S -- master linker script for m68knommu arch
*
- * (C) Copyright 2002-2006, Greg Ungerer <gerg@snapgear.com>
+ * (C) Copyright 2002-2012, Greg Ungerer <gerg@snapgear.com>
*
* This linker script is equipped to build either ROM loaded or RAM
* run kernels.
*/
-#include <asm-generic/vmlinux.lds.h>
-#include <asm/page.h>
-#include <asm/thread_info.h>
-
#if defined(CONFIG_RAMKERNEL)
-#define RAM_START CONFIG_KERNELBASE
-#define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE)
-#define TEXT ram
-#define DATA ram
-#define INIT ram
-#define BSSS ram
-#endif
-#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
-#define RAM_START CONFIG_RAMBASE
-#define RAM_LENGTH CONFIG_RAMSIZE
-#define ROMVEC_START CONFIG_ROMVEC
-#define ROMVEC_LENGTH CONFIG_ROMVECSIZE
-#define ROM_START CONFIG_ROMSTART
-#define ROM_LENGTH CONFIG_ROMSIZE
-#define TEXT rom
-#define DATA ram
-#define INIT ram
-#define BSSS ram
+#define KTEXT_ADDR CONFIG_KERNELBASE
#endif
-
-#ifndef DATA_ADDR
-#define DATA_ADDR
+#if defined(CONFIG_ROMKERNEL)
+#define KTEXT_ADDR CONFIG_ROMSTART
+#define KDATA_ADDR CONFIG_KERNELBASE
+#define LOAD_OFFSET KDATA_ADDR + (ADDR(.text) + SIZEOF(.text))
#endif
+#include <asm/page.h>
+#include <asm/thread_info.h>
+#include <asm-generic/vmlinux.lds.h>
OUTPUT_ARCH(m68k)
ENTRY(_start)
-MEMORY {
- ram : ORIGIN = RAM_START, LENGTH = RAM_LENGTH
-#ifdef ROM_START
- romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
- rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH
-#endif
-}
-
jiffies = jiffies_64 + 4;
SECTIONS {
-#ifdef ROMVEC_START
- . = ROMVEC_START ;
+#ifdef CONFIG_ROMVEC
+ . = CONFIG_ROMVEC;
.romvec : {
- __rom_start = . ;
+ __rom_start = .;
_romvec = .;
+ *(.romvec)
*(.data..initvect)
- } > romvec
+ }
#endif
+ . = KTEXT_ADDR;
+
+ _text = .;
+ _stext = .;
.text : {
- _text = .;
- _stext = . ;
HEAD_TEXT
TEXT_TEXT
SCHED_TEXT
LOCK_TEXT
- *(.text..lock)
*(.fixup)
+ . = ALIGN(16);
+ }
+ _etext = .;
+
+#ifdef KDATA_ADDR
+ . = KDATA_ADDR;
+#endif
+
+ _sdata = .;
+ RO_DATA_SECTION(PAGE_SIZE)
+ RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
+ _edata = .;
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
- *(__ex_table)
- __stop___ex_table = .;
-
- *(.rodata) *(.rodata.*)
- *(__vermagic) /* Kernel version magic */
- *(.rodata1)
- *(.rodata.str1.1)
-
- /* Kernel symbol table: Normal symbols */
- . = ALIGN(4);
- __start___ksymtab = .;
- *(SORT(___ksymtab+*))
- __stop___ksymtab = .;
-
- /* Kernel symbol table: GPL-only symbols */
- __start___ksymtab_gpl = .;
- *(SORT(___ksymtab_gpl+*))
- __stop___ksymtab_gpl = .;
-
- /* Kernel symbol table: Normal unused symbols */
- __start___ksymtab_unused = .;
- *(SORT(___ksymtab_unused+*))
- __stop___ksymtab_unused = .;
-
- /* Kernel symbol table: GPL-only unused symbols */
- __start___ksymtab_unused_gpl = .;
- *(SORT(___ksymtab_unused_gpl+*))
- __stop___ksymtab_unused_gpl = .;
-
- /* Kernel symbol table: GPL-future symbols */
- __start___ksymtab_gpl_future = .;
- *(SORT(___ksymtab_gpl_future+*))
- __stop___ksymtab_gpl_future = .;
-
- /* Kernel symbol table: Normal symbols */
- __start___kcrctab = .;
- *(SORT(___kcrctab+*))
- __stop___kcrctab = .;
-
- /* Kernel symbol table: GPL-only symbols */
- __start___kcrctab_gpl = .;
- *(SORT(___kcrctab_gpl+*))
- __stop___kcrctab_gpl = .;
-
- /* Kernel symbol table: Normal unused symbols */
- __start___kcrctab_unused = .;
- *(SORT(___kcrctab_unused+*))
- __stop___kcrctab_unused = .;
-
- /* Kernel symbol table: GPL-only unused symbols */
- __start___kcrctab_unused_gpl = .;
- *(SORT(___kcrctab_unused_gpl+*))
- __stop___kcrctab_unused_gpl = .;
-
- /* Kernel symbol table: GPL-future symbols */
- __start___kcrctab_gpl_future = .;
- *(SORT(___kcrctab_gpl_future+*))
- __stop___kcrctab_gpl_future = .;
-
- /* Kernel symbol table: strings */
- *(__ksymtab_strings)
-
- /* Built-in module parameters */
- . = ALIGN(4) ;
- __start___param = .;
- *(__param)
- __stop___param = .;
-
- /* Built-in module versions */
- . = ALIGN(4) ;
- __start___modver = .;
- *(__modver)
- __stop___modver = .;
-
- . = ALIGN(4) ;
- _etext = . ;
- } > TEXT
-
- .data DATA_ADDR : {
- . = ALIGN(4);
- _sdata = . ;
- DATA_DATA
- CACHELINE_ALIGNED_DATA(32)
- PAGE_ALIGNED_DATA(PAGE_SIZE)
- *(.data..shared_aligned)
- INIT_TASK_DATA(THREAD_SIZE)
- _edata = . ;
- } > DATA
+ EXCEPTION_TABLE(16)
+ NOTES
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
+ INIT_TEXT_SECTION(PAGE_SIZE)
+ INIT_DATA_SECTION(16)
+ PERCPU_SECTION(16)
.m68k_fixup : {
__start_fixup = .;
*(.m68k_fixup)
__stop_fixup = .;
- } > DATA
- NOTES > DATA
-
- .init.text : {
- . = ALIGN(PAGE_SIZE);
- __init_begin = .;
- } > INIT
- INIT_TEXT_SECTION(PAGE_SIZE) > INIT
- INIT_DATA_SECTION(16) > INIT
+ }
.init.data : {
. = ALIGN(PAGE_SIZE);
__init_end = .;
- } > INIT
-
- .bss : {
- . = ALIGN(4);
- _sbss = . ;
- *(.bss)
- *(COMMON)
- . = ALIGN(4) ;
- _ebss = . ;
- _end = . ;
- } > BSSS
+ }
+
+ BSS_SECTION(0, 0, 0)
+
+ _end = .;
+
+ STABS_DEBUG
+ .comment 0 : { *(.comment) }
+ /* Sections to be discarded */
DISCARDS
}
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds
index 63407c83682..d0993594f55 100644
--- a/arch/m68k/kernel/vmlinux-std.lds
+++ b/arch/m68k/kernel/vmlinux-std.lds
@@ -31,9 +31,7 @@ SECTIONS
RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
- _sbss = .;
BSS_SECTION(0, 0, 0)
- _ebss = .;
_edata = .; /* End of data section */
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index ad0f46d64c0..8080469ee6c 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -44,9 +44,7 @@ __init_begin = .;
. = ALIGN(PAGE_SIZE);
__init_end = .;
- _sbss = .;
BSS_SECTION(0, 0, 0)
- _ebss = .;
_end = . ;