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!
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
new file mode 100644
index 0000000..1546a0e
--- /dev/null
+++ b/arch/cris/kernel/Makefile
@@ -0,0 +1,15 @@
+# $Id: Makefile,v 1.10 2004/05/14 10:18:12 starvik Exp $
+#
+# Makefile for the linux kernel.
+#
+
+extra-y	:= vmlinux.lds
+
+obj-y   := process.o traps.o irq.o ptrace.o setup.o \
+	   time.o sys_cris.o semaphore.o
+
+obj-$(CONFIG_MODULES)    += crisksyms.o
+obj-$(CONFIG_MODULES)	 += module.o
+
+clean:
+
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
new file mode 100644
index 0000000..7141bbe
--- /dev/null
+++ b/arch/cris/kernel/crisksyms.c
@@ -0,0 +1,103 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/sched.h>
+#include <linux/in6.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/pm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+
+#include <asm/semaphore.h>
+#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/checksum.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/irq.h>
+#include <asm/pgtable.h>
+#include <asm/fasttimer.h>
+
+extern void dump_thread(struct pt_regs *, struct user *);
+extern unsigned long get_cmos_time(void);
+extern void __Udiv(void);
+extern void __Umod(void);
+extern void __Div(void);
+extern void __Mod(void);
+extern void __ashrdi3(void);
+extern void iounmap(void *addr);
+
+/* Platform dependent support */
+EXPORT_SYMBOL(dump_thread);
+EXPORT_SYMBOL(enable_irq);
+EXPORT_SYMBOL(disable_irq);
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(get_cmos_time);
+EXPORT_SYMBOL(loops_per_usec);
+
+/* String functions */
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(strpbrk);
+EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strchr);
+EXPORT_SYMBOL(strcmp);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcat);
+EXPORT_SYMBOL(strncat);
+EXPORT_SYMBOL(strncmp);
+EXPORT_SYMBOL(strncpy);
+
+/* Math functions */
+EXPORT_SYMBOL(__Udiv);
+EXPORT_SYMBOL(__Umod);
+EXPORT_SYMBOL(__Div);
+EXPORT_SYMBOL(__Mod);
+EXPORT_SYMBOL(__ashrdi3);
+
+/* Memory functions */
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+/* Semaphore functions */
+EXPORT_SYMBOL(__up);
+EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
+EXPORT_SYMBOL(__down_trylock);
+
+/* Export shadow registers for the CPU I/O pins */
+EXPORT_SYMBOL(genconfig_shadow);
+EXPORT_SYMBOL(port_pa_data_shadow);
+EXPORT_SYMBOL(port_pa_dir_shadow);
+EXPORT_SYMBOL(port_pb_data_shadow);
+EXPORT_SYMBOL(port_pb_dir_shadow);
+EXPORT_SYMBOL(port_pb_config_shadow);
+EXPORT_SYMBOL(port_g_data_shadow);
+
+/* Userspace access functions */
+EXPORT_SYMBOL(__copy_user_zeroing);
+EXPORT_SYMBOL(__copy_user);
+
+/* Cache flush functions */
+EXPORT_SYMBOL(flush_etrax_cache);
+EXPORT_SYMBOL(prepare_rx_descriptor);
+
+#undef memcpy
+#undef memset
+extern void * memset(void *, int, __kernel_size_t);
+extern void * memcpy(void *, const void *, __kernel_size_t);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+
+#ifdef CONFIG_ETRAX_FAST_TIMER
+/* Fast timer functions */
+EXPORT_SYMBOL(fast_timer_list);
+EXPORT_SYMBOL(start_one_shot_timer);
+EXPORT_SYMBOL(del_fast_timer);
+EXPORT_SYMBOL(schedule_usleep);
+#endif
+
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
new file mode 100644
index 0000000..d848b94
--- /dev/null
+++ b/arch/cris/kernel/irq.c
@@ -0,0 +1,297 @@
+/*
+ *
+ *	linux/arch/cris/kernel/irq.c
+ *
+ *      Copyright (c) 2000,2001 Axis Communications AB
+ *
+ *      Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * Notice Linux/CRIS: these routines do not care about SMP
+ *
+ */
+
+/*
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/ptrace.h>
+
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
+
+#include <asm/io.h>
+
+/* Defined in arch specific irq.c */
+extern void arch_setup_irq(int irq);
+extern void arch_free_irq(int irq);
+
+void
+disable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	
+	local_save_flags(flags);
+	local_irq_disable();
+	mask_irq(irq_nr);
+	local_irq_restore(flags);
+}
+
+void
+enable_irq(unsigned int irq_nr)
+{
+	unsigned long flags;
+	local_save_flags(flags);
+	local_irq_disable();
+	unmask_irq(irq_nr);
+	local_irq_restore(flags);
+}
+
+unsigned long
+probe_irq_on()
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(probe_irq_on);
+
+int
+probe_irq_off(unsigned long x)
+{
+	return 0;
+}
+
+EXPORT_SYMBOL(probe_irq_off);
+
+/*
+ * Initial irq handlers.
+ */
+
+static struct irqaction *irq_action[NR_IRQS];
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+	int i = *(loff_t *) v;
+	struct irqaction * action;
+	unsigned long flags;
+
+	if (i < NR_IRQS) {
+		local_irq_save(flags);
+		action = irq_action[i];
+		if (!action) 
+			goto skip;
+		seq_printf(p, "%2d: %10u %c %s",
+			i, kstat_this_cpu.irqs[i],
+			(action->flags & SA_INTERRUPT) ? '+' : ' ',
+			action->name);
+		for (action = action->next; action; action = action->next) {
+			seq_printf(p, ",%s %s",
+				(action->flags & SA_INTERRUPT) ? " +" : "",
+				action->name);
+		}
+		seq_putc(p, '\n');
+skip:
+		local_irq_restore(flags);
+	}
+	return 0;
+}
+
+/* called by the assembler IRQ entry functions defined in irq.h
+ * to dispatch the interrupts to registred handlers
+ * interrupts are disabled upon entry - depending on if the
+ * interrupt was registred with SA_INTERRUPT or not, interrupts
+ * are re-enabled or not.
+ */
+
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+	struct irqaction *action;
+	int do_random, cpu;
+        int ret, retval = 0;
+
+        cpu = smp_processor_id();
+        irq_enter();
+	kstat_cpu(cpu).irqs[irq - FIRST_IRQ]++;
+	action = irq_action[irq - FIRST_IRQ];
+
+        if (action) {
+                if (!(action->flags & SA_INTERRUPT))
+                        local_irq_enable();
+                do_random = 0;
+                do {
+			ret = action->handler(irq, action->dev_id, regs);
+			if (ret == IRQ_HANDLED)
+				do_random |= action->flags;
+                        retval |= ret;
+                        action = action->next;
+                } while (action);
+
+                if (retval != 1) {
+			if (retval) {
+				printk("irq event %d: bogus retval mask %x\n",
+					irq, retval);
+			} else {
+				printk("irq %d: nobody cared\n", irq);
+			}
+		}
+
+                if (do_random & SA_SAMPLE_RANDOM)
+                        add_interrupt_randomness(irq);
+		local_irq_disable();
+        }
+        irq_exit();
+}
+
+/* this function links in a handler into the chain of handlers for the
+   given irq, and if the irq has never been registred, the appropriate
+   handler is entered into the interrupt vector
+*/
+
+int setup_irq(int irq, struct irqaction * new)
+{
+	int shared = 0;
+	struct irqaction *old, **p;
+	unsigned long flags;
+
+	p = irq_action + irq - FIRST_IRQ;
+	if ((old = *p) != NULL) {
+		/* Can't share interrupts unless both agree to */
+		if (!(old->flags & new->flags & SA_SHIRQ))
+			return -EBUSY;
+
+		/* Can't share interrupts unless both are same type */
+		if ((old->flags ^ new->flags) & SA_INTERRUPT)
+			return -EBUSY;
+
+		/* add new interrupt at end of irq queue */
+		do {
+			p = &old->next;
+			old = *p;
+		} while (old);
+		shared = 1;
+	}
+
+	if (new->flags & SA_SAMPLE_RANDOM)
+		rand_initialize_irq(irq);
+
+	local_save_flags(flags);
+	local_irq_disable();
+	*p = new;
+
+	if (!shared) {
+		/* if the irq wasn't registred before, enter it into the vector table
+		   and unmask it physically 
+		*/
+		arch_setup_irq(irq);
+		unmask_irq(irq);
+	}
+	
+	local_irq_restore(flags);
+	return 0;
+}
+
+/* this function is called by a driver to register an irq handler
+   Valid flags:
+   SA_INTERRUPT -> it's a fast interrupt, handler called with irq disabled and
+                   no signal checking etc is performed upon exit
+   SA_SHIRQ -> the interrupt can be shared between different handlers, the handler
+                is required to check if the irq was "aimed" at it explicitely
+   SA_RANDOM -> the interrupt will add to the random generators entropy
+*/
+
+int request_irq(unsigned int irq, 
+		irqreturn_t (*handler)(int, void *, struct pt_regs *),
+		unsigned long irqflags, 
+		const char * devname,
+		void *dev_id)
+{
+	int retval;
+	struct irqaction * action;
+
+	if(!handler)
+		return -EINVAL;
+
+	/* allocate and fill in a handler structure and setup the irq */
+
+	action = (struct irqaction *)kmalloc(sizeof(struct irqaction), GFP_KERNEL);
+	if (!action)
+		return -ENOMEM;
+
+	action->handler = handler;
+	action->flags = irqflags;
+	cpus_clear(action->mask);
+	action->name = devname;
+	action->next = NULL;
+	action->dev_id = dev_id;
+
+	retval = setup_irq(irq, action);
+
+	if (retval)
+		kfree(action);
+	return retval;
+}
+
+EXPORT_SYMBOL(request_irq);
+		
+void free_irq(unsigned int irq, void *dev_id)
+{
+	struct irqaction * action, **p;
+	unsigned long flags;
+
+	if (irq >= NR_IRQS) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+	for (p = irq - FIRST_IRQ + irq_action; (action = *p) != NULL; p = &action->next) {
+		if (action->dev_id != dev_id)
+			continue;
+
+		/* Found it - now free it */
+		local_save_flags(flags);
+		local_irq_disable();
+		*p = action->next;
+		if (!irq_action[irq - FIRST_IRQ]) {
+			mask_irq(irq);
+			arch_free_irq(irq);
+		}
+		local_irq_restore(flags);
+		kfree(action);
+		return;
+	}
+	printk("Trying to free free IRQ%d\n",irq);
+}
+
+EXPORT_SYMBOL(free_irq);
+
+void weird_irq(void)
+{
+	local_irq_disable();
+	printk("weird irq\n");
+	while(1);
+}
+
+#if defined(CONFIG_PROC_FS) && defined(CONFIG_SYSCTL)
+/* Used by other archs to show/control IRQ steering during SMP */
+void __init
+init_irq_proc(void)
+{
+}
+#endif
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
new file mode 100644
index 0000000..f1d3e78
--- /dev/null
+++ b/arch/cris/kernel/module.c
@@ -0,0 +1,121 @@
+/*  Kernel module help for i386.
+    Copyright (C) 2001 Rusty Russell.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+#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_offset
+			+ 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);
+
+                /* We add the value into the location given */
+                *location += sym->st_value;
+	}
+	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 *rela = (void *)sechdrs[relsec].sh_addr;
+
+	DEBUGP ("Applying relocate section %u to %u\n", relsec,
+		sechdrs[relsec].sh_info);
+
+	for (i = 0; i < sechdrs[relsec].sh_size / sizeof (*rela); i++) {
+		/* This is where to make the change */
+		uint32_t *loc
+			= ((void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+			   + rela[i].r_offset);
+		/* This is the symbol it is referring to.  Note that all
+		   undefined symbols have been resolved.  */
+		Elf32_Sym *sym
+			= ((Elf32_Sym *)sechdrs[symindex].sh_addr
+			   + ELF32_R_SYM (rela[i].r_info));
+		*loc = sym->st_value + rela[i].r_addend;
+	}
+
+	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/cris/kernel/process.c b/arch/cris/kernel/process.c
new file mode 100644
index 0000000..9f7cad7
--- /dev/null
+++ b/arch/cris/kernel/process.c
@@ -0,0 +1,280 @@
+/* $Id: process.c,v 1.17 2004/04/05 13:53:48 starvik Exp $
+ * 
+ *  linux/arch/cris/kernel/process.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Copyright (C) 2000-2002  Axis Communications AB
+ *
+ *  Authors:   Bjorn Wesen (bjornw@axis.com)
+ *
+ *  $Log: process.c,v $
+ *  Revision 1.17  2004/04/05 13:53:48  starvik
+ *  Merge of Linux 2.6.5
+ *
+ *  Revision 1.16  2003/10/27 08:04:33  starvik
+ *  Merge of Linux 2.6.0-test9
+ *
+ *  Revision 1.15  2003/09/11 07:29:52  starvik
+ *  Merge of Linux 2.6.0-test5
+ *
+ *  Revision 1.14  2003/06/10 10:21:12  johana
+ *  Moved thread_saved_pc() from arch/cris/kernel/process.c to
+ *  subarch specific process.c. arch-v32 has an erp, no irp.
+ *
+ *  Revision 1.13  2003/04/09 05:20:47  starvik
+ *  Merge of Linux 2.5.67
+ *
+ *  Revision 1.12  2002/12/11 15:41:11  starvik
+ *  Extracted v10 (ETRAX 100LX) specific stuff to arch/cris/arch-v10/kernel
+ *
+ *  Revision 1.11  2002/12/10 09:00:10  starvik
+ *  Merge of Linux 2.5.51
+ *
+ *  Revision 1.10  2002/11/27 08:42:34  starvik
+ *  Argument to user_regs() is thread_info*
+ *
+ *  Revision 1.9  2002/11/26 09:44:21  starvik
+ *  New threads exits through ret_from_fork (necessary for preemptive scheduling)
+ *
+ *  Revision 1.8  2002/11/19 14:35:24  starvik
+ *  Changes from linux 2.4
+ *  Changed struct initializer syntax to the currently prefered notation
+ *
+ *  Revision 1.7  2002/11/18 07:39:42  starvik
+ *  thread_saved_pc moved here from processor.h
+ *
+ *  Revision 1.6  2002/11/14 06:51:27  starvik
+ *  Made cpu_idle more similar with other archs
+ *  init_task_union -> init_thread_union
+ *  Updated for new interrupt macros
+ *  sys_clone and do_fork have a new argument, user_tid
+ *
+ *  Revision 1.5  2002/11/05 06:45:11  starvik
+ *  Merge of Linux 2.5.45
+ *
+ *  Revision 1.4  2002/02/05 15:37:44  bjornw
+ *  Need init_task.h
+ *
+ *  Revision 1.3  2002/01/21 15:22:49  bjornw
+ *  current->counter is gone
+ *
+ *  Revision 1.22  2001/11/13 09:40:43  orjanf
+ *  Added dump_fpu (needed for core dumps).
+ *
+ *  Revision 1.21  2001/11/12 18:26:21  pkj
+ *  Fixed compiler warnings.
+ *
+ *  Revision 1.20  2001/10/03 08:21:39  jonashg
+ *  cause_of_death does not exist if CONFIG_SVINTO_SIM is defined.
+ *
+ *  Revision 1.19  2001/09/26 11:52:54  bjornw
+ *  INIT_MMAP is gone in 2.4.10
+ *
+ *  Revision 1.18  2001/08/21 21:43:51  hp
+ *  Move last watchdog fix inside #ifdef CONFIG_ETRAX_WATCHDOG
+ *
+ *  Revision 1.17  2001/08/21 13:48:01  jonashg
+ *  Added fix by HP to avoid oops when doing a hard_reset_now.
+ *
+ *  Revision 1.16  2001/06/21 02:00:40  hp
+ *  	* entry.S: Include asm/unistd.h.
+ *  	(_sys_call_table): Use section .rodata, not .data.
+ *  	(_kernel_thread): Move from...
+ *  	* process.c: ... here.
+ *  	* entryoffsets.c (VAL): Break out from...
+ *  	(OF): Use VAL.
+ *  	(LCLONE_VM): New asmified value from CLONE_VM.
+ *
+ *  Revision 1.15  2001/06/20 16:31:57  hp
+ *  Add comments to describe empty functions according to review.
+ *
+ *  Revision 1.14  2001/05/29 11:27:59  markusl
+ *  Fixed so that hard_reset_now will do reset even if watchdog wasn't enabled
+ *
+ *  Revision 1.13  2001/03/20 19:44:06  bjornw
+ *  Use the 7th syscall argument for regs instead of current_regs
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <asm/atomic.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/fs_struct.h>
+#include <linux/init_task.h>
+#include <linux/sched.h>
+#include <linux/fs.h>
+#include <linux/user.h>
+#include <linux/elfcore.h>
+#include <linux/mqueue.h>
+
+//#define DEBUG
+
+/*
+ * Initial task structure. Make this a per-architecture thing,
+ * because different architectures tend to have different
+ * alignment requirements and potentially different initial
+ * setup.
+ */
+
+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 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) };
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+
+EXPORT_SYMBOL(init_task);
+
+/*
+ * The hlt_counter, disable_hlt and enable_hlt is just here as a hook if
+ * there would ever be a halt sequence (for power save when idle) with
+ * some largish delay when halting or resuming *and* a driver that can't
+ * afford that delay.  The hlt_counter would then be checked before
+ * executing the halt sequence, and the driver marks the unhaltable
+ * region by enable_hlt/disable_hlt.
+ */
+
+static int hlt_counter=0;
+
+void disable_hlt(void)
+{
+	hlt_counter++;
+}
+
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+	hlt_counter--;
+}
+
+EXPORT_SYMBOL(enable_hlt);
+ 
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+
+extern void default_idle(void);
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle (void)
+{
+	/* endless idle loop with no priority at all */
+	while (1) {
+		while (!need_resched()) {
+			void (*idle)(void) = pm_idle;
+
+			if (!idle)
+				idle = default_idle;
+
+			idle();
+		}
+		schedule();
+	}
+
+}
+
+void hard_reset_now (void);
+
+void machine_restart(void)
+{
+	hard_reset_now();
+}
+
+EXPORT_SYMBOL(machine_restart);
+
+/*
+ * Similar to machine_power_off, but don't shut off power.  Add code
+ * here to freeze the system for e.g. post-mortem debug purpose when
+ * possible.  This halt has nothing to do with the idle halt.
+ */
+
+void machine_halt(void)
+{
+}
+
+EXPORT_SYMBOL(machine_halt);
+
+/* If or when software power-off is implemented, add code here.  */
+
+void machine_power_off(void)
+{
+}
+
+EXPORT_SYMBOL(machine_power_off);
+
+/*
+ * When a process does an "exec", machine state like FPU and debug
+ * registers need to be reset.  This is a hook function for that.
+ * Currently we don't have any such state to reset, so this is empty.
+ */
+
+void flush_thread(void)
+{
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+#if 0
+	int i;
+
+	/* changed the size calculations - should hopefully work better. lbt */
+	dump->magic = CMAGIC;
+	dump->start_code = 0;
+	dump->start_stack = regs->esp & ~(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;
+	for (i = 0; i < 8; i++)
+		dump->u_debugreg[i] = current->debugreg[i];  
+
+	if (dump->start_stack < TASK_SIZE)
+		dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
+
+	dump->regs = *regs;
+
+	dump->u_fpvalid = dump_fpu (regs, &dump->i387);
+#endif 
+}
+
+/* Fill in the fpu structure for a core dump. */
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
+{
+        return 0;
+}
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
new file mode 100644
index 0000000..e85a2fdd
--- /dev/null
+++ b/arch/cris/kernel/ptrace.c
@@ -0,0 +1,119 @@
+/*
+ *  linux/arch/cris/kernel/ptrace.c
+ *
+ * Parts taken from the m68k port.
+ * 
+ * Copyright (c) 2000, 2001, 2002 Axis Communications AB
+ *
+ * Authors:   Bjorn Wesen
+ *
+ * $Log: ptrace.c,v $
+ * Revision 1.9  2003/07/04 12:56:11  tobiasa
+ * Moved arch-specific code to arch-specific files.
+ *
+ * Revision 1.8  2003/04/09 05:20:47  starvik
+ * Merge of Linux 2.5.67
+ *
+ * Revision 1.7  2002/11/27 08:42:34  starvik
+ * Argument to user_regs() is thread_info*
+ *
+ * Revision 1.6  2002/11/20 11:56:11  starvik
+ * Merge of Linux 2.5.48
+ *
+ * Revision 1.5  2002/11/18 07:41:19  starvik
+ * Removed warning
+ *
+ * Revision 1.4  2002/11/11 12:47:28  starvik
+ * SYSCALL_TRACE has been moved to thread flags
+ *
+ * Revision 1.3  2002/02/05 15:37:18  bjornw
+ * * Add do_notify_resume (replaces do_signal in the callchain)
+ * * syscall_trace is now do_syscall_trace
+ * * current->ptrace flag PT_TRACESYS -> PT_SYSCALLTRACE
+ * * Keep track of the current->work.syscall_trace counter
+ *
+ * Revision 1.2  2001/12/18 13:35:20  bjornw
+ * Applied the 2.4.13->2.4.16 CRIS patch to 2.5.1 (is a copy of 2.4.15).
+ *
+ * Revision 1.8  2001/11/12 18:26:21  pkj
+ * Fixed compiler warnings.
+ *
+ * Revision 1.7  2001/09/26 11:53:49  bjornw
+ * PTRACE_DETACH works more simple in 2.4.10
+ *
+ * Revision 1.6  2001/07/25 16:08:47  bjornw
+ * PTRACE_ATTACH bulk moved into arch-independent code in 2.4.7
+ *
+ * Revision 1.5  2001/03/26 14:24:28  orjanf
+ * * Changed loop condition.
+ * * Added comment documenting non-standard ptrace behaviour.
+ *
+ * Revision 1.4  2001/03/20 19:44:41  bjornw
+ * Use the user_regs macro instead of thread.esp0
+ *
+ * Revision 1.3  2000/12/18 23:45:25  bjornw
+ * Linux/CRIS first version
+ *
+ *
+ */
+
+#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 <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+/*
+ * Get contents of register REGNO in task TASK.
+ */
+inline long get_reg(struct task_struct *task, unsigned int regno)
+{
+	/* USP is a special case, it's not in the pt_regs struct but
+	 * in the tasks thread struct
+	 */
+
+	if (regno == PT_USP)
+		return task->thread.usp;
+	else if (regno < PT_MAX)
+		return ((unsigned long *)user_regs(task->thread_info))[regno];
+	else
+		return 0;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+inline int put_reg(struct task_struct *task, unsigned int regno,
+			  unsigned long data)
+{
+	if (regno == PT_USP)
+		task->thread.usp = data;
+	else if (regno < PT_MAX)
+		((unsigned long *)user_regs(task->thread_info))[regno] = data;
+	else
+		return -1;
+	return 0;
+}
+
+/* notification of userspace execution resumption
+ * - triggered by current->work.notify_resume
+ */
+extern int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs);
+
+
+void do_notify_resume(int canrestart, sigset_t *oldset, struct pt_regs *regs, 
+		      __u32 thread_info_flags  )
+{
+	/* deal with pending signal delivery */
+	if (thread_info_flags & _TIF_SIGPENDING)
+		do_signal(canrestart,oldset,regs);
+}
diff --git a/arch/cris/kernel/semaphore.c b/arch/cris/kernel/semaphore.c
new file mode 100644
index 0000000..b884263
--- /dev/null
+++ b/arch/cris/kernel/semaphore.c
@@ -0,0 +1,130 @@
+/*
+ *  Generic semaphore code. Buyer beware. Do your own
+ * specific changes in <asm/semaphore-helper.h>
+ */
+
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <asm/semaphore-helper.h>
+
+/*
+ * 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_VAR				\
+	struct task_struct *tsk = current;	\
+	wait_queue_t wait;			\
+	init_waitqueue_entry(&wait, tsk);
+
+#define DOWN_HEAD(task_state)						\
+									\
+									\
+	tsk->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)			\
+		tsk->state = (task_state);	\
+	}					\
+	tsk->state = TASK_RUNNING;		\
+	remove_wait_queue(&sem->wait, &wait);
+
+void __sched __down(struct semaphore * sem)
+{
+	DOWN_VAR
+	DOWN_HEAD(TASK_UNINTERRUPTIBLE)
+	if (waking_non_zero(sem))
+		break;
+	schedule();
+	DOWN_TAIL(TASK_UNINTERRUPTIBLE)
+}
+
+int __sched __down_interruptible(struct semaphore * sem)
+{
+	int ret = 0;
+	DOWN_VAR
+	DOWN_HEAD(TASK_INTERRUPTIBLE)
+
+	ret = waking_non_zero_interruptible(sem, tsk);
+	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/cris/kernel/setup.c b/arch/cris/kernel/setup.c
new file mode 100644
index 0000000..6ec2671
--- /dev/null
+++ b/arch/cris/kernel/setup.c
@@ -0,0 +1,193 @@
+/*
+ *
+ *  linux/arch/cris/kernel/setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Copyright (c) 2001  Axis Communications AB
+ */
+
+/*
+ * This file handles the architecture-dependent parts of initialization
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <asm/pgtable.h>
+#include <linux/seq_file.h>
+#include <linux/tty.h>
+
+#include <asm/setup.h>
+
+/*
+ * Setup options
+ */
+struct drive_info_struct { char dummy[32]; } drive_info;
+struct screen_info screen_info;
+
+extern int root_mountflags;
+extern char _etext, _edata, _end;
+
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+
+extern const unsigned long text_start, edata; /* set by the linker script */
+extern unsigned long dram_start, dram_end;
+
+extern unsigned long romfs_start, romfs_length, romfs_in_flash; /* from head.S */
+
+extern void show_etrax_copyright(void);		/* arch-vX/kernel/setup.c */
+
+/* This mainly sets up the memory area, and can be really confusing.
+ *
+ * The physical DRAM is virtually mapped into dram_start to dram_end
+ * (usually c0000000 to c0000000 + DRAM size). The physical address is
+ * given by the macro __pa().
+ *
+ * In this DRAM, the kernel code and data is loaded, in the beginning.
+ * It really starts at c0004000 to make room for some special pages - 
+ * the start address is text_start. The kernel data ends at _end. After
+ * this the ROM filesystem is appended (if there is any).
+ * 
+ * Between this address and dram_end, we have RAM pages usable to the
+ * boot code and the system.
+ *
+ */
+
+void __init 
+setup_arch(char **cmdline_p)
+{
+	extern void init_etrax_debug(void);
+	unsigned long bootmap_size;
+	unsigned long start_pfn, max_pfn;
+	unsigned long memory_start;
+
+ 	/* register an initial console printing routine for printk's */
+
+	init_etrax_debug();
+
+	/* we should really poll for DRAM size! */
+
+	high_memory = &dram_end;
+
+	if(romfs_in_flash || !romfs_length) {
+		/* if we have the romfs in flash, or if there is no rom filesystem,
+		 * our free area starts directly after the BSS
+		 */
+		memory_start = (unsigned long) &_end;
+	} else {
+		/* otherwise the free area starts after the ROM filesystem */
+		printk("ROM fs in RAM, size %lu bytes\n", romfs_length);
+		memory_start = romfs_start + romfs_length;
+	}
+
+	/* process 1's initial memory region is the kernel code/data */
+
+	init_mm.start_code = (unsigned long) &text_start;
+	init_mm.end_code =   (unsigned long) &_etext;
+	init_mm.end_data =   (unsigned long) &_edata;
+	init_mm.brk =        (unsigned long) &_end;
+
+#define PFN_UP(x)       (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x)     ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x)     ((x) << PAGE_SHIFT)
+
+	/* min_low_pfn points to the start of DRAM, start_pfn points
+	 * to the first DRAM pages after the kernel, and max_low_pfn
+	 * to the end of DRAM.
+	 */
+
+        /*
+         * partially used pages are not usable - thus
+         * we are rounding upwards:
+         */
+
+        start_pfn = PFN_UP(memory_start);  /* usually c0000000 + kernel + romfs */
+	max_pfn =   PFN_DOWN((unsigned long)high_memory); /* usually c0000000 + dram size */
+
+        /*
+         * Initialize the boot-time allocator (start, end)
+	 *
+	 * We give it access to all our DRAM, but we could as well just have
+	 * given it a small slice. No point in doing that though, unless we
+	 * have non-contiguous memory and want the boot-stuff to be in, say,
+	 * the smallest area.
+	 *
+	 * It will put a bitmap of the allocated pages in the beginning
+	 * of the range we give it, but it won't mark the bitmaps pages
+	 * as reserved. We have to do that ourselves below.
+	 *
+	 * We need to use init_bootmem_node instead of init_bootmem
+	 * because our map starts at a quite high address (min_low_pfn).
+         */
+
+	max_low_pfn = max_pfn;
+	min_low_pfn = PAGE_OFFSET >> PAGE_SHIFT;
+
+	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
+					 min_low_pfn, 
+					 max_low_pfn);
+
+	/* And free all memory not belonging to the kernel (addr, size) */
+
+	free_bootmem(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn - start_pfn));
+
+        /*
+         * Reserve the bootmem bitmap itself as well. We do this in two
+         * steps (first step was init_bootmem()) because this catches
+         * the (very unlikely) case of us accidentally initializing the
+         * bootmem allocator with an invalid RAM area.
+	 *
+	 * Arguments are start, size
+         */
+
+        reserve_bootmem(PFN_PHYS(start_pfn), bootmap_size);
+
+	/* paging_init() sets up the MMU and marks all pages as reserved */
+
+	paging_init();
+
+	/* We don't use a command line yet, so just re-initialize it without
+	   saving anything that might be there.  */
+
+	*cmdline_p = command_line;
+
+#ifdef CONFIG_ETRAX_CMDLINE
+	strlcpy(command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE);
+	command_line[COMMAND_LINE_SIZE - 1] = '\0';
+
+	/* Save command line for future references. */
+	memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
+	saved_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+#endif
+
+	/* give credit for the CRIS port */
+	show_etrax_copyright();
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	/* We only got one CPU... */
+	return *pos < 1 ? (void *)1 : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return NULL;
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+extern int show_cpuinfo(struct seq_file *m, void *v);
+
+struct seq_operations cpuinfo_op = {
+	.start = c_start,
+	.next  = c_next,
+	.stop  = c_stop,
+	.show  = show_cpuinfo,
+};
+
+
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
new file mode 100644
index 0000000..0aa0e0e
--- /dev/null
+++ b/arch/cris/kernel/sys_cris.c
@@ -0,0 +1,174 @@
+/* $Id: sys_cris.c,v 1.6 2004/03/11 11:38:40 starvik Exp $
+ *
+ * linux/arch/cris/kernel/sys_cris.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on some platforms.
+ * Since we don't have to do any backwards compatibility, our
+ * versions are done in the most "normal" way possible.
+ *
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/syscalls.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/mman.h>
+#include <linux/file.h>
+
+#include <asm/uaccess.h>
+#include <asm/ipc.h>
+#include <asm/segment.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 __user * fildes)
+{
+        int fd[2];
+        int error;
+
+        lock_kernel();
+        error = do_pipe(fd);
+        unlock_kernel();
+        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 unsigned long old_mmap(unsigned long __user *args)
+{        
+	unsigned long buffer[6];
+	int err = -EFAULT;
+
+	if (copy_from_user(&buffer, args, sizeof(buffer)))
+		goto out;
+
+	err = -EINVAL;
+	if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
+		goto out;
+
+	err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
+                       buffer[4], buffer[5] >> PAGE_SHIFT);
+out:
+	return err;
+}
+
+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);
+}
+
+/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly. (same as arch/i386)
+ */
+
+asmlinkage int sys_ipc (uint call, int first, int second,
+			int third, void __user *ptr, long fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr, second,
+					(const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget (first, second, third);
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void * __user *) ptr))
+			return -EFAULT;
+		return sys_semctl (first, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd (first, (struct msgbuf __user *) 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 __user *) ptr, 
+					   sizeof (tmp)))
+				return -EFAULT;
+			return sys_msgrcv (first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv (first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget ((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl (first, second, (struct msqid_ds __user *) ptr);
+
+	case SHMAT: {
+                ulong raddr;
+                ret = do_shmat (first, (char __user *) ptr, second, &raddr);
+                if (ret)
+                        return ret;
+                return put_user (raddr, (ulong __user *) third);
+        }
+	case SHMDT: 
+		return sys_shmdt ((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget (first, second, third);
+	case SHMCTL:
+		return sys_shmctl (first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
new file mode 100644
index 0000000..6c28b0e
--- /dev/null
+++ b/arch/cris/kernel/time.c
@@ -0,0 +1,232 @@
+/* $Id: time.c,v 1.14 2004/06/01 05:38:11 starvik Exp $
+ *
+ *  linux/arch/cris/kernel/time.c
+ *
+ *  Copyright (C) 1991, 1992, 1995  Linus Torvalds
+ *  Copyright (C) 1999, 2000, 2001 Axis Communications AB
+ *
+ * 1994-07-02    Alan Modra
+ *	fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ * 1995-03-26    Markus Kuhn
+ *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
+ *      precision CMOS clock update
+ * 1996-05-03    Ingo Molnar
+ *      fixed time warps in do_[slow|fast]_gettimeoffset()
+ * 1997-09-10	Updated NTP code according to technical memorandum Jan '96
+ *		"A Kernel Model for Precision Timekeeping" by Dave Mills
+ *
+ * Linux/CRIS specific code:
+ *
+ * Authors:    Bjorn Wesen
+ *             Johan Adolfsson  
+ *
+ */
+
+#include <asm/rtc.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/jiffies.h>
+#include <linux/bcd.h>
+#include <linux/timex.h>
+#include <linux/init.h>
+
+u64 jiffies_64 = INITIAL_JIFFIES;
+
+EXPORT_SYMBOL(jiffies_64);
+
+int have_rtc;  /* used to remember if we have an RTC or not */;
+
+#define TICK_SIZE tick
+
+extern unsigned long wall_jiffies;
+extern unsigned long loops_per_jiffy; /* init/main.c */
+unsigned long loops_per_usec;
+
+extern unsigned long do_slow_gettimeoffset(void);
+static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+/*
+ * This version of gettimeofday has near microsecond resolution.
+ *
+ * Note: Division is quite slow on CRIS and do_gettimeofday is called
+ *       rather often. Maybe we should do some kind of approximation here
+ *       (a naive approximation would be to divide by 1024).
+ */
+void do_gettimeofday(struct timeval *tv)
+{
+	unsigned long flags;
+	signed long usec, sec;
+	local_irq_save(flags);
+	local_irq_disable();
+	usec = do_gettimeoffset();
+	{
+		unsigned long lost = jiffies - wall_jiffies;
+		if (lost)
+			usec += lost * (1000000 / HZ);
+	}
+
+        /*
+	 * If time_adjust is negative then NTP is slowing the clock
+	 * so make sure not to go into next possible interval.
+	 * Better to lose some accuracy than have time go backwards..
+	 */
+	if (unlikely(time_adjust < 0) && usec > tickadj)
+		usec = tickadj;
+
+	sec = xtime.tv_sec;
+	usec += xtime.tv_nsec / 1000;
+	local_irq_restore(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 "xtime" correctly. However, the
+	 * value in this location is the value at the most recent update of
+	 * wall time.  Discover what correction gettimeofday() would have
+	 * made, and then undo it!
+	 */
+	nsec -= do_gettimeoffset() * NSEC_PER_USEC;
+	nsec -= (jiffies - wall_jiffies) * TICK_NSEC;
+
+	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;
+}
+
+EXPORT_SYMBOL(do_settimeofday);
+
+
+/*
+ * BUG: This routine does not handle hour overflow properly; it just
+ *      sets the minutes. Usually you'll only notice that after reboot!
+ */
+
+int set_rtc_mmss(unsigned long nowtime)
+{
+	int retval = 0;
+	int real_seconds, real_minutes, cmos_minutes;
+
+	printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime);
+
+	if(!have_rtc)
+		return 0;
+
+	cmos_minutes = CMOS_READ(RTC_MINUTES);
+	BCD_TO_BIN(cmos_minutes);
+
+	/*
+	 * since we're only adjusting minutes and seconds,
+	 * don't interfere with hour overflow. This avoids
+	 * messing with unknown time zones but requires your
+	 * RTC not to be off by more than 15 minutes
+	 */
+	real_seconds = nowtime % 60;
+	real_minutes = nowtime / 60;
+	if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+		real_minutes += 30;		/* correct for half hour time zone */
+	real_minutes %= 60;
+
+	if (abs(real_minutes - cmos_minutes) < 30) {
+		BIN_TO_BCD(real_seconds);
+		BIN_TO_BCD(real_minutes);
+		CMOS_WRITE(real_seconds,RTC_SECONDS);
+		CMOS_WRITE(real_minutes,RTC_MINUTES);
+	} else {
+		printk(KERN_WARNING
+		       "set_rtc_mmss: can't update from %d to %d\n",
+		       cmos_minutes, real_minutes);
+		retval = -1;
+	}
+
+	return retval;
+}
+
+/* grab the time from the RTC chip */
+
+unsigned long
+get_cmos_time(void)
+{
+	unsigned int year, mon, day, hour, min, sec;
+
+	sec = CMOS_READ(RTC_SECONDS);
+	min = CMOS_READ(RTC_MINUTES);
+	hour = CMOS_READ(RTC_HOURS);
+	day = CMOS_READ(RTC_DAY_OF_MONTH);
+	mon = CMOS_READ(RTC_MONTH);
+	year = CMOS_READ(RTC_YEAR);
+
+	printk(KERN_DEBUG
+	       "rtc: sec 0x%x min 0x%x hour 0x%x day 0x%x mon 0x%x year 0x%x\n",
+	       sec, min, hour, day, mon, year);
+
+	BCD_TO_BIN(sec);
+	BCD_TO_BIN(min);
+	BCD_TO_BIN(hour);
+	BCD_TO_BIN(day);
+	BCD_TO_BIN(mon);
+	BCD_TO_BIN(year);
+
+	if ((year += 1900) < 1970)
+		year += 100;
+
+	return mktime(year, mon, day, hour, min, sec);
+}
+
+/* update xtime from the CMOS settings. used when /dev/rtc gets a SET_TIME.
+ * TODO: this doesn't reset the fancy NTP phase stuff as do_settimeofday does.
+ */
+
+void
+update_xtime_from_cmos(void)
+{
+	if(have_rtc) {
+		xtime.tv_sec = get_cmos_time();
+		xtime.tv_nsec = 0;
+	}
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ */
+unsigned long long sched_clock(void)
+{
+	return (unsigned long long)jiffies * (1000000000 / HZ);
+}
+
+static int
+__init init_udelay(void)
+{
+	loops_per_usec = (loops_per_jiffy * HZ) / 1000000;
+	return 0;
+}
+
+__initcall(init_udelay);
diff --git a/arch/cris/kernel/traps.c b/arch/cris/kernel/traps.c
new file mode 100644
index 0000000..d4dfa05
--- /dev/null
+++ b/arch/cris/kernel/traps.c
@@ -0,0 +1,144 @@
+/* $Id: traps.c,v 1.9 2004/05/11 12:28:26 starvik Exp $
+ *
+ *  linux/arch/cris/traps.c
+ *
+ *  Here we handle the break vectors not used by the system call 
+ *  mechanism, as well as some general stack/register dumping 
+ *  things.
+ * 
+ *  Copyright (C) 2000-2002 Axis Communications AB
+ *
+ *  Authors:   Bjorn Wesen
+ *  	       Hans-Peter Nilsson
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+
+static int kstack_depth_to_print = 24;
+
+void show_trace(unsigned long * stack)
+{
+	unsigned long addr, module_start, module_end;
+	extern char _stext, _etext;
+	int i;
+
+        printk("\nCall Trace: ");
+
+        i = 1;
+        module_start = VMALLOC_START;
+        module_end = VMALLOC_END;
+
+        while (((long) stack & (THREAD_SIZE-1)) != 0) {
+		if (__get_user (addr, stack)) {
+			/* This message matches "failing address" marked
+			   s390 in ksymoops, so lines containing it will
+			   not be filtered out by ksymoops.  */
+			printk ("Failing address 0x%lx\n", (unsigned long)stack);
+			break;
+		}
+		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) &_stext) &&
+                     (addr <= (unsigned long) &_etext)) ||
+                    ((addr >= module_start) && (addr <= module_end))) {
+                        if (i && ((i % 8) == 0))
+                                printk("\n       ");
+                        printk("[<%08lx>] ", addr);
+                        i++;
+                }
+        }
+}
+
+/*
+ * These constants are for searching for possible module text
+ * segments. MODULE_RANGE is a guess of how much space is likely
+ * to be vmalloced.
+ */
+
+#define MODULE_RANGE (8*1024*1024)
+
+/*
+ * The output (format, strings and order) is adjusted to be usable with
+ * ksymoops-2.4.1 with some necessary CRIS-specific patches.  Please don't
+ * change it unless you're serious about adjusting ksymoops and syncing
+ * with the ksymoops maintainer.
+ */
+
+void 
+show_stack(struct task_struct *task, unsigned long *sp)
+{
+        unsigned long *stack, addr;
+        int i;
+
+	/*
+	 * debugging aid: "show_stack(NULL);" prints a
+	 * back trace.
+	 */
+
+        if(sp == NULL) {
+		if (task)
+			sp = (unsigned long*)task->thread.ksp;
+		else
+			sp = (unsigned long*)rdsp();
+	}
+
+        stack = sp;
+
+	printk("\nStack from %08lx:\n       ", (unsigned long)stack);
+        for(i = 0; i < kstack_depth_to_print; i++) {
+                if (((long) stack & (THREAD_SIZE-1)) == 0)
+                        break;
+                if (i && ((i % 8) == 0))
+                        printk("\n       ");
+		if (__get_user (addr, stack)) {
+			/* This message matches "failing address" marked
+			   s390 in ksymoops, so lines containing it will
+			   not be filtered out by ksymoops.  */
+			printk ("Failing address 0x%lx\n", (unsigned long)stack);
+			break;
+		}
+		stack++;
+		printk("%08lx ", addr);
+        }
+	show_trace(sp);
+}
+
+#if 0
+/* displays a short stack trace */
+
+int 
+show_stack()
+{
+	unsigned long *sp = (unsigned long *)rdusp();
+	int i;
+	printk("Stack dump [0x%08lx]:\n", (unsigned long)sp);
+	for(i = 0; i < 16; i++)
+		printk("sp + %d: 0x%08lx\n", i*4, sp[i]);
+	return 0;
+}
+#endif
+
+void dump_stack(void)
+{
+	show_stack(NULL, NULL);
+}
+
+EXPORT_SYMBOL(dump_stack);
+
+void __init 
+trap_init(void)
+{
+	/* Nothing needs to be done */
+}