summary refs log tree commit diff
path: root/arch/m68knommu/kernel
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/m68knommu/kernel
downloadlinux-1da177e4c3f41524e886b7f1b8a0c1fc7321cac2.tar.gz
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
Diffstat (limited to 'arch/m68knommu/kernel')
-rw-r--r--arch/m68knommu/kernel/Makefile11
-rw-r--r--arch/m68knommu/kernel/asm-offsets.c101
-rw-r--r--arch/m68knommu/kernel/comempci.c989
-rw-r--r--arch/m68knommu/kernel/dma.c36
-rw-r--r--arch/m68knommu/kernel/entry.S143
-rw-r--r--arch/m68knommu/kernel/init_task.c43
-rw-r--r--arch/m68knommu/kernel/m68k_ksyms.c104
-rw-r--r--arch/m68knommu/kernel/module.c128
-rw-r--r--arch/m68knommu/kernel/process.c442
-rw-r--r--arch/m68knommu/kernel/ptrace.c383
-rw-r--r--arch/m68knommu/kernel/semaphore.c134
-rw-r--r--arch/m68knommu/kernel/setup.c347
-rw-r--r--arch/m68knommu/kernel/signal.c788
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c208
-rw-r--r--arch/m68knommu/kernel/syscalltable.S308
-rw-r--r--arch/m68knommu/kernel/time.c198
-rw-r--r--arch/m68knommu/kernel/traps.c320
-rw-r--r--arch/m68knommu/kernel/vmlinux.lds.S348
18 files changed, 5031 insertions, 0 deletions
diff --git a/arch/m68knommu/kernel/Makefile b/arch/m68knommu/kernel/Makefile
new file mode 100644
index 000000000000..1c6cd1ab571e
--- /dev/null
+++ b/arch/m68knommu/kernel/Makefile
@@ -0,0 +1,11 @@
+#
+# Makefile for arch/m68knommu/kernel.
+#
+
+extra-y := vmlinux.lds
+
+obj-y += dma.o entry.o init_task.o m68k_ksyms.o process.o ptrace.o semaphore.o \
+	 setup.o signal.o syscalltable.o sys_m68k.o time.o traps.o
+
+obj-$(CONFIG_MODULES)	+= module.o
+obj-$(CONFIG_COMEMPCI)	+= comempci.o
diff --git a/arch/m68knommu/kernel/asm-offsets.c b/arch/m68knommu/kernel/asm-offsets.c
new file mode 100644
index 000000000000..cd3ffe12653e
--- /dev/null
+++ b/arch/m68knommu/kernel/asm-offsets.c
@@ -0,0 +1,101 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/ptrace.h>
+#include <linux/hardirq.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/thread_info.h>
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+int main(void)
+{
+	/* offsets into the task struct */
+	DEFINE(TASK_STATE, offsetof(struct task_struct, state));
+	DEFINE(TASK_FLAGS, offsetof(struct task_struct, flags));
+	DEFINE(TASK_PTRACE, offsetof(struct task_struct, ptrace));
+	DEFINE(TASK_BLOCKED, offsetof(struct task_struct, blocked));
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_THREAD_INFO, offsetof(struct task_struct, thread_info));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+
+	/* offsets into the kernel_stat struct */
+	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
+	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
+	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
+	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
+	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
+	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_D0, offsetof(struct pt_regs, d0));
+	DEFINE(PT_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+	DEFINE(PT_D1, offsetof(struct pt_regs, d1));
+	DEFINE(PT_D2, offsetof(struct pt_regs, d2));
+	DEFINE(PT_D3, offsetof(struct pt_regs, d3));
+	DEFINE(PT_D4, offsetof(struct pt_regs, d4));
+	DEFINE(PT_D5, offsetof(struct pt_regs, d5));
+	DEFINE(PT_A0, offsetof(struct pt_regs, a0));
+	DEFINE(PT_A1, offsetof(struct pt_regs, a1));
+	DEFINE(PT_A2, offsetof(struct pt_regs, a2));
+	DEFINE(PT_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_SR, offsetof(struct pt_regs, sr));
+
+#ifdef CONFIG_COLDFIRE
+	/* bitfields are a bit difficult */
+	DEFINE(PT_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
+#else
+	/* bitfields are a bit difficult */
+	DEFINE(PT_VECTOR, offsetof(struct pt_regs, pc) + 4);
+	/* offsets into the irq_handler struct */
+	DEFINE(IRQ_HANDLER, offsetof(struct irq_node, handler));
+	DEFINE(IRQ_DEVID, offsetof(struct irq_node, dev_id));
+	DEFINE(IRQ_NEXT, offsetof(struct irq_node, next));
+#endif
+
+	/* offsets into the kernel_stat struct */
+	DEFINE(STAT_IRQ, offsetof(struct kernel_stat, irqs));
+
+	/* signal defines */
+	DEFINE(SIGSEGV, SIGSEGV);
+	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
+	DEFINE(SIGTRAP, SIGTRAP);
+	DEFINE(TRAP_TRACE, TRAP_TRACE);
+
+	DEFINE(PT_PTRACED, PT_PTRACED);
+	DEFINE(PT_DTRACE, PT_DTRACE);
+
+	DEFINE(THREAD_SIZE, THREAD_SIZE);
+
+	/* Offsets in thread_info structure */
+	DEFINE(TI_TASK, offsetof(struct thread_info, task));
+	DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
+	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+	DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
+
+	return 0;
+}
diff --git a/arch/m68knommu/kernel/comempci.c b/arch/m68knommu/kernel/comempci.c
new file mode 100644
index 000000000000..8670938f1107
--- /dev/null
+++ b/arch/m68knommu/kernel/comempci.c
@@ -0,0 +1,989 @@
+/*****************************************************************************/
+
+/*
+ *	comemlite.c -- PCI access code for embedded CO-MEM Lite PCI controller.
+ *
+ *	(C) Copyright 1999-2003, Greg Ungerer (gerg@snapgear.com).
+ *	(C) Copyright 2000, Lineo (www.lineo.com)
+ */
+
+/*****************************************************************************/
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <asm/coldfire.h>
+#include <asm/mcfsim.h>
+#include <asm/irq.h>
+#include <asm/anchor.h>
+
+#ifdef CONFIG_eLIA
+#include <asm/elia.h>
+#endif
+
+/*****************************************************************************/
+
+/*
+ *	Debug configuration defines. DEBUGRES sets debugging output for
+ *	the resource allocation phase. DEBUGPCI traces on pcibios_ function
+ *	calls, and DEBUGIO traces all accesses to devices on the PCI bus.
+ */
+/*#define	DEBUGRES	1*/
+/*#define	DEBUGPCI	1*/
+/*#define	DEBUGIO		1*/
+
+/*****************************************************************************/
+
+/*
+ *	PCI markers for bus present and active slots.
+ */
+int		pci_bus_is_present = 0;
+unsigned long	pci_slotmask = 0;
+
+/*
+ *	We may or may not need to swap the bytes of PCI bus tranfers.
+ *	The endianess is re-roder automatically by the CO-MEM, but it
+ *	will get the wrong byte order for a pure data stream.
+ */
+#define	pci_byteswap	0
+
+
+/*
+ *	Resource tracking. The CO-MEM part creates a virtual address
+ *	space that all the PCI devices live in - it is not in any way
+ *	directly mapped into the ColdFire address space. So we can
+ *	really assign any resources we like to devices, as long as
+ *	they do not clash with other PCI devices.
+ */
+unsigned int	pci_iobase = PCIBIOS_MIN_IO;	/* Arbitrary start address */
+unsigned int	pci_membase = PCIBIOS_MIN_MEM;	/* Arbitrary start address */
+
+#define	PCI_MINIO	0x100			/* 256 byte minimum I/O */
+#define	PCI_MINMEM	0x00010000		/* 64k minimum chunk */
+
+/*
+ *	The CO-MEM's shared memory segment is visible inside the PCI
+ *	memory address space. We need to keep track of the address that
+ *	this is mapped at, to setup the bus masters pointers.
+ */
+unsigned int	pci_shmemaddr;
+
+/*****************************************************************************/
+
+void	pci_interrupt(int irq, void *id, struct pt_regs *fp);
+
+/*****************************************************************************/
+
+/*
+ *	Some platforms have custom ways of reseting the PCI bus.
+ */
+
+void pci_resetbus(void)
+{
+#ifdef CONFIG_eLIA
+	int	i;
+
+#ifdef DEBUGPCI
+	printk(KERN_DEBUG "pci_resetbus()\n");
+#endif
+
+	*((volatile unsigned short *) (MCF_MBAR+MCFSIM_PADDR)) |= eLIA_PCIRESET;
+	for (i = 0; (i < 1000); i++) {
+		*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = 
+			(ppdata | eLIA_PCIRESET);
+	}
+
+
+	*((volatile unsigned short *) (MCF_MBAR + MCFSIM_PADAT)) = ppdata;
+#endif
+}
+
+/*****************************************************************************/
+
+int pcibios_assign_resource_slot(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*ip;
+	unsigned int		idsel, addr, val, align, i;
+	int			bar;
+
+#ifdef DEBUGPCI
+	printk(KERN_INFO "pcibios_assign_resource_slot(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Try to assign resource to each BAR */
+	for (bar = 0; (bar < 6); bar++) {
+		addr = COMEM_PCIBUS + PCI_BASE_ADDRESS_0 + (bar * 4);
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk(KERN_DEBUG "-----------------------------------"
+			"-------------------------------------\n");
+		printk(KERN_DEBUG "BAR[%d]: read=%08x ", bar, val);
+#endif
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = 0xffffffff;
+
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+		val = rp[LREG(addr)];
+#ifdef DEBUGRES
+		printk(KERN_DEBUG "write=%08x ", val);
+#endif
+		if (val == 0) {
+#ifdef DEBUGRES
+			printk(KERN_DEBUG "\n");
+#endif
+			continue;
+		}
+
+		/* Determine space required by BAR */
+		/* FIXME: this should go backwords from 0x80000000... */
+		for (i = 0; (i < 32); i++) {
+			if ((0x1 << i) & (val & 0xfffffffc))
+				break;
+		}
+
+#ifdef DEBUGRES
+		printk(KERN_DEBUG "size=%08x(%d)\n", (0x1 << i), i);
+#endif
+		i = 0x1 << i;
+
+		/* Assign a resource */
+		if (val & PCI_BASE_ADDRESS_SPACE_IO) {
+			if (i < PCI_MINIO)
+				i = PCI_MINIO;
+#ifdef DEBUGRES
+			printk(KERN_DEBUG "BAR[%d]: IO size=%08x iobase=%08x\n",
+				bar, i, pci_iobase);
+#endif
+			if (i > 0xffff) {
+				/* Invalid size?? */
+				val = 0 | PCI_BASE_ADDRESS_SPACE_IO;
+#ifdef DEBUGRES
+				printk(KERN_DEBUG "BAR[%d]: too big for IO??\n", bar);
+#endif
+			} else {
+				/* Check for un-alignment */
+				if ((align = pci_iobase % i))
+					pci_iobase += (i - align);
+				val = pci_iobase | PCI_BASE_ADDRESS_SPACE_IO;
+				pci_iobase += i;
+			}
+		} else {
+			if (i < PCI_MINMEM)
+				i = PCI_MINMEM;
+#ifdef DEBUGRES
+			printk(KERN_DEBUG "BAR[%d]: MEMORY size=%08x membase=%08x\n",
+				bar, i, pci_membase);
+#endif
+			/* Check for un-alignment */
+			if ((align = pci_membase % i))
+				pci_membase += (i - align);
+			val = pci_membase | PCI_BASE_ADDRESS_SPACE_MEMORY;
+			pci_membase += i;
+		}
+
+		/* Write resource back into BAR register */
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		rp[LREG(addr)] = val;
+#ifdef DEBUGRES
+		printk(KERN_DEBUG "BAR[%d]: assigned bar=%08x\n", bar, val);
+#endif
+	}
+
+#ifdef DEBUGRES
+	printk(KERN_DEBUG "-----------------------------------"
+			"-------------------------------------\n");
+#endif
+
+	/* Assign IRQ if one is wanted... */
+	ip = (volatile unsigned char *) (COMEM_BASE + COMEM_PCIBUS);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+
+	addr = (PCI_INTERRUPT_PIN & 0xfc) + (~PCI_INTERRUPT_PIN & 0x03);
+	if (ip[addr]) {
+		rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+		addr = (PCI_INTERRUPT_LINE & 0xfc)+(~PCI_INTERRUPT_LINE & 0x03);
+		ip[addr] = 25;
+#ifdef DEBUGRES
+		printk(KERN_DEBUG "IRQ LINE=25\n");
+#endif
+	}
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+int pcibios_enable_slot(int slot)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned int		idsel, addr;
+	unsigned short		cmd;
+
+#ifdef DEBUGPCI
+	printk(KERN_DEBUG "pcibios_enbale_slot(slot=%x)\n", slot);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	wp = (volatile unsigned short *) COMEM_BASE;
+	idsel = COMEM_DA_ADDR(0x1 << (slot + 16));
+
+	/* Get current command settings */
+	addr = COMEM_PCIBUS + PCI_COMMAND;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGRD | idsel;
+	cmd = wp[WREG(addr)];
+	/*val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);*/
+
+	/* Enable I/O and memory accesses to this device */
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_CFGWR | idsel;
+	cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
+	wp[WREG(addr)] = cmd;
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+void pcibios_assign_resources(void)
+{
+	volatile unsigned long	*rp;
+	unsigned long		sel, id;
+	int			slot;
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+
+	/*
+	 *	Do a quick scan of the PCI bus and see what is here.
+	 */
+	for (slot = COMEM_MINDEV; (slot <= COMEM_MAXDEV); slot++) {
+		sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+		rp[LREG(COMEM_DAHBASE)] = sel;
+		rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+		id = rp[LREG(COMEM_PCIBUS)];
+		if ((id != 0) && ((id & 0xffff0000) != (sel & 0xffff0000))) {
+			printk(KERN_INFO "PCI: slot=%d id=%08x\n", slot, (int) id);
+			pci_slotmask |= 0x1 << slot;
+			pcibios_assign_resource_slot(slot);
+			pcibios_enable_slot(slot);
+		}
+	}
+}
+
+/*****************************************************************************/
+
+int pcibios_init(void)
+{
+	volatile unsigned long	*rp;
+	unsigned long		sel, id;
+	int			slot;
+
+#ifdef DEBUGPCI
+	printk(KERN_DEBUG "pcibios_init()\n");
+#endif
+
+	pci_resetbus();
+
+	/*
+	 *	Do some sort of basic check to see if the CO-MEM part
+	 *	is present... This works ok, but I think we really need
+	 *	something better...
+	 */
+	rp = (volatile unsigned long *) COMEM_BASE;
+	if ((rp[LREG(COMEM_LBUSCFG)] & 0xff) != 0x50) {
+		printk(KERN_INFO "PCI: no PCI bus present\n");
+		return(0);
+	}
+
+#ifdef COMEM_BRIDGEDEV
+	/*
+	 *	Setup the PCI bridge device first. It needs resources too,
+	 *	so that bus masters can get to its shared memory.
+	 */
+	slot = COMEM_BRIDGEDEV;
+	sel = COMEM_DA_CFGRD | COMEM_DA_ADDR(0x1 << (slot + 16));
+	rp[LREG(COMEM_DAHBASE)] = sel;
+	rp[LREG(COMEM_PCIBUS)] = 0; /* Clear bus */
+	id = rp[LREG(COMEM_PCIBUS)];
+	if ((id == 0) || ((id & 0xffff0000) == (sel & 0xffff0000))) {
+		printk(KERN_INFO "PCI: no PCI bus bridge present\n");
+		return(0);
+	}
+
+	printk(KERN_INFO "PCI: bridge device at slot=%d id=%08x\n", slot, (int) id);
+	pci_slotmask |= 0x1 << slot;
+	pci_shmemaddr = pci_membase;
+	pcibios_assign_resource_slot(slot);
+	pcibios_enable_slot(slot);
+#endif
+
+	pci_bus_is_present = 1;
+
+	/* Get PCI irq for local vectoring */
+	if (request_irq(COMEM_IRQ, pci_interrupt, 0, "PCI bridge", NULL)) {
+		printk(KERN_WARNING "PCI: failed to acquire interrupt %d\n", COMEM_IRQ);
+	} else {
+		mcf_autovector(COMEM_IRQ);
+	}
+
+	pcibios_assign_resources();
+
+	return(0);
+}
+
+/*****************************************************************************/
+
+char *pcibios_setup(char *option)
+{
+	/* Nothing for us to handle. */
+	return(option);
+}
+/*****************************************************************************/
+
+void pcibios_fixup_bus(struct pci_bus *b)
+{
+}
+
+/*****************************************************************************/
+
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size, unsigned long align)
+{
+}
+
+/*****************************************************************************/
+
+int pcibios_enable_device(struct pci_dev *dev, int mask)
+{
+	int slot;
+
+	slot = PCI_SLOT(dev->devfn);
+	if ((dev->bus == 0) && (pci_slotmask & (1 << slot)))
+		pcibios_enable_slot(slot);
+	return(0);
+}
+
+/*****************************************************************************/
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *r, int resource)
+{
+	printk(KERN_WARNING "%s(%d): no support for changing PCI resources...\n",
+		__FILE__, __LINE__);
+}
+
+
+/*****************************************************************************/
+
+/*
+ *	Local routines to interrcept the standard I/O and vector handling
+ *	code. Don't include this 'till now - initialization code above needs
+ *	access to the real code too.
+ */
+#include <asm/mcfpci.h>
+
+/*****************************************************************************/
+
+void pci_outb(unsigned char val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outb(val=%02x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x03);
+	bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outw(unsigned short val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outw(val=%04x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	sp = (volatile unsigned short *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+	sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+void pci_outl(unsigned int val, unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outl(val=%08x,addr=%x)\n", val, addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(addr);
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+	lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))] = val;
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_blmask[] = {
+	0x000000e0,
+	0x000000d0,
+	0x000000b0,
+	0x00000070
+};
+
+unsigned char pci_inb(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned long		r;
+	unsigned char		val;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_inb(addr=%x)\n", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	bp = (volatile unsigned char *) COMEM_BASE;
+
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_blmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	addr = (addr & ~0x3) + (~addr & 0x3);
+	val = bp[(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned long	pci_bwmask[] = {
+	0x000000c0,
+	0x000000c0,
+	0x00000030,
+	0x00000030
+};
+
+unsigned short pci_inw(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*sp;
+	unsigned long		r;
+	unsigned short		val;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_inw(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	r = COMEM_DA_IORD | COMEM_DA_ADDR(addr) | pci_bwmask[(addr & 0x3)];
+	rp[LREG(COMEM_DAHBASE)] = r;
+
+	sp = (volatile unsigned short *) COMEM_BASE;
+	addr = (addr & ~0x3) + (~addr & 0x02);
+	val = sp[WREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+	if (pci_byteswap)
+		val = ((val & 0xff) << 8) | ((val >> 8) & 0xff);
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "=%04x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+unsigned int pci_inl(unsigned int addr)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned int	*lp;
+	unsigned int		val;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_inl(addr=%x)", addr);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	lp = (volatile unsigned int *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(addr);
+	val = lp[LREG(COMEM_PCIBUS + COMEM_DA_OFFSET(addr))];
+
+	if (pci_byteswap)
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "=%08x\n", val);
+#endif
+	return(val);
+}
+
+/*****************************************************************************/
+
+void pci_outsb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outsb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*bp = *dp++;
+}
+
+/*****************************************************************************/
+
+void pci_outsw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outsw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *dp++;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*wp = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_outsl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_outsl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IOWR | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *dp++;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*lp = l;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insb(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned char	*bp;
+	unsigned char		*dp = (unsigned char *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_insb(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x03);
+	bp = (volatile unsigned char *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--)
+		*dp++ = *bp;
+}
+
+/*****************************************************************************/
+
+void pci_insw(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned short	*wp;
+	unsigned short		w, *dp = (unsigned short *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_insw(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	a = (a & ~0x3) + (~a & 0x2);
+	wp = (volatile unsigned short *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		w = *wp;
+		if (pci_byteswap)
+			w = ((w & 0xff) << 8) | ((w >> 8) & 0xff);
+		*dp++ = w;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_insl(void *addr, void *buf, int len)
+{
+	volatile unsigned long	*rp;
+	volatile unsigned long	*lp;
+	unsigned long		l, *dp = (unsigned long *) buf;
+	unsigned int		a = (unsigned int) addr;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_insl(addr=%x,buf=%x,len=%d)\n", (int)addr, (int)buf, len);
+#endif
+
+	rp = (volatile unsigned long *) COMEM_BASE;
+	rp[LREG(COMEM_DAHBASE)] = COMEM_DA_IORD | COMEM_DA_ADDR(a);
+
+	lp = (volatile unsigned long *)
+		(COMEM_BASE + COMEM_PCIBUS + COMEM_DA_OFFSET(a));
+
+	while (len--) {
+		l = *lp;
+		if (pci_byteswap)
+			l = (l << 24) | ((l & 0x0000ff00) << 8) |
+				((l & 0x00ff0000) >> 8) | (l >> 24);
+		*dp++ = l;
+	}
+}
+
+/*****************************************************************************/
+
+struct pci_localirqlist {
+	void		(*handler)(int, void *, struct pt_regs *);
+	const char	*device;
+	void		*dev_id;
+};
+
+struct pci_localirqlist	pci_irqlist[COMEM_MAXPCI];
+
+/*****************************************************************************/
+
+int pci_request_irq(unsigned int irq,
+	void (*handler)(int, void *, struct pt_regs *),
+	unsigned long flags, const char *device, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_request_irq(irq=%d,handler=%x,flags=%x,device=%s,"
+		"dev_id=%x)\n", irq, (int) handler, (int) flags, device,
+		(int) dev_id);
+#endif
+
+	/* Check if this interrupt handler is already lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == handler)
+			return(0);
+	}
+
+	/* Find a free spot to put this handler */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler == 0) {
+			pci_irqlist[i].handler = handler;
+			pci_irqlist[i].device = device;
+			pci_irqlist[i].dev_id = dev_id;
+			return(0);
+		}
+	}
+
+	/* Couldn't fit?? */
+	return(1);
+}
+
+/*****************************************************************************/
+
+void pci_free_irq(unsigned int irq, void *dev_id)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_free_irq(irq=%d,dev_id=%x)\n", irq, (int) dev_id);
+#endif
+
+	if (dev_id == (void *) NULL)
+		return;
+
+	/* Check if this interrupt handler is lodged */
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].dev_id == dev_id) {
+			pci_irqlist[i].handler = NULL;
+			pci_irqlist[i].device = NULL;
+			pci_irqlist[i].dev_id = NULL;
+			break;
+		}
+	}
+}
+
+/*****************************************************************************/
+
+void pci_interrupt(int irq, void *id, struct pt_regs *fp)
+{
+	int	i;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_interrupt(irq=%d,id=%x,fp=%x)\n", irq, (int) id, (int) fp);
+#endif
+
+	for (i = 0; (i < COMEM_MAXPCI); i++) {
+		if (pci_irqlist[i].handler)
+			(*pci_irqlist[i].handler)(irq,pci_irqlist[i].dev_id,fp);
+	}
+}
+
+/*****************************************************************************/
+
+/*
+ *	The shared memory region is broken up into contiguous 512 byte
+ *	regions for easy allocation... This is not an optimal solution
+ *	but it makes allocation and freeing regions really easy.
+ */
+
+#define	PCI_MEMSLOTSIZE		512
+#define	PCI_MEMSLOTS		(COMEM_SHMEMSIZE / PCI_MEMSLOTSIZE)
+
+char	pci_shmemmap[PCI_MEMSLOTS];
+
+
+void *pci_bmalloc(int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_bmalloc(size=%d)\n", size);
+#endif
+
+	if (size <= 0)
+		return((void *) NULL);
+
+	nrslots = (size - 1) / PCI_MEMSLOTSIZE;
+
+	for (i = 0; (i < (PCI_MEMSLOTS-nrslots)); i++) {
+		if (pci_shmemmap[i] == 0) {
+			for (j = i+1; (j < (i+nrslots)); j++) {
+				if (pci_shmemmap[j])
+					goto restart;
+			}
+
+			for (j = i; (j <= i+nrslots); j++)
+				pci_shmemmap[j] = 1;
+			break;
+		}
+restart:
+	}
+
+	return((void *) (COMEM_BASE + COMEM_SHMEM + (i * PCI_MEMSLOTSIZE)));
+}
+
+/*****************************************************************************/
+
+void pci_bmfree(void *mp, int size)
+{
+	int	i, j, nrslots;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_bmfree(mp=%x,size=%d)\n", (int) mp, size);
+#endif
+
+	nrslots = size / PCI_MEMSLOTSIZE;
+	i = (((unsigned long) mp) - (COMEM_BASE + COMEM_SHMEM)) /
+		PCI_MEMSLOTSIZE;
+
+	for (j = i; (j < (i+nrslots)); j++)
+		pci_shmemmap[j] = 0;
+}
+
+/*****************************************************************************/
+
+unsigned long pci_virt_to_bus(volatile void *address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_virt_to_bus(address=%x)", (int) address);
+#endif
+
+	l = ((unsigned long) address) - COMEM_BASE;
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "=%x\n", (int) (l+pci_shmemaddr));
+#endif
+	return(l + pci_shmemaddr);
+}
+
+/*****************************************************************************/
+
+void *pci_bus_to_virt(unsigned long address)
+{
+	unsigned long	l;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_bus_to_virt(address=%x)", (int) address);
+#endif
+
+	l = address - pci_shmemaddr;
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "=%x\n", (int) (address + COMEM_BASE));
+#endif
+	return((void *) (address + COMEM_BASE));
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyto(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i, j;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_bmcpyto(dst=%x,src=%x,len=%d)\n", (int)dst, (int)src, len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+#if 0
+	printk(KERN_INFO "DATA:");
+	scp = (unsigned char *) sp;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk(KERN_INFO "\n%04x: ", i);
+		printk(KERN_INFO "%02x ", *scp++);
+	}
+	printk(KERN_INFO "\n");
+#endif
+
+	for (j = 0; (i >= 0); i--, j++) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = (unsigned char *) dp;
+		scp = ((unsigned char *) sp) + 3;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+}
+
+/*****************************************************************************/
+
+void pci_bmcpyfrom(void *dst, void *src, int len)
+{
+	unsigned long	*dp, *sp, val;
+	unsigned char	*dcp, *scp;
+	int		i;
+
+#ifdef DEBUGIO
+	printk(KERN_DEBUG "pci_bmcpyfrom(dst=%x,src=%x,len=%d)\n",(int)dst,(int)src,len);
+#endif
+
+	dp = (unsigned long *) dst;
+	sp = (unsigned long *) src;
+	i = len >> 2;
+
+	for (; (i >= 0); i--) {
+		val = *sp++;
+		val = (val << 24) | ((val & 0x0000ff00) << 8) |
+			((val & 0x00ff0000) >> 8) | (val >> 24);
+		*dp++ = val;
+	}
+
+	if (len & 0x3) {
+		dcp = ((unsigned char *) dp) + 3;
+		scp = (unsigned char *) sp;
+		for (i = 0; (i < (len & 0x3)); i++)
+			*dcp++ = *scp--;
+	}
+
+#if 0
+	printk(KERN_INFO "DATA:");
+	dcp = (unsigned char *) dst;
+	for (i = 0; (i < len); i++) {
+		if ((i % 16) == 0) printk(KERN_INFO "\n%04x: ", i);
+		printk(KERN_INFO "%02x ", *dcp++);
+	}
+	printk(KERN_INFO "\n");
+#endif
+}
+
+/*****************************************************************************/
+
+void *pci_alloc_consistent(struct pci_dev *dev, size_t size, dma_addr_t *dma_addr)
+{
+	void *mp;
+	if ((mp = pci_bmalloc(size)) != NULL) {
+		dma_addr = mp - (COMEM_BASE + COMEM_SHMEM);
+		return(mp);
+	}
+	*dma_addr = (dma_addr_t) NULL;
+	return(NULL);
+}
+
+/*****************************************************************************/
+
+void pci_free_consistent(struct pci_dev *dev, size_t size, void *cpu_addr, dma_addr_t dma_addr)
+{
+	pci_bmfree(cpu_addr, size);
+}
+
+/*****************************************************************************/
diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c
new file mode 100644
index 000000000000..14b19c4161f4
--- /dev/null
+++ b/arch/m68knommu/kernel/dma.c
@@ -0,0 +1,36 @@
+/*
+ * 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/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+			   dma_addr_t *dma_handle, int 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));
+}
diff --git a/arch/m68knommu/kernel/entry.S b/arch/m68knommu/kernel/entry.S
new file mode 100644
index 000000000000..8b1f47239b9a
--- /dev/null
+++ b/arch/m68knommu/kernel/entry.S
@@ -0,0 +1,143 @@
+/*
+ *  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/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/asm-offsets.h>
+#include <asm/entry.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
+	moveq	#-1,%d0
+	movel	%d0,%sp@(PT_ORIG_D0)
+	movel	%sp,%sp@- 		/* stack frame pointer argument */
+	jsr	buserr_c
+	addql	#4,%sp
+	jra	ret_from_exception
+
+ENTRY(trap)
+	SAVE_ALL
+	moveq	#-1,%d0
+	movel	%d0,%sp@(PT_ORIG_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
+	moveq	#-1,%d0
+	movel	%d0,%sp@(PT_ORIG_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_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_sigsuspend
+	addql	#4,%sp
+	RESTORE_SWITCH_STACK
+	rts
+
+ENTRY(sys_rt_sigsuspend)
+	SAVE_SWITCH_STACK
+	pea	%sp@(SWITCH_STACK_SIZE)
+	jbsr	do_rt_sigsuspend
+	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
+
diff --git a/arch/m68knommu/kernel/init_task.c b/arch/m68knommu/kernel/init_task.c
new file mode 100644
index 000000000000..3897043a126a
--- /dev/null
+++ b/arch/m68knommu/kernel/init_task.c
@@ -0,0 +1,43 @@
+/*
+ *  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 fs_struct init_fs = INIT_FS;
+static struct files_struct init_files = INIT_FILES;
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+struct mm_struct init_mm = INIT_MM(init_mm);
+
+EXPORT_SYMBOL(init_mm);
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+__asm__(".align 4");
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is 8192-byte 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
+	__attribute__((__section__(".data.init_task"))) =
+		{ INIT_THREAD_INFO(init_task) };
+
diff --git a/arch/m68knommu/kernel/m68k_ksyms.c b/arch/m68knommu/kernel/m68k_ksyms.c
new file mode 100644
index 000000000000..e93a5ad56496
--- /dev/null
+++ b/arch/m68knommu/kernel/m68k_ksyms.c
@@ -0,0 +1,104 @@
+#include <linux/module.h>
+#include <linux/linkage.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
+
+#include <asm/setup.h>
+#include <asm/machdep.h>
+#include <asm/pgalloc.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+#include <asm/checksum.h>
+#include <asm/current.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
+
+/* platform dependent support */
+
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+EXPORT_SYMBOL(dump_fpu);
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(strnlen);
+EXPORT_SYMBOL(strrchr);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strncmp);
+
+EXPORT_SYMBOL(ip_fast_csum);
+
+EXPORT_SYMBOL(mach_enable_irq);
+EXPORT_SYMBOL(mach_disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memscan);
+EXPORT_SYMBOL(memmove);
+
+EXPORT_SYMBOL(__down_failed);
+EXPORT_SYMBOL(__down_failed_interruptible);
+EXPORT_SYMBOL(__down_failed_trylock);
+EXPORT_SYMBOL(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
+
+/*
+ * libgcc functions - functions that are used internally by the
+ * compiler...  (prototypes are not correct though, but that
+ * doesn't really matter since they're not versioned).
+ */
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __divsi3(void);
+extern void __lshrdi3(void);
+extern void __modsi3(void);
+extern void __muldi3(void);
+extern void __mulsi3(void);
+extern void __udivsi3(void);
+extern void __umodsi3(void);
+
+        /* gcc lib functions */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__mulsi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
+
+EXPORT_SYMBOL(is_in_rom);
+
+#ifdef CONFIG_COLDFIRE
+extern unsigned int *dma_device_address;
+extern unsigned long dma_base_addr, _ramend;
+EXPORT_SYMBOL(dma_base_addr);
+EXPORT_SYMBOL(dma_device_address);
+EXPORT_SYMBOL(_ramend);
+
+extern asmlinkage void trap(void);
+extern void	*_ramvec;
+EXPORT_SYMBOL(trap);
+EXPORT_SYMBOL(_ramvec);
+#endif /* CONFIG_COLDFIRE */
diff --git a/arch/m68knommu/kernel/module.c b/arch/m68knommu/kernel/module.c
new file mode 100644
index 000000000000..3b1a2ff61ddc
--- /dev/null
+++ b/arch/m68knommu/kernel/module.c
@@ -0,0 +1,128 @@
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+void *module_alloc(unsigned long size)
+{
+	if (size == 0)
+		return NULL;
+	return vmalloc(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+	vfree(module_region);
+	/* FIXME: If module_region == mod->init_region, trim exception
+           table entries. */
+}
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+			      Elf_Shdr *sechdrs,
+			      char *secstrings,
+			      struct module *mod)
+{
+	return 0;
+}
+
+int apply_relocate(Elf32_Shdr *sechdrs,
+		   const char *strtab,
+		   unsigned int symindex,
+		   unsigned int relsec,
+		   struct module *me)
+{
+	unsigned int i;
+	Elf32_Rel *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+
+	DEBUGP("Applying relocate section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_68K_32:
+			/* We add the value into the location given */
+			*location += sym->st_value;
+			break;
+		case R_68K_PC32:
+			/* Add the value, subtract its postition */
+			*location += sym->st_value - (uint32_t)location;
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+		       const char *strtab,
+		       unsigned int symindex,
+		       unsigned int relsec,
+		       struct module *me)
+{
+	unsigned int i;
+	Elf32_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+	Elf32_Sym *sym;
+	uint32_t *location;
+
+	DEBUGP("Applying relocate_add section %u to %u\n", relsec,
+	       sechdrs[relsec].sh_info);
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+		/* This is where to make the change */
+		location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			+ rel[i].r_offset;
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		sym = (Elf32_Sym *)sechdrs[symindex].sh_addr
+			+ ELF32_R_SYM(rel[i].r_info);
+
+		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_68K_32:
+			/* We add the value into the location given */
+			*location = rel[i].r_addend + sym->st_value;
+			break;
+		case R_68K_PC32:
+			/* Add the value, subtract its postition */
+			*location = rel[i].r_addend + sym->st_value - (uint32_t)location;
+			break;
+		default:
+			printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+			       me->name, ELF32_R_TYPE(rel[i].r_info));
+			return -ENOEXEC;
+		}
+	}
+	return 0;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+		    const Elf_Shdr *sechdrs,
+		    struct module *me)
+{
+	return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
new file mode 100644
index 000000000000..2b6c9d32b7a6
--- /dev/null
+++ b/arch/m68knommu/kernel/process.c
@@ -0,0 +1,442 @@
+/*
+ *  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/config.h>
+#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/smp_lock.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/reboot.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 idle loop on an m68knommu..
+ */
+void default_idle(void)
+{
+	while(1) {
+		if (need_resched())
+			__asm__("stop #0x2000" : : : "cc");
+		schedule();
+	}
+}
+
+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 */
+	idle();
+}
+
+void machine_restart(char * __unused)
+{
+	if (mach_reset)
+		mach_reset();
+	for (;;);
+}
+
+EXPORT_SYMBOL(machine_restart);
+
+void machine_halt(void)
+{
+	if (mach_halt)
+		mach_halt();
+	for (;;);
+}
+
+EXPORT_SYMBOL(machine_halt);
+
+void machine_power_off(void)
+{
+	if (mach_power_off)
+		mach_power_off();
+	for (;;);
+}
+
+EXPORT_SYMBOL(machine_power_off);
+
+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;
+}
+
+void flush_thread(void)
+{
+#ifdef CONFIG_FPU
+	unsigned long zero = 0;
+#endif
+	set_fs(USER_DS);
+	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" : : "a" (&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(int nr, 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 stack_offset, *retp;
+
+	stack_offset = THREAD_SIZE - sizeof(struct pt_regs);
+	childregs = (struct pt_regs *) ((unsigned long) p->thread_info + stack_offset);
+
+	*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;
+	/*
+	 * 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;
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+	struct switch_stack *sw;
+
+	/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = rdusp() & ~(PAGE_SIZE - 1);
+	dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
+	dump->u_dsize = ((unsigned long) (current->mm->brk +
+					  (PAGE_SIZE-1))) >> PAGE_SHIFT;
+	dump->u_dsize -= dump->u_tsize;
+	dump->u_ssize = 0;
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->u_ar0 = (struct user_regs_struct *)((int)&dump->regs - (int)dump);
+	sw = ((struct switch_stack *)regs) - 1;
+	dump->regs.d1 = regs->d1;
+	dump->regs.d2 = regs->d2;
+	dump->regs.d3 = regs->d3;
+	dump->regs.d4 = regs->d4;
+	dump->regs.d5 = regs->d5;
+	dump->regs.d6 = sw->d6;
+	dump->regs.d7 = sw->d7;
+	dump->regs.a0 = regs->a0;
+	dump->regs.a1 = regs->a1;
+	dump->regs.a2 = regs->a2;
+	dump->regs.a3 = sw->a3;
+	dump->regs.a4 = sw->a4;
+	dump->regs.a5 = sw->a5;
+	dump->regs.a6 = sw->a6;
+	dump->regs.d0 = regs->d0;
+	dump->regs.orig_d0 = regs->orig_d0;
+	dump->regs.stkadj = regs->stkadj;
+	dump->regs.sr = regs->sr;
+	dump->regs.pc = regs->pc;
+	dump->regs.fmtvec = (regs->format << 12) | regs->vector;
+	/* dump floating point stuff */
+	dump->u_fpvalid = dump_fpu (regs, &dump->m68kfp);
+}
+
+/*
+ *	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: %08x\n", (unsigned int) rdusp(),
+		(unsigned int) 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 "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n");
+
+	printk(KERN_EMERG "\nKERNEL STACK:");
+	tp = ((unsigned char *) fp) - 0x40;
+	for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
+		if ((i % 0x10) == 0)
+			printk(KERN_EMERG "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n");
+	printk(KERN_EMERG "\n");
+
+	printk(KERN_EMERG "\nUSER STACK:");
+	tp = (unsigned char *) (rdusp() - 0x10);
+	for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
+		if ((i % 0x10) == 0)
+			printk(KERN_EMERG "\n%08x: ", (int) (tp + i));
+		printk(KERN_EMERG "%08x ", (int) *sp++);
+	}
+	printk(KERN_EMERG "\n\n");
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+asmlinkage int sys_execve(char *name, char **argv, char **envp)
+{
+	int error;
+	char * filename;
+	struct pt_regs *regs = (struct pt_regs *) &name;
+
+	lock_kernel();
+	filename = getname(name);
+	error = PTR_ERR(filename);
+	if (IS_ERR(filename))
+		goto out;
+	error = do_execve(filename, argv, envp, regs);
+	putname(filename);
+out:
+	unlock_kernel();
+	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 >= 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;
+}
+
+/*
+ * 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/m68knommu/kernel/ptrace.c b/arch/m68knommu/kernel/ptrace.c
new file mode 100644
index 000000000000..15cf79080b15
--- /dev/null
+++ b/arch/m68knommu/kernel/ptrace.c
@@ -0,0 +1,383 @@
+/*
+ *  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/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/config.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 < sizeof(regoff)/sizeof(regoff[0]))
+		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 < sizeof(regoff)/sizeof(regoff[0]))
+		addr = (unsigned long *) (task->thread.esp0 + regoff[regno]);
+	else
+		return -1;
+	*addr = data;
+	return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ *
+ * Make sure the single step bit is not set.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+	unsigned long tmp;
+	/* make sure the single step bit is not set. */
+	tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+	put_reg(child, PT_SR, tmp);
+}
+
+asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
+{
+	struct task_struct *child;
+	int ret;
+
+	lock_kernel();
+	ret = -EPERM;
+	if (request == PTRACE_TRACEME) {
+		/* are we already being traced? */
+		if (current->ptrace & PT_PTRACED)
+			goto out;
+		/* set the ptrace bit in the process flags. */
+		current->ptrace |= PT_PTRACED;
+		ret = 0;
+		goto out;
+	}
+	ret = -ESRCH;
+	read_lock(&tasklist_lock);
+	child = find_task_by_pid(pid);
+	if (child)
+		get_task_struct(child);
+	read_unlock(&tasklist_lock);
+	if (!child)
+		goto out;
+
+	ret = -EPERM;
+	if (pid == 1)		/* you may not mess with init */
+		goto out_tsk;
+
+	if (request == PTRACE_ATTACH) {
+		ret = ptrace_attach(child);
+		goto out_tsk;
+	}
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out_tsk;
+
+	switch (request) {
+		/* when I and D space are separate, these will need to be fixed. */
+		case PTRACE_PEEKTEXT: /* read word at location addr. */ 
+		case PTRACE_PEEKDATA: {
+			unsigned long tmp;
+			int copied;
+
+			copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+			ret = -EIO;
+			if (copied != sizeof(tmp))
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+		/* read the word at location addr in the USER area. */
+		case PTRACE_PEEKUSR: {
+			unsigned long tmp;
+			
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+			
+			tmp = 0;  /* Default return condition */
+			addr = addr >> 2; /* temporary hack. */
+			ret = -EIO;
+			if (addr < 19) {
+				tmp = get_reg(child, addr);
+				if (addr == PT_SR)
+					tmp >>= 16;
+			} else if (addr >= 21 && addr < 49) {
+				tmp = child->thread.fp[addr - 21];
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert internal fpu reg representation
+				 * into long double format
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3))
+					tmp = ((tmp & 0xffff0000) << 15) |
+					      ((tmp & 0x0000ffff) << 16);
+#endif
+			} else if (addr == 49) {
+				tmp = child->mm->start_code;
+			} else if (addr == 50) {
+				tmp = child->mm->start_data;
+			} else if (addr == 51) {
+				tmp = child->mm->end_code;
+			} else
+				break;
+			ret = put_user(tmp,(unsigned long *) data);
+			break;
+		}
+
+		/* when I and D space are separate, this will have to be fixed. */
+		case PTRACE_POKETEXT: /* write the word at location addr. */
+		case PTRACE_POKEDATA:
+			ret = 0;
+			if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+				break;
+			ret = -EIO;
+			break;
+
+		case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+			ret = -EIO;
+			if ((addr & 3) || addr < 0 ||
+			    addr > sizeof(struct user) - 3)
+				break;
+
+			addr = addr >> 2; /* temporary hack. */
+			    
+			if (addr == PT_SR) {
+				data &= SR_MASK;
+				data <<= 16;
+				data |= get_reg(child, PT_SR) & ~(SR_MASK << 16);
+			}
+			if (addr < 19) {
+				if (put_reg(child, addr, data))
+					break;
+				ret = 0;
+				break;
+			}
+			if (addr >= 21 && addr < 48)
+			{
+#ifdef CONFIG_M68KFPU_EMU
+				/* Convert long double format
+				 * into internal fpu reg representation
+				 */
+				if (FPU_IS_EMU && (addr < 45) && !(addr % 3)) {
+					data = (unsigned long)data << 15;
+					data = (data & 0xffff0000) |
+					       ((data & 0x0000ffff) >> 1);
+				}
+#endif
+				child->thread.fp[addr - 21] = data;
+				ret = 0;
+			}
+			break;
+
+		case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+		case PTRACE_CONT: { /* restart after signal. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			if (request == PTRACE_SYSCALL)
+				set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			else
+				clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			child->exit_code = data;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		/*
+		 * make the child exit.  Best I can do is send it a sigkill. 
+		 * perhaps it should be put in the status that it wants to 
+		 * exit.
+		 */
+		case PTRACE_KILL: {
+			long tmp;
+
+			ret = 0;
+			if (child->exit_state == EXIT_ZOMBIE) /* already dead */
+				break;
+			child->exit_code = SIGKILL;
+			/* make sure the single step bit is not set. */
+			tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+			wake_up_process(child);
+			break;
+		}
+
+		case PTRACE_SINGLESTEP: {  /* set the trap flag. */
+			long tmp;
+
+			ret = -EIO;
+			if ((unsigned long) data > _NSIG)
+				break;
+			clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+			tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16);
+			put_reg(child, PT_SR, tmp);
+
+			child->exit_code = data;
+			/* give it a chance to run. */
+			wake_up_process(child);
+			ret = 0;
+			break;
+		}
+
+		case PTRACE_DETACH:	/* detach a process that was attached. */
+			ret = ptrace_detach(child, data);
+			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, (unsigned long *) data)) {
+				ret = -EFAULT;
+				break;
+			    }
+			    data += sizeof(long);
+			}
+			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, (unsigned long *) data)) {
+				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);
+			    data += sizeof(long);
+			}
+			ret = 0;
+			break;
+		}
+
+#ifdef PTRACE_GETFPREGS
+		case PTRACE_GETFPREGS: { /* Get the child FPU state. */
+			ret = 0;
+			if (copy_to_user((void *)data, &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, (void *)data,
+					   sizeof(struct user_m68kfp_struct)))
+				ret = -EFAULT;
+			break;
+		}
+#endif
+
+		default:
+			ret = -EIO;
+			break;
+	}
+out_tsk:
+	put_task_struct(child);
+out:
+	unlock_kernel();
+	return ret;
+}
+
+asmlinkage void syscall_trace(void)
+{
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+	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;
+	}
+}
diff --git a/arch/m68knommu/kernel/semaphore.c b/arch/m68knommu/kernel/semaphore.c
new file mode 100644
index 000000000000..c083f4772add
--- /dev/null
+++ b/arch/m68knommu/kernel/semaphore.c
@@ -0,0 +1,134 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <asm/semaphore-helper.h>
+
+#ifndef CONFIG_RMW_INSNS
+spinlock_t semaphore_wake_lock;
+#endif
+
+/*
+ * Semaphores are implemented using a two-way counter:
+ * The "count" variable is decremented for each process
+ * that tries to sleep, while the "waking" variable is
+ * incremented when the "up()" code goes to wake up waiting
+ * processes.
+ *
+ * Notably, the inline "up()" and "down()" functions can
+ * efficiently test if they need to do any extra work (up
+ * needs to do something only if count was negative before
+ * the increment operation.
+ *
+ * waking_non_zero() (from asm/semaphore.h) must execute
+ * atomically.
+ *
+ * When __up() is called, the count was negative before
+ * incrementing it, and we need to wake up somebody.
+ *
+ * This routine adds one to the count of processes that need to
+ * wake up and exit.  ALL waiting processes actually wake up but
+ * only the one that gets to the "waking" field first will gate
+ * through and acquire the semaphore.  The others will go back
+ * to sleep.
+ *
+ * Note that these functions are only called when there is
+ * contention on the lock, and as such all this is the
+ * "non-critical" part of the whole semaphore business. The
+ * critical part is the inline stuff in <asm/semaphore.h>
+ * where we want to avoid any extra jumps and calls.
+ */
+void __up(struct semaphore *sem)
+{
+	wake_one_more(sem);
+	wake_up(&sem->wait);
+}
+
+/*
+ * Perform the "down" function.  Return zero for semaphore acquired,
+ * return negative for signalled out of the function.
+ *
+ * If called from __down, the return is ignored and the wait loop is
+ * not interruptible.  This means that a task waiting on a semaphore
+ * using "down()" cannot be killed until someone does an "up()" on
+ * the semaphore.
+ *
+ * If called from __down_interruptible, the return value gets checked
+ * upon return.  If the return value is negative then the task continues
+ * with the negative value in the return register (it can be tested by
+ * the caller).
+ *
+ * Either form may be used in conjunction with "up()".
+ *
+ */
+
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	current->state = (task_state);					\
+	add_wait_queue(&sem->wait, &wait);				\
+									\
+	/*								\
+	 * Ok, we're set up.  sem->count is known to be less than zero	\
+	 * so we must wait.						\
+	 *								\
+	 * We can let go the lock for purposes of waiting.		\
+	 * We re-acquire it after awaking so as to protect		\
+	 * all semaphore operations.					\
+	 *								\
+	 * If "up()" is called before we call waking_non_zero() then	\
+	 * we will catch it right away.  If it is called later then	\
+	 * we will have to go through a wakeup cycle to catch it.	\
+	 *								\
+	 * Multiple waiters contend for the semaphore lock to see	\
+	 * who gets to gate through and who has to wait some more.	\
+	 */								\
+	for (;;) {
+
+#define DOWN_TAIL(task_state)			\
+		current->state = (task_state);	\
+	}					\
+	current->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __sched __down(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+	DECLARE_WAITQUEUE(wait, current);
+	int ret = 0;
+
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, current);
+	if (ret)
+	{
+		if (ret == 1)
+			/* ret != 0 only if we get interrupted -arca */
+			ret = 0;
+		break;
+	}
+	schedule();
+	DOWN_TAIL(TASK_INTERRUPTIBLE)
+	return ret;
+}
+
+int __down_trylock(struct semaphore * sem)
+{
+	return waking_non_zero_trylock(sem);
+}
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
new file mode 100644
index 000000000000..557238596dcb
--- /dev/null
+++ b/arch/m68knommu/kernel/setup.c
@@ -0,0 +1,347 @@
+/*
+ *  linux/arch/m68knommu/kernel/setup.c
+ *
+ *  Copyright (C) 1999-2004  Greg Ungerer (gerg@snapgear.com)
+ *  Copyright (C) 1998,1999  D. Jeff Dionne <jeff@lineo.ca>
+ *  Copyleft  ()) 2000       James D. Schettine {james@telos-systems.com}
+ *  Copyright (C) 1998       Kenneth Albanowski <kjahds@kjahds.com>
+ *  Copyright (C) 1995       Hamish Macdonald
+ *  Copyright (C) 2000       Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 2001 	     Lineo, Inc. <www.lineo.com>
+ *
+ *  68VZ328 Fixes/support    Evan Stawnyczy <e@lineo.ca>
+ */
+
+/*
+ * This file handles the architecture-dependent parts of system setup
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/major.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/root_dev.h>
+#include <linux/init.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/machdep.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <asm/pgtable.h>
+#endif
+
+unsigned long rom_length;
+unsigned long memory_start;
+unsigned long memory_end;
+
+char command_line[COMMAND_LINE_SIZE];
+
+/* setup some dummy routines */
+static void dummy_waitbut(void)
+{
+}
+
+void (*mach_sched_init) (irqreturn_t (*handler)(int, void *, struct pt_regs *)) = NULL;
+void (*mach_tick)( void ) = NULL;
+/* machine dependent keyboard functions */
+int (*mach_keyb_init) (void) = NULL;
+int (*mach_kbdrate) (struct kbd_repeat *) = NULL;
+void (*mach_kbd_leds) (unsigned int) = NULL;
+/* machine dependent irq functions */
+void (*mach_init_IRQ) (void) = NULL;
+irqreturn_t (*(*mach_default_handler)[]) (int, void *, struct pt_regs *) = NULL;
+void (*mach_enable_irq) (unsigned int) = NULL;
+void (*mach_disable_irq) (unsigned int) = NULL;
+int (*mach_get_irq_list) (struct seq_file *, void *) = NULL;
+void (*mach_process_int) (int irq, struct pt_regs *fp) = NULL;
+void (*mach_trap_init) (void);
+/* machine dependent timer functions */
+unsigned long (*mach_gettimeoffset) (void) = NULL;
+void (*mach_gettod) (int*, int*, int*, int*, int*, int*) = NULL;
+int (*mach_hwclk) (int, struct hwclk_time*) = NULL;
+int (*mach_set_clock_mmss) (unsigned long) = NULL;
+void (*mach_mksound)( unsigned int count, unsigned int ticks ) = NULL;
+void (*mach_reset)( void ) = NULL;
+void (*waitbut)(void) = dummy_waitbut;
+void (*mach_debug_init)(void) = NULL;
+void (*mach_halt)( void ) = NULL;
+void (*mach_power_off)( void ) = NULL;
+
+
+#ifdef CONFIG_M68000
+	#define CPU "MC68000"
+#endif
+#ifdef CONFIG_M68328
+	#define CPU "MC68328"
+#endif
+#ifdef CONFIG_M68EZ328
+	#define CPU "MC68EZ328"
+#endif
+#ifdef CONFIG_M68VZ328
+	#define CPU "MC68VZ328"
+#endif
+#ifdef CONFIG_M68332
+	#define CPU "MC68332"
+#endif
+#ifdef CONFIG_M68360
+	#define CPU "MC68360"
+#endif
+#if defined(CONFIG_M5206)
+	#define	CPU "COLDFIRE(m5206)"
+#endif
+#if defined(CONFIG_M5206e)
+	#define	CPU "COLDFIRE(m5206e)"
+#endif
+#if defined(CONFIG_M5249)
+	#define CPU "COLDFIRE(m5249)"
+#endif
+#if defined(CONFIG_M527x)
+	#define CPU "COLDFIRE(m5270/5271/5274/5275)"
+#endif
+#if defined(CONFIG_M5272)
+	#define CPU "COLDFIRE(m5272)"
+#endif
+#if defined(CONFIG_M528x)
+	#define CPU "COLDFIRE(m5280/5282)"
+#endif
+#if defined(CONFIG_M5307)
+	#define	CPU "COLDFIRE(m5307)"
+#endif
+#if defined(CONFIG_M5407)
+	#define	CPU "COLDFIRE(m5407)"
+#endif
+#ifndef CPU
+	#define	CPU "UNKOWN"
+#endif
+
+/* (es) */
+/* note: why is this defined here?  the must be a better place to put this */
+#if defined( CONFIG_TELOS) || defined( CONFIG_UCDIMM ) || defined( CONFIG_UCSIMM ) || defined(CONFIG_DRAGEN2) || (defined( CONFIG_PILOT ) && defined( CONFIG_M68328 ))
+#define CAT_ROMARRAY
+#endif
+/* (/es) */
+
+extern int _stext, _etext, _sdata, _edata, _sbss, _ebss, _end;
+extern int _ramstart, _ramend;
+
+void setup_arch(char **cmdline_p)
+{
+	int bootmap_size;
+
+#if defined(CAT_ROMARRAY) && defined(DEBUG)
+	extern int __data_rom_start;
+	extern int __data_start;
+	int *romarray = (int *)((int) &__data_rom_start +
+			      (int)&_edata - (int)&__data_start);
+#endif
+
+	memory_start = PAGE_ALIGN(_ramstart);
+	memory_end = _ramend; /* by now the stack is part of the init task */
+
+	init_mm.start_code = (unsigned long) &_stext;
+	init_mm.end_code = (unsigned long) &_etext;
+	init_mm.end_data = (unsigned long) &_edata;
+	init_mm.brk = (unsigned long) 0; 
+
+	config_BSP(&command_line[0], sizeof(command_line));
+
+	printk(KERN_INFO "\x0F\r\n\nuClinux/" CPU "\n");
+
+#ifdef CONFIG_UCDIMM
+	printk(KERN_INFO "uCdimm by Lineo, Inc. <www.lineo.com>\n");
+#endif
+#ifdef CONFIG_M68VZ328
+	printk(KERN_INFO "M68VZ328 support by Evan Stawnyczy <e@lineo.ca>\n");
+#endif
+#ifdef CONFIG_COLDFIRE
+	printk(KERN_INFO "COLDFIRE port done by Greg Ungerer, gerg@snapgear.com\n");
+#ifdef CONFIG_M5307
+	printk(KERN_INFO "Modified for M5307 by Dave Miller, dmiller@intellistor.com\n");
+#endif
+#ifdef CONFIG_ELITE
+	printk(KERN_INFO "Modified for M5206eLITE by Rob Scott, rscott@mtrob.fdns.net\n");
+#endif  
+#ifdef CONFIG_TELOS
+	printk(KERN_INFO "Modified for Omnia ToolVox by James D. Schettine, james@telos-systems.com\n");
+#endif
+#endif
+	printk(KERN_INFO "Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68328 )
+	printk(KERN_INFO "TRG SuperPilot FLASH card support <info@trgnet.com>\n");
+#endif
+
+#if defined( CONFIG_PILOT ) && defined( CONFIG_M68EZ328 )
+	printk(KERN_INFO "PalmV support by Lineo Inc. <jeff@uclinux.com>\n");
+#endif
+
+#ifdef CONFIG_M68EZ328ADS
+	printk(KERN_INFO "M68EZ328ADS board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+
+#ifdef CONFIG_ALMA_ANS
+	printk(KERN_INFO "Alma Electronics board support (C) 1999 Vladimir Gurevich <vgurevic@cisco.com>\n");
+#endif
+#if defined (CONFIG_M68360)
+	printk(KERN_INFO "QUICC port done by SED Systems <hamilton@sedsystems.ca>,\n");
+	printk(KERN_INFO "based on 2.0.38 port by Lineo Inc. <mleslie@lineo.com>.\n");
+#endif
+#ifdef CONFIG_DRAGEN2
+	printk(KERN_INFO "DragonEngine II board support by Georges Menie\n");
+#endif
+
+#ifdef DEBUG
+	printk(KERN_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);
+	printk(KERN_DEBUG "KERNEL -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x "
+		"STACK=0x%06x-0x%06x\n",
+#ifdef CAT_ROMARRAY
+		(int) romarray, ((int) romarray) + romarray[2],
+#else
+		(int) &_ebss, (int) memory_start,
+#endif
+		(int) memory_start, (int) memory_end,
+		(int) memory_end, (int) _ramend);
+#endif
+
+	/* Keep a copy of command line */
+	*cmdline_p = &command_line[0];
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE-1] = 0;
+
+#ifdef DEBUG
+	if (strlen(*cmdline_p)) 
+		printk(KERN_DEBUG "Command line: '%s'\n", *cmdline_p);
+#endif
+
+#if defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_DUMMY_CONSOLE)
+	conswitchp = &dummy_con;
+#endif
+
+	/*
+	 * Give all the memory to the bootmap allocator, tell it to put the
+	 * boot mem_map at the start of memory.
+	 */
+	bootmap_size = init_bootmem_node(
+			NODE_DATA(0),
+			memory_start >> PAGE_SHIFT, /* map goes here */
+			PAGE_OFFSET >> PAGE_SHIFT,	/* 0 on coldfire */
+			memory_end >> PAGE_SHIFT);
+	/*
+	 * Free the usable memory, we have to make sure we do not free
+	 * the bootmem bitmap so we then reserve it after freeing it :-)
+	 */
+	free_bootmem(memory_start, memory_end - memory_start);
+	reserve_bootmem(memory_start, bootmap_size);
+
+	/*
+	 * Get kmalloc into gear.
+	 */
+	paging_init();
+}
+
+int get_cpuinfo(char * buffer)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#ifdef CONFIG_COLDFIRE
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16;
+#endif
+
+    return(sprintf(buffer, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ)));
+
+}
+
+/*
+ *	Get CPU information for use by the procfs.
+ */
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+    char *cpu, *mmu, *fpu;
+    u_long clockfreq;
+
+    cpu = CPU;
+    mmu = "none";
+    fpu = "none";
+
+#ifdef CONFIG_COLDFIRE
+    clockfreq = (loops_per_jiffy*HZ)*3;
+#else
+    clockfreq = (loops_per_jiffy*HZ)*16;
+#endif
+
+    seq_printf(m, "CPU:\t\t%s\n"
+		   "MMU:\t\t%s\n"
+		   "FPU:\t\t%s\n"
+		   "Clocking:\t%lu.%1luMHz\n"
+		   "BogoMips:\t%lu.%02lu\n"
+		   "Calibration:\t%lu loops\n",
+		   cpu, mmu, fpu,
+		   clockfreq/1000000,(clockfreq/100000)%10,
+		   (loops_per_jiffy*HZ)/500000,((loops_per_jiffy*HZ)/5000)%100,
+		   (loops_per_jiffy*HZ));
+
+	return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	return *pos < NR_CPUS ? ((void *) 0x12345678) : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+struct seq_operations cpuinfo_op = {
+	.start	= c_start,
+	.next	= c_next,
+	.stop	= c_stop,
+	.show	= show_cpuinfo,
+};
+
+void arch_gettod(int *year, int *mon, int *day, int *hour,
+		 int *min, int *sec)
+{
+	if (mach_gettod)
+		mach_gettod(year, mon, day, hour, min, sec);
+	else
+		*year = *mon = *day = *hour = *min = *sec = 0;
+}
+
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c
new file mode 100644
index 000000000000..30dceb59a462
--- /dev/null
+++ b/arch/m68knommu/kernel/signal.c
@@ -0,0 +1,788 @@
+/*
+ *  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)))
+
+asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs);
+
+/*
+ * Atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int do_sigsuspend(struct pt_regs *regs)
+{
+	old_sigset_t mask = regs->d3;
+	sigset_t saveset;
+
+	mask &= _BLOCKABLE;
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	siginitset(&current->blocked, mask);
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int
+do_rt_sigsuspend(struct pt_regs *regs)
+{
+	sigset_t *unewset = (sigset_t *)regs->d1;
+	size_t sigsetsize = (size_t)regs->d2;
+	sigset_t saveset, newset;
+
+	/* XXX: Don't preclude handling different sized sigset_t's.  */
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&newset, unewset, sizeof(newset)))
+		return -EFAULT;
+	sigdelsetmask(&newset, ~_BLOCKABLE);
+
+	spin_lock_irq(&current->sighand->siglock);
+	saveset = current->blocked;
+	current->blocked = newset;
+	recalc_sigpending();
+	spin_unlock_irq(&current->sighand->siglock);
+
+	regs->d0 = -EINTR;
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(&saveset, regs))
+			return -EINTR;
+	}
+}
+
+asmlinkage int 
+sys_sigaction(int sig, const struct old_sigaction *act,
+	      struct old_sigaction *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))
+			return -EFAULT;
+		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
+		__get_user(mask, &act->sa_mask);
+		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))
+			return -EFAULT;
+		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+	}
+
+	return ret;
+}
+
+asmlinkage int
+sys_sigaltstack(const stack_t *uss, stack_t *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 *pretcode;
+	int sig;
+	int code;
+	struct sigcontext *psc;
+	char retcode[8];
+	unsigned long extramask[_NSIG_WORDS-1];
+	struct sigcontext sc;
+};
+
+struct rt_sigframe
+{
+	char *pretcode;
+	int sig;
+	struct siginfo *pinfo;
+	void *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 *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_pcr, 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 *)&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_pcr));
+	}
+	if (context_size &&
+	    __copy_from_user(fpstate + 4, (long *)&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 *usc, void *fp,
+		   int *pd0)
+{
+	int formatvec;
+	struct sigcontext context;
+	int err = 0;
+
+	/* 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;
+	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 *uc, int *pd0)
+{
+	int temp;
+	greg_t *gregs = uc->uc_mcontext.gregs;
+	unsigned long usp;
+	int err;
+
+	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 *frame = (struct sigframe *)(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 *frame = (struct rt_sigframe *)(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"
+				  : /* no outputs */
+				  : "m" (*sc->sc_fpregs),
+				    "m" (*sc->sc_fpcntl)
+				  : "memory");
+	}
+}
+
+static inline int rt_save_fpu_state(struct ucontext *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_pcr,
+				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 *)&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"
+				  : /* no outputs */
+				  : "m" (*fpregs.f_fpregs),
+				    "m" (fpregs.f_pcr)
+				  : "memory");
+		err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
+				    sizeof(fpregs));
+	}
+	if (context_size)
+		err |= copy_to_user((long *)&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_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 *uc, struct pt_regs *regs)
+{
+	struct switch_stack *sw = (struct switch_stack *)regs - 1;
+	greg_t *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 push_cache (unsigned long vaddr)
+{
+}
+
+static inline void *
+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 (!on_sig_stack(usp))
+			usp = current->sas_ss_sp + current->sas_ss_size;
+	}
+	return (void *)((usp - frame_size) & -8UL);
+}
+
+static void setup_frame (int sig, struct k_sigaction *ka,
+			 sigset_t *set, struct pt_regs *regs)
+{
+	struct sigframe *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(frame->retcode, &frame->pretcode);
+	/* moveq #,d0; trap #0 */
+	err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
+			  (long *)(frame->retcode));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+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 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;
+
+give_sigsegv:
+	force_sigsegv(sig, current);
+	goto adjust_stack;
+}
+
+static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
+			    sigset_t *set, struct pt_regs *regs)
+{
+	struct rt_sigframe *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(0, &frame->uc.uc_link);
+	err |= __put_user((void *)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);
+	/* moveq #,d0; notb d0; trap #0 */
+	err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
+			  (long *)(frame->retcode + 0));
+	err |= __put_user(0x4e40, (short *)(frame->retcode + 4));
+
+	if (err)
+		goto give_sigsegv;
+
+	push_cache ((unsigned long) &frame->retcode);
+
+	/* Set up registers for signal handler */
+	wrusp ((unsigned long) frame);
+	regs->pc = (unsigned long) ka->sa.sa_handler;
+
+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 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;
+
+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 -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)
+{
+	/* 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)
+		setup_rt_frame(sig, ka, info, oldset, regs);
+	else
+		setup_frame(sig, ka, oldset, regs);
+
+	if (ka->sa.sa_flags & SA_ONESHOT)
+		ka->sa.sa_handler = SIG_DFL;
+
+	if (!(ka->sa.sa_flags & SA_NODEFER)) {
+		spin_lock_irq(&current->sighand->siglock);
+		sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+		sigaddset(&current->blocked,sig);
+		recalc_sigpending();
+		spin_unlock_irq(&current->sighand->siglock);
+	}
+}
+
+/*
+ * 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 int do_signal(sigset_t *oldset, struct pt_regs *regs)
+{
+	struct k_sigaction ka;
+	siginfo_t info;
+	int signr;
+
+	/*
+	 * 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 1;
+
+	if (!oldset)
+		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 1;
+	}
+
+	/* Did we come from a system call? */
+	if (regs->orig_d0 >= 0) {
+		/* Restart the system call - no handlers present */
+		if (regs->d0 == -ERESTARTNOHAND
+		    || regs->d0 == -ERESTARTSYS
+		    || regs->d0 == -ERESTARTNOINTR) {
+			regs->d0 = regs->orig_d0;
+			regs->pc -= 2;
+		} else if (regs->d0 == -ERESTART_RESTARTBLOCK) {
+			regs->d0 = __NR_restart_syscall;
+			regs->pc -= 2;
+		}
+	}
+	return 0;
+}
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
new file mode 100644
index 000000000000..d87e1e0a1336
--- /dev/null
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -0,0 +1,208 @@
+/*
+ * linux/arch/m68knommu/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/ipc.h>
+#include <asm/cacheflush.h>
+
+/*
+ * sys_pipe() is the normal C calling standard for creating
+ * a pipe. It's not the way unix traditionally does this, though.
+ */
+asmlinkage int sys_pipe(unsigned long * fildes)
+{
+	int fd[2];
+	int error;
+
+	error = do_pipe(fd);
+	if (!error) {
+		if (copy_to_user(fildes, fd, 2*sizeof(int)))
+			error = -EFAULT;
+	}
+	return error;
+}
+
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+	unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	int error = -EBADF;
+	struct file * file = NULL;
+
+	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+	if (!(flags & MAP_ANONYMOUS)) {
+		file = fget(fd);
+		if (!file)
+			goto out;
+	}
+
+	down_write(&current->mm->mmap_sem);
+	error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+	up_write(&current->mm->mmap_sem);
+
+	if (file)
+		fput(file);
+out:
+	return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+	unsigned long prot, unsigned long flags,
+	unsigned long fd, unsigned long pgoff)
+{
+	return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
+ * handle more than 4 system call parameters, so these system calls
+ * used a memory block for parameter passing..
+ */
+
+struct mmap_arg_struct {
+	unsigned long addr;
+	unsigned long len;
+	unsigned long prot;
+	unsigned long flags;
+	unsigned long fd;
+	unsigned long offset;
+};
+
+asmlinkage int old_mmap(struct mmap_arg_struct *arg)
+{
+	struct mmap_arg_struct a;
+	int error = -EFAULT;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		goto out;
+
+	error = -EINVAL;
+	if (a.offset & ~PAGE_MASK)
+		goto out;
+
+	a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+	error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
+out:
+	return error;
+}
+
+struct sel_arg_struct {
+	unsigned long n;
+	fd_set *inp, *outp, *exp;
+	struct timeval *tvp;
+};
+
+asmlinkage int old_select(struct sel_arg_struct *arg)
+{
+	struct sel_arg_struct a;
+
+	if (copy_from_user(&a, arg, sizeof(a)))
+		return -EFAULT;
+	/* sys_select() does the appropriate kernel locking */
+	return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void *ptr, long fifth)
+{
+	int version;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	if (call <= SEMCTL)
+		switch (call) {
+		case SEMOP:
+			return sys_semop (first, (struct sembuf *)ptr, second);
+		case SEMGET:
+			return sys_semget (first, second, third);
+		case SEMCTL: {
+			union semun fourth;
+			if (!ptr)
+				return -EINVAL;
+			if (get_user(fourth.__pad, (void **) ptr))
+				return -EFAULT;
+			return sys_semctl (first, second, third, fourth);
+			}
+		default:
+			return -EINVAL;
+		}
+	if (call <= MSGCTL) 
+		switch (call) {
+		case MSGSND:
+			return sys_msgsnd (first, (struct msgbuf *) ptr, 
+					  second, third);
+		case MSGRCV:
+			switch (version) {
+			case 0: {
+				struct ipc_kludge tmp;
+				if (!ptr)
+					return -EINVAL;
+				if (copy_from_user (&tmp,
+						    (struct ipc_kludge *)ptr,
+						    sizeof (tmp)))
+					return -EFAULT;
+				return sys_msgrcv (first, tmp.msgp, second,
+						   tmp.msgtyp, third);
+				}
+			default:
+				return sys_msgrcv (first,
+						   (struct msgbuf *) ptr,
+						   second, fifth, third);
+			}
+		case MSGGET:
+			return sys_msgget ((key_t) first, second);
+		case MSGCTL:
+			return sys_msgctl (first, second,
+					   (struct msqid_ds *) ptr);
+		default:
+			return -EINVAL;
+		}
+
+	return -EINVAL;
+}
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	flush_cache_all();
+	return(0);
+}
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
diff --git a/arch/m68knommu/kernel/syscalltable.S b/arch/m68knommu/kernel/syscalltable.S
new file mode 100644
index 000000000000..897deaa06b01
--- /dev/null
+++ b/arch/m68knommu/kernel/syscalltable.S
@@ -0,0 +1,308 @@
+/*
+ *  linux/arch/m68knommu/kernel/syscalltable.S
+ *
+ *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ *  Based on older entry.S files, the following copyrights apply:
+ *
+ *  Copyright (C) 1998  D. Jeff Dionne <jeff@lineo.ca>,
+ *                      Kenneth Albanowski <kjahds@kjahds.com>,
+ *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ */
+
+#include <linux/config.h>
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/unistd.h>
+
+.text
+ALIGN
+ENTRY(sys_call_table)
+	.long sys_ni_syscall	/* 0  -  old "setup()" system call*/
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open		/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink	/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_chown16
+	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid	/* 20 */
+	.long sys_mount
+	.long sys_oldumount
+	.long sys_setuid16
+	.long sys_getuid16
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_ni_syscall	/* old stty syscall holder */
+	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_access
+	.long sys_nice
+	.long sys_ni_syscall	/* 35 */ /* old ftime syscall holder */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_ni_syscall	/* old prof syscall holder */
+	.long sys_brk		/* 45 */
+	.long sys_setgid16
+	.long sys_getgid16
+	.long sys_signal
+	.long sys_geteuid16
+	.long sys_getegid16	/* 50 */
+	.long sys_acct
+	.long sys_umount	/* recycled never used phys() */
+	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_setpgid
+	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp	/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid16	/* 70 */
+	.long sys_setregid16
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit	/* 75 */
+	.long sys_old_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups16	/* 80 */
+	.long sys_setgroups16
+	.long old_select
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink	/* 85 */
+	.long sys_uselib
+	.long sys_ni_syscall	/* sys_swapon */
+	.long sys_reboot
+	.long old_readdir
+	.long old_mmap		/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown16	/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_statfs
+	.long sys_fstatfs	/* 100 */
+	.long sys_ni_syscall	/* ioperm for i386 */
+	.long sys_socketcall
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer	/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_ni_syscall
+	.long sys_ni_syscall	/* iopl for i386 */ /* 110 */
+	.long sys_vhangup
+	.long sys_ni_syscall	/* obsolete idle() syscall */
+	.long sys_ni_syscall	/* vm86old for i386 */
+	.long sys_wait4
+	.long sys_ni_syscall	/* 115 */ /* sys_swapoff */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_cacheflush	/* modify_ldt for i386 */
+	.long sys_adjtimex
+	.long sys_ni_syscall	/* 125 */ /* sys_mprotect */
+	.long sys_sigprocmask
+	.long sys_ni_syscall	/* old "creat_module" */
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_ni_syscall	/* 130: old "get_kernel_syms" */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_setfsuid16
+	.long sys_setfsgid16
+	.long sys_llseek	/* 140 */
+	.long sys_getdents
+	.long sys_select
+	.long sys_flock
+	.long sys_ni_syscall	/* sys_msync */
+	.long sys_readv		/* 145 */
+	.long sys_writev
+	.long sys_getsid
+	.long sys_fdatasync
+	.long sys_sysctl
+	.long sys_ni_syscall	/* 150 */ /* sys_mlock */
+	.long sys_ni_syscall	/* sys_munlock */
+	.long sys_ni_syscall	/* sys_mlockall */
+	.long sys_ni_syscall	/* sys_munlockall */
+	.long sys_sched_setparam
+	.long sys_sched_getparam /* 155 */
+	.long sys_sched_setscheduler
+	.long sys_sched_getscheduler
+	.long sys_sched_yield
+	.long sys_sched_get_priority_max
+	.long sys_sched_get_priority_min  /* 160 */
+	.long sys_sched_rr_get_interval
+	.long sys_nanosleep
+	.long sys_ni_syscall	/* sys_mremap */
+	.long sys_setresuid16
+	.long sys_getresuid16	/* 165 */
+	.long sys_getpagesize	/* sys_getpagesize */
+	.long sys_ni_syscall	/* old "query_module" */
+	.long sys_poll
+	.long sys_ni_syscall	/* sys_nfsservctl */
+	.long sys_setresgid16	/* 170 */
+	.long sys_getresgid16
+	.long sys_prctl
+	.long sys_rt_sigreturn
+	.long sys_rt_sigaction
+	.long sys_rt_sigprocmask /* 175 */
+	.long sys_rt_sigpending
+	.long sys_rt_sigtimedwait
+	.long sys_rt_sigqueueinfo
+	.long sys_rt_sigsuspend
+	.long sys_pread64	/* 180 */
+	.long sys_pwrite64
+	.long sys_lchown16
+	.long sys_getcwd
+	.long sys_capget
+	.long sys_capset	/* 185 */
+	.long sys_sigaltstack
+	.long sys_sendfile
+	.long sys_ni_syscall	/* streams1 */
+	.long sys_ni_syscall	/* streams2 */
+	.long sys_vfork		/* 190 */
+	.long sys_getrlimit
+	.long sys_mmap2
+	.long sys_truncate64
+	.long sys_ftruncate64
+	.long sys_stat64	/* 195 */
+	.long sys_lstat64
+	.long sys_fstat64
+	.long sys_chown
+	.long sys_getuid
+	.long sys_getgid	/* 200 */
+	.long sys_geteuid
+	.long sys_getegid
+	.long sys_setreuid
+	.long sys_setregid
+	.long sys_getgroups	/* 205 */
+	.long sys_setgroups
+	.long sys_fchown
+	.long sys_setresuid
+	.long sys_getresuid
+	.long sys_setresgid	/* 210 */
+	.long sys_getresgid
+	.long sys_lchown
+	.long sys_setuid
+	.long sys_setgid
+	.long sys_setfsuid	/* 215 */
+	.long sys_setfsgid
+	.long sys_pivot_root
+	.long sys_ni_syscall
+	.long sys_ni_syscall
+	.long sys_getdents64	/* 220 */
+	.long sys_gettid
+	.long sys_tkill
+	.long sys_setxattr
+	.long sys_lsetxattr
+	.long sys_fsetxattr	/* 225 */
+	.long sys_getxattr
+	.long sys_lgetxattr
+	.long sys_fgetxattr
+	.long sys_listxattr
+	.long sys_llistxattr	/* 230 */
+	.long sys_flistxattr
+	.long sys_removexattr
+	.long sys_lremovexattr
+	.long sys_fremovexattr
+	.long sys_futex		/* 235 */
+	.long sys_sendfile64
+	.long sys_ni_syscall	/* sys_mincore */
+	.long sys_ni_syscall	/* sys_madvise */
+	.long sys_fcntl64
+	.long sys_readahead	/* 240 */
+	.long sys_io_setup
+	.long sys_io_destroy
+	.long sys_io_getevents
+	.long sys_io_submit
+	.long sys_io_cancel	/* 245 */
+	.long sys_fadvise64
+	.long sys_exit_group
+	.long sys_lookup_dcookie
+	.long sys_epoll_create
+	.long sys_epoll_ctl	/* 250 */
+	.long sys_epoll_wait
+	.long sys_ni_syscall	/* sys_remap_file_pages */
+	.long sys_set_tid_address
+	.long sys_timer_create
+	.long sys_timer_settime	/* 255 */
+	.long sys_timer_gettime
+	.long sys_timer_getoverrun
+	.long sys_timer_delete
+	.long sys_clock_settime
+	.long sys_clock_gettime	/* 260 */
+	.long sys_clock_getres
+	.long sys_clock_nanosleep
+	.long sys_statfs64
+	.long sys_fstatfs64
+	.long sys_tgkill	/* 265 */
+	.long sys_utimes
+	.long sys_fadvise64_64
+	.long sys_mbind	
+	.long sys_get_mempolicy
+	.long sys_set_mempolicy	/* 270 */
+	.long sys_mq_open
+	.long sys_mq_unlink
+	.long sys_mq_timedsend
+	.long sys_mq_timedreceive
+	.long sys_mq_notify	/* 275 */
+	.long sys_mq_getsetattr
+	.long sys_waitid
+	.long sys_ni_syscall	/* sys_setaltroot */
+	.long sys_ni_syscall	/* sys_add_key */
+	.long sys_ni_syscall	/* 280 */ /* sys_request_key */
+	.long sys_ni_syscall	/* sys_keyctl */
+
+	.rept NR_syscalls-(.-sys_call_table)/4
+		.long sys_ni_syscall
+	.endr
+
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c
new file mode 100644
index 000000000000..5c3ca671627c
--- /dev/null
+++ b/arch/m68knommu/kernel/time.c
@@ -0,0 +1,198 @@
+/*
+ *  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/config.h>
+#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/io.h>
+
+#define	TICK_SIZE (tick_nsec / 1000)
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
+extern unsigned long wall_jiffies;
+
+
+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 "do_timer()" routine every clocktick
+ */
+static irqreturn_t timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
+{
+	/* last time the cmos clock got updated */
+	static long last_rtc_update=0;
+
+	/* may need to kick the hardware timer */
+	if (mach_tick)
+	  mach_tick();
+
+	write_seqlock(&xtime_lock);
+
+	do_timer(regs);
+#ifndef CONFIG_SMP
+	update_process_times(user_mode(regs));
+#endif
+	if (current->pid)
+		profile_tick(CPU_PROFILING, regs);
+
+	/*
+	 * If we have an externally synchronized Linux clock, then update
+	 * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
+	 * called as close as possible to 500 ms before the new second starts.
+	 */
+	if ((time_status & STA_UNSYNC) == 0 &&
+	    xtime.tv_sec > last_rtc_update + 660 &&
+	    (xtime.tv_nsec / 1000) >= 500000 - ((unsigned) TICK_SIZE) / 2 &&
+	    (xtime.tv_nsec  / 1000) <= 500000 + ((unsigned) TICK_SIZE) / 2) {
+	  if (set_rtc_mmss(xtime.tv_sec) == 0)
+	    last_rtc_update = xtime.tv_sec;
+	  else
+	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+	}
+#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 */
+
+	write_sequnlock(&xtime_lock);
+	return(IRQ_HANDLED);
+}
+
+void time_init(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	extern void arch_gettod(int *year, int *mon, int *day, int *hour,
+				int *min, int *sec);
+
+	arch_gettod(&year, &mon, &day, &hour, &min, &sec);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_nsec = 0;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
+
+	mach_sched_init(timer_interrupt);
+}
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	unsigned long lost, seq;
+	unsigned long usec, sec;
+
+	do {
+		seq = read_seqbegin_irqsave(&xtime_lock, flags);
+		usec = mach_gettimeoffset ? mach_gettimeoffset() : 0;
+		lost = jiffies - wall_jiffies;
+		if (lost)
+			usec += lost * (1000000 / HZ);
+		sec = xtime.tv_sec;
+		usec += (xtime.tv_nsec / 1000);
+	} while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
+
+	while (usec >= 1000000) {
+		usec -= 1000000;
+		sec++;
+	}
+
+	tv->tv_sec = sec;
+	tv->tv_usec = usec;
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
+int do_settimeofday(struct timespec *tv)
+{
+	time_t wtm_sec, sec = tv->tv_sec;
+	long wtm_nsec, nsec = tv->tv_nsec;
+
+	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
+		return -EINVAL;
+
+	write_seqlock_irq(&xtime_lock);
+	/*
+	 * This is revolting. We need to set the xtime.tv_usec
+	 * correctly. However, the value in this location is
+	 * is value at the last tick.
+	 * Discover what correction gettimeofday
+	 * would have done, and then undo it!
+	 */
+	if (mach_gettimeoffset)
+		nsec -= (mach_gettimeoffset() * 1000);
+
+	wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
+	wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
+
+	set_normalized_timespec(&xtime, sec, nsec);
+	set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
+
+	time_adjust = 0;		/* stop active adjtime() */
+	time_status |= STA_UNSYNC;
+	time_maxerror = NTP_PHASE_LIMIT;
+	time_esterror = NTP_PHASE_LIMIT;
+	write_sequnlock_irq(&xtime_lock);
+	clock_was_set();
+	return 0;
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+}
+
+EXPORT_SYMBOL(do_settimeofday);
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
new file mode 100644
index 000000000000..ad7dc6347f19
--- /dev/null
+++ b/arch/m68knommu/kernel/traps.c
@@ -0,0 +1,320 @@
+/*
+ *  linux/arch/m68knommu/kernel/traps.c
+ *
+ *  Copyright (C) 1993, 1994 by Hamish Macdonald
+ *
+ *  68040 fixes by Michael Rausch
+ *  68040 fixes by Martin Apel
+ *  68060 fixes by Roman Hodek
+ *  68060 fixes by Jesper Skov
+ *
+ * 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.
+ */
+
+/*
+ * Sets up all exception vectors
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/a.out.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/ptrace.h>
+
+#include <asm/setup.h>
+#include <asm/fpu.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/traps.h>
+#include <asm/pgtable.h>
+#include <asm/machdep.h>
+#include <asm/siginfo.h>
+
+static char *vec_names[] = {
+	"RESET SP", "RESET PC", "BUS ERROR", "ADDRESS ERROR",
+	"ILLEGAL INSTRUCTION", "ZERO DIVIDE", "CHK", "TRAPcc",
+	"PRIVILEGE VIOLATION", "TRACE", "LINE 1010", "LINE 1111",
+	"UNASSIGNED RESERVED 12", "COPROCESSOR PROTOCOL VIOLATION",
+	"FORMAT ERROR", "UNINITIALIZED INTERRUPT",
+	"UNASSIGNED RESERVED 16", "UNASSIGNED RESERVED 17",
+	"UNASSIGNED RESERVED 18", "UNASSIGNED RESERVED 19",
+	"UNASSIGNED RESERVED 20", "UNASSIGNED RESERVED 21",
+	"UNASSIGNED RESERVED 22", "UNASSIGNED RESERVED 23",
+	"SPURIOUS INTERRUPT", "LEVEL 1 INT", "LEVEL 2 INT", "LEVEL 3 INT",
+	"LEVEL 4 INT", "LEVEL 5 INT", "LEVEL 6 INT", "LEVEL 7 INT",
+	"SYSCALL", "TRAP #1", "TRAP #2", "TRAP #3",
+	"TRAP #4", "TRAP #5", "TRAP #6", "TRAP #7",
+	"TRAP #8", "TRAP #9", "TRAP #10", "TRAP #11",
+	"TRAP #12", "TRAP #13", "TRAP #14", "TRAP #15",
+	"FPCP BSUN", "FPCP INEXACT", "FPCP DIV BY 0", "FPCP UNDERFLOW",
+	"FPCP OPERAND ERROR", "FPCP OVERFLOW", "FPCP SNAN",
+	"FPCP UNSUPPORTED OPERATION",
+	"MMU CONFIGURATION ERROR"
+};
+
+void __init trap_init(void)
+{
+	if (mach_trap_init)
+		mach_trap_init();
+}
+
+void die_if_kernel(char *str, struct pt_regs *fp, int nr)
+{
+	if (!(fp->sr & PS_S))
+		return;
+
+	console_verbose();
+	printk(KERN_EMERG "%s: %08x\n",str,nr);
+	printk(KERN_EMERG "PC: [<%08lx>]\nSR: %04x  SP: %p  a2: %08lx\n",
+	       fp->pc, fp->sr, fp, fp->a2);
+	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 "Process %s (pid: %d, stackpage=%08lx)\n",
+		current->comm, current->pid, PAGE_SIZE+(unsigned long)current);
+	show_stack(NULL, (unsigned long *)fp);
+	do_exit(SIGSEGV);
+}
+
+asmlinkage void buserr_c(struct frame *fp)
+{
+	/* Only set esp0 if coming from user mode */
+	if (user_mode(&fp->ptregs))
+		current->thread.esp0 = (unsigned long) fp;
+
+#if DEBUG
+	printk (KERN_DEBUG "*** Bus Error *** Format is %x\n", fp->ptregs.format);
+#endif
+
+	die_if_kernel("bad frame format",&fp->ptregs,0);
+#if DEBUG
+	printk(KERN_DEBUG "Unknown SIGSEGV - 4\n");
+#endif
+	force_sig(SIGSEGV, current);
+}
+
+
+int kstack_depth_to_print = 48;
+
+void show_stack(struct task_struct *task, unsigned long *esp)
+{
+	unsigned long *stack, *endstack, addr;
+	extern char _start, _etext;
+	int i;
+
+	if (esp == NULL)
+		esp = (unsigned long *) &esp;
+
+	stack = esp;
+	addr = (unsigned long) esp;
+	endstack = (unsigned long *) PAGE_ALIGN(addr);
+
+	printk(KERN_EMERG "Stack from %08lx:", (unsigned long)stack);
+	for (i = 0; i < kstack_depth_to_print; i++) {
+		if (stack + 1 > endstack)
+			break;
+		if (i % 8 == 0)
+			printk(KERN_EMERG "\n       ");
+		printk(KERN_EMERG " %08lx", *stack++);
+	}
+
+	printk(KERN_EMERG "\nCall Trace:");
+	i = 0;
+	while (stack + 1 <= endstack) {
+		addr = *stack++;
+		/*
+		 * If the address is either in the text segment of the
+		 * kernel, or in the region which contains vmalloc'ed
+		 * memory, it *may* be the address of a calling
+		 * routine; if so, print it so that someone tracing
+		 * down the cause of the crash will be able to figure
+		 * out the call path that was taken.
+		 */
+		if (((addr >= (unsigned long) &_start) &&
+		     (addr <= (unsigned long) &_etext))) {
+			if (i % 4 == 0)
+				printk(KERN_EMERG "\n       ");
+			printk(KERN_EMERG " [<%08lx>]", addr);
+			i++;
+		}
+	}
+	printk(KERN_EMERG "\n");
+}
+
+void bad_super_trap(struct frame *fp)
+{
+	console_verbose();
+	if (fp->ptregs.vector < 4*sizeof(vec_names)/sizeof(vec_names[0]))
+		printk (KERN_WARNING "*** %s ***   FORMAT=%X\n",
+			vec_names[(fp->ptregs.vector) >> 2],
+			fp->ptregs.format);
+	else
+		printk (KERN_WARNING "*** Exception %d ***   FORMAT=%X\n",
+			(fp->ptregs.vector) >> 2, 
+			fp->ptregs.format);
+	printk (KERN_WARNING "Current process id is %d\n", current->pid);
+	die_if_kernel("BAD KERNEL TRAP", &fp->ptregs, 0);
+}
+
+asmlinkage void trap_c(struct frame *fp)
+{
+	int sig;
+	siginfo_t info;
+
+	if (fp->ptregs.sr & PS_S) {
+		if ((fp->ptregs.vector >> 2) == VEC_TRACE) {
+			/* traced a trapping instruction */
+			current->ptrace |= PT_DTRACE;
+		} else
+			bad_super_trap(fp);
+		return;
+	}
+
+	/* send the appropriate signal to the user program */
+	switch ((fp->ptregs.vector) >> 2) {
+	    case VEC_ADDRERR:
+		info.si_code = BUS_ADRALN;
+		sig = SIGBUS;
+		break;
+	    case VEC_ILLEGAL:
+	    case VEC_LINE10:
+	    case VEC_LINE11:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_PRIV:
+		info.si_code = ILL_PRVOPC;
+		sig = SIGILL;
+		break;
+	    case VEC_COPROC:
+		info.si_code = ILL_COPROC;
+		sig = SIGILL;
+		break;
+	    case VEC_TRAP1: /* gdbserver breakpoint */
+		fp->ptregs.pc -= 2;
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP2:
+	    case VEC_TRAP3:
+	    case VEC_TRAP4:
+	    case VEC_TRAP5:
+	    case VEC_TRAP6:
+	    case VEC_TRAP7:
+	    case VEC_TRAP8:
+	    case VEC_TRAP9:
+	    case VEC_TRAP10:
+	    case VEC_TRAP11:
+	    case VEC_TRAP12:
+	    case VEC_TRAP13:
+	    case VEC_TRAP14:
+		info.si_code = ILL_ILLTRP;
+		sig = SIGILL;
+		break;
+	    case VEC_FPBRUC:
+	    case VEC_FPOE:
+	    case VEC_FPNAN:
+		info.si_code = FPE_FLTINV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPIR:
+		info.si_code = FPE_FLTRES;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPDIVZ:
+		info.si_code = FPE_FLTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPUNDER:
+		info.si_code = FPE_FLTUND;
+		sig = SIGFPE;
+		break;
+	    case VEC_FPOVER:
+		info.si_code = FPE_FLTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_ZERODIV:
+		info.si_code = FPE_INTDIV;
+		sig = SIGFPE;
+		break;
+	    case VEC_CHK:
+	    case VEC_TRAP:
+		info.si_code = FPE_INTOVF;
+		sig = SIGFPE;
+		break;
+	    case VEC_TRACE:		/* ptrace single step */
+		info.si_code = TRAP_TRACE;
+		sig = SIGTRAP;
+		break;
+	    case VEC_TRAP15:		/* breakpoint */
+		info.si_code = TRAP_BRKPT;
+		sig = SIGTRAP;
+		break;
+	    default:
+		info.si_code = ILL_ILLOPC;
+		sig = SIGILL;
+		break;
+	}
+	info.si_signo = sig;
+	info.si_errno = 0;
+	switch (fp->ptregs.format) {
+	    default:
+		info.si_addr = (void *) fp->ptregs.pc;
+		break;
+	    case 2:
+		info.si_addr = (void *) fp->un.fmt2.iaddr;
+		break;
+	    case 7:
+		info.si_addr = (void *) fp->un.fmt7.effaddr;
+		break;
+	    case 9:
+		info.si_addr = (void *) fp->un.fmt9.iaddr;
+		break;
+	    case 10:
+		info.si_addr = (void *) fp->un.fmta.daddr;
+		break;
+	    case 11:
+		info.si_addr = (void *) fp->un.fmtb.daddr;
+		break;
+	}
+	force_sig_info (sig, &info, current);
+}
+
+asmlinkage void set_esp0(unsigned long ssp)
+{
+	current->thread.esp0 = ssp;
+}
+
+
+/*
+ * The architecture-independent backtrace generator
+ */
+void dump_stack(void)
+{
+	unsigned long stack;
+
+	show_stack(current, &stack);
+}
+
+#ifdef CONFIG_M68KFPU_EMU
+asmlinkage void fpemu_signal(int signal, int code, void *addr)
+{
+	siginfo_t info;
+
+	info.si_signo = signal;
+	info.si_errno = 0;
+	info.si_code = code;
+	info.si_addr = addr;
+	force_sig_info(signal, &info, current);
+}
+#endif
diff --git a/arch/m68knommu/kernel/vmlinux.lds.S b/arch/m68knommu/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..31cb12892da5
--- /dev/null
+++ b/arch/m68knommu/kernel/vmlinux.lds.S
@@ -0,0 +1,348 @@
+/*
+ *	vmlinux.lds.S -- master linker script for m68knommu arch
+ *
+ *	(C) Copyright 2002-2004, Greg Ungerer <gerg@snapgear.com>
+ *
+ *	This ends up looking compilcated, because of the number of
+ *	address variations for ram and rom/flash layouts. The real
+ *	work of the linker script is all at the end, and reasonably
+ *	strait forward.
+ */
+
+#include <linux/config.h>
+#include <asm-generic/vmlinux.lds.h>
+
+/*
+ *	Original Palm pilot (same for Xcopilot).
+ *	There is really only a rom target for this.
+ */
+#ifdef CONFIG_PILOT3
+#define	ROMVEC_START	0x10c00000
+#define	ROMVEC_LENGTH	0x10400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0xfec00
+#define	ROM_END		0x10d00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x10000400
+#define	RAM_LENGTH	0xffc00
+#define	RAM_END		0x10100000
+#define _ramend	_ram_end_notused
+#define	DATA_ADDR	RAM_START
+#endif
+
+/*
+ *	Same setup on both the uCsimm and uCdimm.
+ */
+#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM)
+#ifdef CONFIG_RAMKERNEL
+#define	ROMVEC_START	0x10c10000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x10e00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020400
+#define	RAM_LENGTH	0x7dfc00
+#define	RAM_END		0x00800000
+#endif
+#ifdef CONFIG_ROMKERNEL
+#define	ROMVEC_START	0x10c10000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x10c10400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x10e00000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020000
+#define	RAM_LENGTH	0x600000
+#define	RAM_END		0x00800000
+#endif
+#ifdef CONFIG_HIMEMKERNEL
+#define	ROMVEC_START	0x00600000
+#define	ROMVEC_LENGTH	0x400
+#define	ROM_START	0x00600400
+#define	ROM_LENGTH	0x1efc00
+#define	ROM_END		0x007f0000
+#define	RAMVEC_START	0x00000000
+#define	RAMVEC_LENGTH	0x400
+#define	RAM_START	0x00020000
+#define	RAM_LENGTH	0x5e0000
+#define	RAM_END		0x00600000
+#endif
+#endif
+
+#ifdef CONFIG_DRAGEN2
+#define	RAM_START	0x10000
+#define	RAM_LENGTH	0x7f0000
+#endif
+
+#ifdef CONFIG_UCQUICC
+#define	ROMVEC_START	0x00000000
+#define	ROMVEC_LENGTH	0x404
+#define	ROM_START	0x00000404
+#define	ROM_LENGTH	0x1ff6fc
+#define	ROM_END		0x00200000
+#define	RAMVEC_START	0x00200000
+#define	RAMVEC_LENGTH	0x404
+#define	RAM_START	0x00200404
+#define	RAM_LENGTH	0x1ff6fc
+#define	RAM_END		0x00400000
+#endif
+
+/*
+ *	The standard Arnewsh 5206 board only has 1MiB of ram. Not normally
+ *	enough to be useful. Assume the user has fitted something larger,
+ *	at least 4MiB in size. No point in not letting the kernel completely
+ *	link, it will be obvious if it is too big when they go to load it.
+ */
+#if defined(CONFIG_ARN5206)
+#define	RAM_START	0x10000
+#define	RAM_LENGTH	0x3f0000
+#endif
+
+/*
+ *	The Motorola 5206eLITE board only has 1MiB of static RAM.
+ */
+#if defined(CONFIG_ELITE)
+#define	RAM_START	0x30020000
+#define	RAM_END		0xe0000
+#endif
+
+/*
+ *	All the Motorola eval boards have the same basic arrangement.
+ *	The end of RAM will vary depending on how much ram is fitted,
+ *	but this isn't important here, we assume at least 4MiB.
+ */
+#if defined(CONFIG_M5206eC3) || defined(CONFIG_M5249C3) || \
+    defined(CONFIG_M5272C3) || defined(CONFIG_M5307C3) || \
+    defined(CONFIG_ARN5307) || defined(CONFIG_M5407C3) || \
+    defined(CONFIG_M5271EVB) || defined(CONFIG_M5275EVB)
+#define	RAM_START	0x20000
+#define	RAM_LENGTH	0x3e0000
+#endif
+
+/*
+ *	The senTec COBRA5272 board has nearly the same memory layout as 
+ *	the M5272C3. We assume 16MiB ram.
+ */
+#if defined(CONFIG_COBRA5272)
+#define RAM_START   0x20000
+#define RAM_LENGTH  0xfe0000
+#endif
+
+#if defined(CONFIG_M5282EVB)
+#define	RAM_START	0x10000
+#define	RAM_LENGTH	0x3f0000
+#endif
+
+/*
+ *	The senTec COBRA5282 board has the same memory layout as the M5282EVB.
+ */
+#if defined(CONFIG_COBRA5282)
+#define  RAM_START   0x10000
+#define  RAM_LENGTH  0x3f0000
+#endif
+
+/*
+ *	These flash boot boards use all of ram for operation. Again the
+ *	actual memory size is not important here, assume at least 4MiB.
+ *	They currently have no support for running in flash.
+ */
+#if defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
+    defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \
+    defined(CONFIG_HW_FEITH)
+#define	RAM_START	0x400
+#define	RAM_LENGTH	0x3ffc00
+#endif
+
+/*
+ *	Sneha Boards mimimun memmory
+ *	The end of RAM will vary depending on how much ram is fitted,
+ *	but this isn't important here, we assume at least 4MiB.
+ */
+#if defined(CONFIG_CPU16B)   
+#define	RAM_START	0x20000
+#define	RAM_LENGTH	0x3e0000
+#endif
+
+
+#if defined(CONFIG_RAMKERNEL)
+#define	TEXT		ram
+#define	DATA		ram
+#define	INIT		ram
+#define	BSS		ram
+#endif
+#if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL)
+#define	TEXT		rom
+#define	DATA		ram
+#define	INIT		ram
+#define	BSS		ram
+#endif
+
+#ifndef DATA_ADDR
+#define	DATA_ADDR
+#endif
+
+
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+
+MEMORY {
+#ifdef RAMVEC_START
+	ramvec	: ORIGIN = RAMVEC_START, LENGTH = RAMVEC_LENGTH
+#endif
+	ram	: ORIGIN = RAM_START, LENGTH = RAM_LENGTH
+#ifdef RAM_END
+	eram	: ORIGIN = RAM_END, LENGTH = 0
+#endif
+#ifdef ROM_START
+	romvec	: ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH
+	rom	: ORIGIN = ROM_START, LENGTH = ROM_LENGTH
+	erom	: ORIGIN = ROM_END, LENGTH = 0
+#endif
+}
+
+jiffies = jiffies_64 + 4;
+
+SECTIONS {
+
+#ifdef ROMVEC_START
+	. = ROMVEC_START ;
+	.romvec : {
+		__rom_start = . ;
+		_romvec = .;
+		*(.data.initvect)
+	} > romvec
+#endif
+
+	.text : {
+		_stext = . ;
+        	*(.text)
+		SCHED_TEXT
+        	*(.text.lock)
+
+		. = 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 = .;
+		*(__ksymtab)
+		__stop___ksymtab = .;
+
+		/* Kernel symbol table: GPL-only symbols */
+		__start___ksymtab_gpl = .;
+		*(__ksymtab_gpl)
+		__stop___ksymtab_gpl = .;
+
+		/* Kernel symbol table: Normal symbols */
+		__start___kcrctab = .;
+		*(__kcrctab)
+		__stop___kcrctab = .;
+
+		/* Kernel symbol table: GPL-only symbols */
+		__start___kcrctab_gpl = .;
+		*(__kcrctab_gpl)
+		__stop___kcrctab_gpl = .;
+
+		/* Kernel symbol table: strings */
+		*(__ksymtab_strings)
+
+		/* Built-in module parameters */
+		__start___param = .;
+		*(__param)
+		__stop___param = .;
+
+		. = ALIGN(4) ;
+		_etext = . ;
+	} > TEXT
+
+#ifdef ROM_END
+	. = ROM_END ;
+	.erom : {
+		__rom_end = . ;
+	} > erom
+#endif
+#ifdef RAMVEC_START
+	. = RAMVEC_START ;
+	.ramvec : {
+		__ramvec = .;
+	} > ramvec
+#endif
+
+	.data DATA_ADDR : {
+		. = ALIGN(4);
+		_sdata = . ;
+		*(.data)
+		. = ALIGN(8192) ;
+		*(.data.init_task)
+		_edata = . ;
+	} > DATA
+
+	.init : {
+		. = ALIGN(4096);
+		__init_begin = .;
+		_sinittext = .;
+		*(.init.text)
+		_einittext = .;
+		*(.init.data)
+		. = ALIGN(16);
+		__setup_start = .;
+		*(.init.setup)
+		__setup_end = .;
+		__initcall_start = .;
+		*(.initcall1.init)
+		*(.initcall2.init)
+		*(.initcall3.init)
+		*(.initcall4.init)
+		*(.initcall5.init)
+		*(.initcall6.init)
+		*(.initcall7.init)
+		__initcall_end = .;
+		__con_initcall_start = .;
+		*(.con_initcall.init)
+		__con_initcall_end = .;
+		__security_initcall_start = .;
+		*(.security_initcall.init)
+		__security_initcall_end = .;
+		. = ALIGN(4);
+		__initramfs_start = .;
+		*(.init.ramfs)
+		__initramfs_end = .;
+		. = ALIGN(4096);
+		__init_end = .;
+	} > INIT
+
+	/DISCARD/ : {
+		*(.exit.text)
+		*(.exit.data)
+		*(.exitcall.exit)
+	}
+
+	.bss : {
+		. = ALIGN(4);
+		_sbss = . ;
+		*(.bss)
+		*(COMMON)
+		. = ALIGN(4) ;
+		_ebss = . ;
+	} > BSS
+
+#ifdef RAM_END
+	. = RAM_END ;
+	.eram : {
+		__ramend = . ;
+		_ramend = . ;
+	} > eram
+#endif
+}
+