summaryrefslogtreecommitdiffstats
path: root/arch/cris/kernel
diff options
context:
space:
mode:
authorAnton Arapov <anton@redhat.com>2012-04-16 10:05:28 +0200
committerAnton Arapov <anton@redhat.com>2012-04-16 10:05:28 +0200
commitb4b6116a13633898cf868f2f103c96a90c4c20f8 (patch)
tree93d1b7e2cfcdf473d8d4ff3ad141fa864f8491f6 /arch/cris/kernel
parentedd4be777c953e5faafc80d091d3084b4343f5d3 (diff)
downloadkernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.gz
kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.tar.xz
kernel-uprobes-b4b6116a13633898cf868f2f103c96a90c4c20f8.zip
fedora kernel: d9aad82f3319f3cfd1aebc01234254ef0c37ad84v3.3.2-1
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/cris/kernel')
-rw-r--r--arch/cris/kernel/Makefile16
-rw-r--r--arch/cris/kernel/asm-offsets.c63
-rw-r--r--arch/cris/kernel/crisksyms.c69
-rw-r--r--arch/cris/kernel/irq.c68
-rw-r--r--arch/cris/kernel/module.c84
-rw-r--r--arch/cris/kernel/process.c161
-rw-r--r--arch/cris/kernel/profile.c86
-rw-r--r--arch/cris/kernel/ptrace.c47
-rw-r--r--arch/cris/kernel/setup.c203
-rw-r--r--arch/cris/kernel/sys_cris.c35
-rw-r--r--arch/cris/kernel/time.c168
-rw-r--r--arch/cris/kernel/traps.c238
-rw-r--r--arch/cris/kernel/vmlinux.lds.S131
13 files changed, 1369 insertions, 0 deletions
diff --git a/arch/cris/kernel/Makefile b/arch/cris/kernel/Makefile
new file mode 100644
index 00000000000..b45640b3e60
--- /dev/null
+++ b/arch/cris/kernel/Makefile
@@ -0,0 +1,16 @@
+# $Id: Makefile,v 1.12 2004/10/19 13:07:43 starvik Exp $
+#
+# Makefile for the linux kernel.
+#
+
+CPPFLAGS_vmlinux.lds := -DDRAM_VIRTUAL_BASE=0x$(CONFIG_ETRAX_DRAM_VIRTUAL_BASE)
+extra-y := vmlinux.lds
+
+obj-y := process.o traps.o irq.o ptrace.o setup.o time.o sys_cris.o
+
+obj-$(CONFIG_MODULES) += crisksyms.o
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_SYSTEM_PROFILER) += profile.o
+
+clean:
+
diff --git a/arch/cris/kernel/asm-offsets.c b/arch/cris/kernel/asm-offsets.c
new file mode 100644
index 00000000000..dd7b8e98322
--- /dev/null
+++ b/arch/cris/kernel/asm-offsets.c
@@ -0,0 +1,63 @@
+#include <linux/sched.h>
+#include <asm/thread_info.h>
+
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed to extract
+ * and format the required data.
+ */
+
+#define DEFINE(sym, val) \
+ asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+#if !defined(CONFIG_ETRAX_ARCH_V10) && !defined(CONFIG_ETRAX_ARCH_V32)
+#error One of ARCH v10 and ARCH v32 must be true!
+#endif
+
+int main(void)
+{
+#define ENTRY(entry) DEFINE(PT_ ## entry, offsetof(struct pt_regs, entry))
+ ENTRY(orig_r10);
+ ENTRY(r13);
+ ENTRY(r12);
+ ENTRY(r11);
+ ENTRY(r10);
+ ENTRY(r9);
+#ifdef CONFIG_ETRAX_ARCH_V32
+ ENTRY(acr);
+ ENTRY(srs);
+#endif
+ ENTRY(mof);
+#ifdef CONFIG_ETRAX_ARCH_V10
+ ENTRY(dccr);
+#else
+ ENTRY(ccs);
+#endif
+ ENTRY(srp);
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(TI_ ## entry, offsetof(struct thread_info, entry))
+ ENTRY(task);
+ ENTRY(flags);
+ ENTRY(preempt_count);
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(THREAD_ ## entry, offsetof(struct thread_struct, entry))
+ ENTRY(ksp);
+ ENTRY(usp);
+#ifdef CONFIG_ETRAX_ARCH_V10
+ ENTRY(dccr);
+#else
+ ENTRY(ccs);
+#endif
+ BLANK();
+#undef ENTRY
+#define ENTRY(entry) DEFINE(TASK_ ## entry, offsetof(struct task_struct, entry))
+ ENTRY(pid);
+ BLANK();
+ DEFINE(LCLONE_VM, CLONE_VM);
+ DEFINE(LCLONE_UNTRACED, CLONE_UNTRACED);
+ return 0;
+}
diff --git a/arch/cris/kernel/crisksyms.c b/arch/cris/kernel/crisksyms.c
new file mode 100644
index 00000000000..7ac000f6a88
--- /dev/null
+++ b/arch/cris/kernel/crisksyms.c
@@ -0,0 +1,69 @@
+#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/pm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/tty.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 unsigned long get_cmos_time(void);
+extern void __Udiv(void);
+extern void __Umod(void);
+extern void __Div(void);
+extern void __Mod(void);
+extern void __ashldi3(void);
+extern void __ashrdi3(void);
+extern void __lshrdi3(void);
+extern void __negdi2(void);
+extern void iounmap(volatile void * __iomem);
+
+/* Platform dependent support */
+EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(get_cmos_time);
+EXPORT_SYMBOL(loops_per_usec);
+
+/* Math functions */
+EXPORT_SYMBOL(__Udiv);
+EXPORT_SYMBOL(__Umod);
+EXPORT_SYMBOL(__Div);
+EXPORT_SYMBOL(__Mod);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__negdi2);
+
+/* Memory functions */
+EXPORT_SYMBOL(__ioremap);
+EXPORT_SYMBOL(iounmap);
+
+/* Userspace access functions */
+EXPORT_SYMBOL(__copy_user_zeroing);
+EXPORT_SYMBOL(__copy_user);
+
+#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
+EXPORT_SYMBOL(csum_partial);
diff --git a/arch/cris/kernel/irq.c b/arch/cris/kernel/irq.c
new file mode 100644
index 00000000000..788eb224891
--- /dev/null
+++ b/arch/cris/kernel/irq.c
@@ -0,0 +1,68 @@
+/*
+ *
+ * linux/arch/cris/kernel/irq.c
+ *
+ * Copyright (c) 2000,2007 Axis Communications AB
+ *
+ * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQs 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.
+ *
+ */
+
+/*
+ * IRQs 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/module.h>
+#include <linux/ptrace.h>
+#include <linux/irq.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/random.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+
+#include <asm/io.h>
+
+/* called by the assembler IRQ entry functions defined in irq.h
+ * to dispatch the interrupts to registered handlers
+ * interrupts are disabled upon entry - depending on if the
+ * interrupt was registered with IRQF_DISABLED or not, interrupts
+ * are re-enabled or not.
+ */
+
+asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
+{
+ unsigned long sp;
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ irq_enter();
+ sp = rdsp();
+ if (unlikely((sp & (PAGE_SIZE - 1)) < (PAGE_SIZE/8))) {
+ printk("do_IRQ: stack overflow: %lX\n", sp);
+ show_stack(NULL, (unsigned long *)sp);
+ }
+ generic_handle_irq(irq);
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+
+void weird_irq(void)
+{
+ local_irq_disable();
+ printk("weird irq\n");
+ while(1);
+}
+
diff --git a/arch/cris/kernel/module.c b/arch/cris/kernel/module.c
new file mode 100644
index 00000000000..37400f5869e
--- /dev/null
+++ b/arch/cris/kernel/module.c
@@ -0,0 +1,84 @@
+/* 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>
+#include <linux/slab.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt , ...)
+#endif
+
+#ifdef CONFIG_ETRAX_KMALLOCED_MODULES
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return kmalloc(size, GFP_KERNEL);
+}
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ kfree(module_region);
+}
+#endif
+
+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 add 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));
+ switch (ELF32_R_TYPE(rela[i].r_info)) {
+ case R_CRIS_32:
+ *loc = sym->st_value + rela[i].r_addend;
+ break;
+ case R_CRIS_32_PCREL:
+ *loc = sym->st_value - (unsigned)loc + rela[i].r_addend - 4;
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown relocation: %u\n",
+ me->name, ELF32_R_TYPE(rela[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+
+ return 0;
+}
diff --git a/arch/cris/kernel/process.c b/arch/cris/kernel/process.c
new file mode 100644
index 00000000000..aa585e4e979
--- /dev/null
+++ b/arch/cris/kernel/process.c
@@ -0,0 +1,161 @@
+/*
+ * linux/arch/cris/kernel/process.c
+ *
+ * Copyright (C) 1995 Linus Torvalds
+ * Copyright (C) 2000-2002 Axis Communications AB
+ *
+ * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/atomic.h>
+#include <asm/pgtable.h>
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <linux/module.h>
+#include <linux/spinlock.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>
+#include <linux/reboot.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 signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+/*
+ * 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 __init_task_data =
+ { 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.
+ */
+
+int cris_hlt_counter=0;
+
+void disable_hlt(void)
+{
+ cris_hlt_counter++;
+}
+
+EXPORT_SYMBOL(disable_hlt);
+
+void enable_hlt(void)
+{
+ cris_hlt_counter--;
+}
+
+EXPORT_SYMBOL(enable_hlt);
+
+/*
+ * The following aren't currently used.
+ */
+void (*pm_idle)(void);
+
+extern void default_idle(void);
+
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+/*
+ * 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);
+ /*
+ * Mark this as an RCU critical section so that
+ * synchronize_kernel() in the unload path waits
+ * for our completion.
+ */
+ idle = pm_idle;
+ if (!idle)
+ idle = default_idle;
+ idle();
+ }
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+void hard_reset_now (void);
+
+void machine_restart(char *cmd)
+{
+ hard_reset_now();
+}
+
+/*
+ * 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)
+{
+}
+
+/* If or when software power-off is implemented, add code here. */
+
+void machine_power_off(void)
+{
+}
+
+/*
+ * 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 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/profile.c b/arch/cris/kernel/profile.c
new file mode 100644
index 00000000000..b82e08615d1
--- /dev/null
+++ b/arch/cris/kernel/profile.c
@@ -0,0 +1,86 @@
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/uaccess.h>
+
+#define SAMPLE_BUFFER_SIZE 8192
+
+static char *sample_buffer;
+static char *sample_buffer_pos;
+static int prof_running = 0;
+
+void cris_profile_sample(struct pt_regs *regs)
+{
+ if (!prof_running)
+ return;
+
+ if (user_mode(regs))
+ *(unsigned int*)sample_buffer_pos = current->pid;
+ else
+ *(unsigned int*)sample_buffer_pos = 0;
+
+ *(unsigned int *)(sample_buffer_pos + 4) = instruction_pointer(regs);
+ sample_buffer_pos += 8;
+
+ if (sample_buffer_pos == sample_buffer + SAMPLE_BUFFER_SIZE)
+ sample_buffer_pos = sample_buffer;
+}
+
+static ssize_t
+read_cris_profile(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ unsigned long p = *ppos;
+ ssize_t ret;
+
+ ret = simple_read_from_buffer(buf, count, ppos, sample_buffer,
+ SAMPLE_BUFFER_SIZE);
+ if (ret < 0)
+ return ret;
+
+ memset(sample_buffer + p, 0, ret);
+
+ return ret;
+}
+
+static ssize_t
+write_cris_profile(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ sample_buffer_pos = sample_buffer;
+ memset(sample_buffer, 0, SAMPLE_BUFFER_SIZE);
+ return count < SAMPLE_BUFFER_SIZE ? count : SAMPLE_BUFFER_SIZE;
+}
+
+static const struct file_operations cris_proc_profile_operations = {
+ .read = read_cris_profile,
+ .write = write_cris_profile,
+ .llseek = default_llseek,
+};
+
+static int __init init_cris_profile(void)
+{
+ struct proc_dir_entry *entry;
+
+ sample_buffer = kmalloc(SAMPLE_BUFFER_SIZE, GFP_KERNEL);
+ if (!sample_buffer) {
+ return -ENOMEM;
+ }
+
+ sample_buffer_pos = sample_buffer;
+
+ entry = proc_create("system_profile", S_IWUSR | S_IRUGO, NULL,
+ &cris_proc_profile_operations);
+ if (entry) {
+ entry->size = SAMPLE_BUFFER_SIZE;
+ }
+ prof_running = 1;
+
+ return 0;
+}
+__initcall(init_cris_profile);
+
diff --git a/arch/cris/kernel/ptrace.c b/arch/cris/kernel/ptrace.c
new file mode 100644
index 00000000000..48b0f391263
--- /dev/null
+++ b/arch/cris/kernel/ptrace.c
@@ -0,0 +1,47 @@
+/*
+ * linux/arch/cris/kernel/ptrace.c
+ *
+ * Parts taken from the m68k port.
+ *
+ * Copyright (c) 2000, 2001, 2002 Axis Communications AB
+ *
+ * Authors: Bjorn Wesen
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/tracehook.h>
+
+#include <asm/uaccess.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+
+
+/* notification of userspace execution resumption
+ * - triggered by current->work.notify_resume
+ */
+extern int do_signal(int canrestart, struct pt_regs *regs);
+
+
+void do_notify_resume(int canrestart, struct pt_regs *regs,
+ __u32 thread_info_flags)
+{
+ /* deal with pending signal delivery */
+ if (thread_info_flags & _TIF_SIGPENDING)
+ do_signal(canrestart,regs);
+
+ if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ if (current->replacement_session_keyring)
+ key_replace_session_keyring();
+ }
+}
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c
new file mode 100644
index 00000000000..b712f4934c4
--- /dev/null
+++ b/arch/cris/kernel/setup.c
@@ -0,0 +1,203 @@
+/*
+ *
+ * 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/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <asm/pgtable.h>
+#include <linux/seq_file.h>
+#include <linux/screen_info.h>
+#include <linux/utsname.h>
+#include <linux/pfn.h>
+#include <linux/cpu.h>
+#include <asm/setup.h>
+
+/*
+ * Setup options
+ */
+struct screen_info screen_info;
+
+extern int root_mountflags;
+extern char _etext, _edata, _end;
+
+char __initdata cris_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 */
+
+static struct cpu cpu_devices[NR_CPUS];
+
+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;
+
+ /* 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, BOOTMEM_DEFAULT);
+
+ /* paging_init() sets up the MMU and marks all pages as reserved */
+
+ paging_init();
+
+ *cmdline_p = cris_command_line;
+
+#ifdef CONFIG_ETRAX_CMDLINE
+ if (!strcmp(cris_command_line, "")) {
+ strlcpy(cris_command_line, CONFIG_ETRAX_CMDLINE, COMMAND_LINE_SIZE);
+ cris_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+ }
+#endif
+
+ /* Save command line for future references. */
+ memcpy(boot_command_line, cris_command_line, COMMAND_LINE_SIZE);
+ boot_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+
+ /* give credit for the CRIS port */
+ show_etrax_copyright();
+
+ /* Setup utsname */
+ strcpy(init_utsname()->machine, cris_machine_name);
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < nr_cpu_ids ? (void *)(int)(*pos + 1) : 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)
+{
+}
+
+extern int show_cpuinfo(struct seq_file *m, void *v);
+
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
+
+static int __init topology_init(void)
+{
+ int i;
+
+ for_each_possible_cpu(i) {
+ return register_cpu(&cpu_devices[i], i);
+ }
+
+ return 0;
+}
+
+subsys_initcall(topology_init);
+
diff --git a/arch/cris/kernel/sys_cris.c b/arch/cris/kernel/sys_cris.c
new file mode 100644
index 00000000000..7aa036ec78f
--- /dev/null
+++ b/arch/cris/kernel/sys_cris.c
@@ -0,0 +1,35 @@
+/* $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/fs.h>
+#include <linux/smp.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 <linux/ipc.h>
+
+#include <asm/uaccess.h>
+#include <asm/segment.h>
+
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+ /* bug(?): 8Kb pages here */
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+}
diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
new file mode 100644
index 00000000000..4e73092e85c
--- /dev/null
+++ b/arch/cris/kernel/time.c
@@ -0,0 +1,168 @@
+/*
+ * 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>
+#include <linux/profile.h>
+#include <linux/sched.h> /* just for sched_clock() - funny that */
+
+int have_rtc; /* used to remember if we have an RTC or not */;
+
+#define TICK_SIZE tick
+
+extern unsigned long loops_per_jiffy; /* init/main.c */
+unsigned long loops_per_usec;
+
+
+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
+extern unsigned long do_slow_gettimeoffset(void);
+static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
+
+u32 arch_gettimeoffset(void)
+{
+ return do_gettimeoffset() * 1000;
+}
+#endif
+
+/*
+ * 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);
+ cmos_minutes = bcd2bin(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) {
+ real_seconds = bin2bcd(real_seconds);
+ real_minutes = bin2bcd(real_minutes);
+ CMOS_WRITE(real_seconds,RTC_SECONDS);
+ CMOS_WRITE(real_minutes,RTC_MINUTES);
+ } else {
+ printk_once(KERN_NOTICE
+ "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;
+ if(!have_rtc)
+ return 0;
+
+ 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);
+
+ sec = bcd2bin(sec);
+ min = bcd2bin(min);
+ hour = bcd2bin(hour);
+ day = bcd2bin(day);
+ mon = bcd2bin(mon);
+ year = bcd2bin(year);
+
+ if ((year += 1900) < 1970)
+ year += 100;
+
+ return mktime(year, mon, day, hour, min, sec);
+}
+
+
+int update_persistent_clock(struct timespec now)
+{
+ return set_rtc_mmss(now.tv_sec);
+}
+
+void read_persistent_clock(struct timespec *ts)
+{
+ ts->tv_sec = get_cmos_time();
+ ts->tv_nsec = 0;
+}
+
+
+extern void cris_profile_sample(struct pt_regs* regs);
+
+void
+cris_do_profile(struct pt_regs* regs)
+{
+
+#ifdef CONFIG_SYSTEM_PROFILER
+ cris_profile_sample(regs);
+#endif
+
+#ifdef CONFIG_PROFILING
+ profile_tick(CPU_PROFILING);
+#endif
+}
+
+unsigned long long sched_clock(void)
+{
+ return (unsigned long long)jiffies * (NSEC_PER_SEC / HZ) +
+ get_ns_in_jiffie();
+}
+
+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 00000000000..8da53f34c7a
--- /dev/null
+++ b/arch/cris/kernel/traps.c
@@ -0,0 +1,238 @@
+/*
+ * 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-2007 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>
+
+extern void arch_enable_nmi(void);
+extern void stop_watchdog(void);
+extern void reset_watchdog(void);
+extern void show_registers(struct pt_regs *regs);
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+extern void handle_BUG(struct pt_regs *regs);
+#else
+#define handle_BUG(regs)
+#endif
+
+static int kstack_depth_to_print = 24;
+
+void (*nmi_handler)(struct pt_regs *);
+
+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(void)
+{
+ 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
+set_nmi_handler(void (*handler)(struct pt_regs *))
+{
+ nmi_handler = handler;
+ arch_enable_nmi();
+}
+
+#ifdef CONFIG_DEBUG_NMI_OOPS
+void
+oops_nmi_handler(struct pt_regs *regs)
+{
+ stop_watchdog();
+ oops_in_progress = 1;
+ printk("NMI!\n");
+ show_registers(regs);
+ oops_in_progress = 0;
+}
+
+static int __init
+oops_nmi_register(void)
+{
+ set_nmi_handler(oops_nmi_handler);
+ return 0;
+}
+
+__initcall(oops_nmi_register);
+
+#endif
+
+/*
+ * This gets called from entry.S when the watchdog has bitten. Show something
+ * similar to an Oops dump, and if the kernel is configured to be a nice
+ * doggy, then halt instead of reboot.
+ */
+void
+watchdog_bite_hook(struct pt_regs *regs)
+{
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+ local_irq_disable();
+ stop_watchdog();
+ show_registers(regs);
+
+ while (1)
+ ; /* Do nothing. */
+#else
+ show_registers(regs);
+#endif
+}
+
+/* This is normally the Oops function. */
+void
+die_if_kernel(const char *str, struct pt_regs *regs, long err)
+{
+ if (user_mode(regs))
+ return;
+
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+ /*
+ * This printout might take too long and could trigger
+ * the watchdog normally. If NICE_DOGGY is set, simply
+ * stop the watchdog during the printout.
+ */
+ stop_watchdog();
+#endif
+
+ handle_BUG(regs);
+
+ printk("%s: %04lx\n", str, err & 0xffff);
+
+ show_registers(regs);
+
+ oops_in_progress = 0;
+
+#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
+ reset_watchdog();
+#endif
+ do_exit(SIGSEGV);
+}
+
+void __init
+trap_init(void)
+{
+ /* Nothing needs to be done */
+}
diff --git a/arch/cris/kernel/vmlinux.lds.S b/arch/cris/kernel/vmlinux.lds.S
new file mode 100644
index 00000000000..a6990cb0f09
--- /dev/null
+++ b/arch/cris/kernel/vmlinux.lds.S
@@ -0,0 +1,131 @@
+/* ld script to make the Linux/CRIS kernel
+ * Authors: Bjorn Wesen (bjornw@axis.com)
+ *
+ * It is VERY DANGEROUS to fiddle around with the symbols in this
+ * script. It is for example quite vital that all generated sections
+ * that are used are actually named here, otherwise the linker will
+ * put them at the end, where the init stuff is which is FREED after
+ * the kernel has booted.
+ */
+
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
+
+#ifdef CONFIG_ETRAX_VMEM_SIZE
+#define __CONFIG_ETRAX_VMEM_SIZE CONFIG_ETRAX_VMEM_SIZE
+#else
+#define __CONFIG_ETRAX_VMEM_SIZE 0
+#endif
+
+
+jiffies = jiffies_64;
+SECTIONS
+{
+ . = DRAM_VIRTUAL_BASE;
+ dram_start = .;
+#ifdef CONFIG_ETRAX_ARCH_V10
+ ibr_start = .;
+#else
+ ebp_start = .;
+ /* The boot section is only necessary until the VCS top */
+ /* level testbench includes both flash and DRAM. */
+ .boot : { *(.boot) }
+#endif
+
+ /* see head.S and pages reserved at the start */
+ . = DRAM_VIRTUAL_BASE + 0x4000;
+
+ _text = .; /* Text and read-only data. */
+ text_start = .; /* Lots of aliases. */
+ _stext = .;
+ __stext = .;
+ .text : {
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ *(.fixup)
+ *(.text.__*)
+ }
+
+ _etext = . ; /* End of text section. */
+ __etext = .;
+
+ EXCEPTION_TABLE(4)
+
+ RODATA
+
+ . = ALIGN (4);
+ ___data_start = . ;
+ __Sdata = . ;
+ .data : { /* Data */
+ CACHELINE_ALIGNED_DATA(32)
+ READ_MOSTLY_DATA(32)
+ DATA_DATA
+ }
+ __edata = . ; /* End of data section. */
+ _edata = . ;
+
+ INIT_TASK_DATA_SECTION(PAGE_SIZE)
+
+ . = ALIGN(PAGE_SIZE); /* Init code and data. */
+ __init_begin = .;
+ INIT_TEXT_SECTION(PAGE_SIZE)
+ .init.data : { INIT_DATA }
+ .init.setup : { INIT_SETUP(16) }
+ .initcall.init : {
+ INIT_CALLS
+ }
+
+ .con_initcall.init : {
+ CON_INITCALL
+ }
+ SECURITY_INIT
+
+ /* .exit.text is discarded at runtime, not link time,
+ * to deal with references from __bug_table
+ */
+ .exit.text : {
+ EXIT_TEXT
+ }
+ .exit.data : {
+ EXIT_DATA
+ }
+
+#ifdef CONFIG_ETRAX_ARCH_V10
+#ifdef CONFIG_BLK_DEV_INITRD
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+#endif
+#endif
+ __vmlinux_end = .; /* Last address of the physical file. */
+#ifdef CONFIG_ETRAX_ARCH_V32
+ PERCPU_SECTION(32)
+
+ .init.ramfs : {
+ INIT_RAM_FS
+ }
+#endif
+
+ /*
+ * We fill to the next page, so we can discard all init
+ * pages without needing to consider what payload might be
+ * appended to the kernel image.
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ __init_end = .;
+
+ __data_end = . ; /* Move to _edata ? */
+ BSS_SECTION(1, 1, 1)
+
+ . = ALIGN (0x20);
+ _end = .;
+ __end = .;
+
+ dram_end = dram_start + (CONFIG_ETRAX_DRAM_SIZE - __CONFIG_ETRAX_VMEM_SIZE)*1024*1024;
+
+ DISCARDS
+}