]> rtime.felk.cvut.cz Git - mcf548x/linux.git/commitdiff
Bootcode
authorMartin <meloumar@cmp.felk.cvut.cz>
Fri, 29 Apr 2011 14:45:49 +0000 (16:45 +0200)
committerMartin <meloumar@cmp.felk.cvut.cz>
Fri, 29 Apr 2011 14:45:49 +0000 (16:45 +0200)
arch/m68k/coldfire/config.c [new file with mode: 0644]
arch/m68k/coldfire/entry.S [new file with mode: 0644]
arch/m68k/coldfire/head.S [new file with mode: 0644]
arch/m68k/include/asm/mcfdspi.h [new file with mode: 0644]
arch/m68k/include/asm/mcfsim.h

diff --git a/arch/m68k/coldfire/config.c b/arch/m68k/coldfire/config.c
new file mode 100644 (file)
index 0000000..a3fcb59
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ *  linux/arch/m68k/coldfire/config.c
+ *
+ *  Kurt Mahan kmahan@freescale.com
+ *  Matt Waddel Matt.Waddel@freescale.com
+ *  Copyright Freescale Semiconductor, Inc. 2007, 2008
+ *
+ *  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.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <asm/bootinfo.h>
+#include <asm/machdep.h>
+#include <asm/coldfire.h>
+//#include <asm/cfcache.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
+//#include <asm/cfmmu.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/movs.h>
+#include <asm/movs.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+
+#include <asm/mcfsim.h>
+
+#ifdef CONFIG_UBOOT
+
+#if defined(CONFIG_M5445X)
+#define UBOOT_EXTRA_CLOCKS
+#elif defined(CONFIG_M547X_8X)
+#define UBOOT_PCI
+#endif
+
+#endif
+
+#include <asm/bootinfo.h>
+
+#ifdef CONFIG_M5445X
+#include <asm/mcf5445x_intc.h>
+#include <asm/mcf5445x_sdramc.h>
+#include <asm/mcf5445x_fbcs.h>
+#include <asm/mcf5445x_dtim.h>
+#include <asm/mcf5445x_xbs.h>
+#endif
+
+#ifdef CONFIG_M547X_8X
+#include <asm/m5485gpt.h>
+#endif
+
+extern int get_irq_list(struct seq_file *p, void *v);
+extern char _text, _end;
+extern char _etext, _edata, __init_begin, __init_end;
+extern struct console mcfrs_console;
+extern char m68k_command_line[CL_SIZE];
+extern unsigned long availmem;
+
+static int irq_enable[NR_IRQS];
+unsigned long num_pages;
+
+/* ethernet mac addresses from uboot */
+#ifdef CONFIG_UBOOT
+unsigned char uboot_enet0[6];
+unsigned char uboot_enet1[6];
+#endif
+
+void coldfire_sort_memrec(void)
+{
+       int i, j;
+
+       /* Sort the m68k_memory records by address */
+       for (i = 0; i < m68k_num_memory; ++i) {
+               for (j = i + 1; j < m68k_num_memory; ++j) {
+                       if (m68k_memory[i].addr > m68k_memory[j].addr) {
+                               struct mem_info tmp;
+                               tmp = m68k_memory[i];
+                               m68k_memory[i] = m68k_memory[j];
+                               m68k_memory[j] = tmp;
+                       }
+               }
+       }
+       /* Trim off discontiguous bits */
+       for (i = 1; i < m68k_num_memory; ++i) {
+               if ((m68k_memory[i-1].addr + m68k_memory[i-1].size) !=
+                       m68k_memory[i].addr) {
+                       printk(KERN_DEBUG "m68k_parse_bootinfo: addr gap between \
+                               0x%lx & 0x%lx\n",
+                               m68k_memory[i-1].addr+m68k_memory[i-1].size,
+                               m68k_memory[i].addr);
+                       m68k_num_memory = i;
+                       break;
+               }
+       }
+}
+
+/*
+ * UBoot Handler
+ */
+ #ifdef CONFIG_UBOOT
+int __init uboot_commandline(char *bootargs)
+{
+       int len = 0, cmd_line_len;
+       static struct uboot_record uboot_info;
+       u32 offset = PAGE_OFFSET_RAW - PHYS_OFFSET;
+
+       extern unsigned long uboot_info_stk;
+
+       /* validate address */
+       if ((uboot_info_stk < PAGE_OFFSET_RAW) ||
+           (uboot_info_stk >= (PAGE_OFFSET_RAW + CONFIG_SDRAM_SIZE)))
+               return 0;
+
+       /* Add offset to get post-remapped kernel memory location */
+       uboot_info.bdi = (struct bd_info *)((*(u32 *)(uboot_info_stk)) + offset);
+       uboot_info.initrd_start = (*(u32 *)(uboot_info_stk+4)) + offset;
+       uboot_info.initrd_end = (*(u32 *)(uboot_info_stk+8)) + offset;
+       uboot_info.cmd_line_start = (*(u32 *)(uboot_info_stk+12)) + offset;
+       uboot_info.cmd_line_stop = (*(u32 *)(uboot_info_stk+16)) + offset;
+
+       /* copy over mac addresses */
+       memcpy(uboot_enet0, uboot_info.bdi->bi_enet0addr, 6);
+       memcpy(uboot_enet1, uboot_info.bdi->bi_enet1addr, 6);
+
+       /* copy command line */
+       cmd_line_len = uboot_info.cmd_line_stop - uboot_info.cmd_line_start;
+       if ((cmd_line_len > 0) && (cmd_line_len < CL_SIZE-1))
+               len = (int)strncpy(bootargs, (char *)uboot_info.cmd_line_start,\
+                                  cmd_line_len);
+
+       return len;
+}
+#endif
+
+/*
+ * This routine does things not done in the bootloader.
+ */
+
+// Default command line is required to be passed from defconfig.
+
+asmlinkage void __init cf_early_init(void)
+{
+       struct bi_record *record = (struct bi_record *) &_end;
+
+       extern char _end;
+
+#if defined(CONFIG_M5445X)
+       SET_VBR((void *)MCF_RAMBAR1);
+#elif defined(CONFIG_M547X_8X)
+       SET_VBR((void *)MCF_RAMBAR0);
+#endif
+
+       /* Mask all interrupts */
+#if defined(CONFIG_M5445X)
+       MCF_INTC0_IMRL = 0xFFFFFFFF;
+       MCF_INTC0_IMRH = 0xFFFFFFFF;
+       MCF_INTC1_IMRL = 0xFFFFFFFF;
+       MCF_INTC1_IMRH = 0xFFFFFFFF;
+#elif defined(CONFIG_M547X_8X)
+       MCF_IMRL = 0xFFFFFFFF;
+       MCF_IMRH = 0xFFFFFFFF;
+#endif
+
+#if defined(CONFIG_M5445X)
+#if defined(CONFIG_NOR_FLASH_BASE)
+       MCF_FBCS_CSAR(1) = CONFIG_NOR_FLASH_BASE;
+#else
+       MCF_FBCS_CSAR(1) = 0x00000000;
+#endif
+
+#if CONFIG_SDRAM_SIZE > (256*1024*1024)
+       /* Init optional SDRAM chip select */
+       MCF_SDRAMC_SDCS(1) = (256*1024*1024) | 0x1B;
+#endif
+#endif /* CONFIG_M5445X */
+
+#if defined(CONFIG_M5445X)
+       /* Setup SDRAM crossbar(XBS) priorities */
+       MCF_XBS_PRS2 = (MCF_XBS_PRS_M0(MCF_XBS_PRI_2) |
+                       MCF_XBS_PRS_M1(MCF_XBS_PRI_3) |
+                       MCF_XBS_PRS_M2(MCF_XBS_PRI_4) |
+                       MCF_XBS_PRS_M3(MCF_XBS_PRI_5) |
+                       MCF_XBS_PRS_M5(MCF_XBS_PRI_6) |
+                       MCF_XBS_PRS_M6(MCF_XBS_PRI_1) |
+                       MCF_XBS_PRS_M7(MCF_XBS_PRI_7));
+#endif
+
+       m68k_machtype = MACH_CFMMU;
+       m68k_fputype = FPU_CFV4E;
+       m68k_mmutype = MMU_CFV4E;
+       m68k_cputype = CPU_CFV4E;
+
+       m68k_num_memory = 0;
+       m68k_memory[m68k_num_memory].addr = CONFIG_SDRAM_BASE;
+       m68k_memory[m68k_num_memory++].size = CONFIG_SDRAM_SIZE;
+
+
+#ifdef CONFIG_UBOOT
+       if (!uboot_commandline(m68k_command_line))      
+               strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE-1);
+#else
+       //FIXME: some better way here
+       strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE-1);
+#endif
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+       /* add initrd image */
+       record = (struct bi_record *) ((void *)record + record->size);
+       record->tag = BI_RAMDISK;
+       record->size =  sizeof(record->tag) + sizeof(record->size)
+               + sizeof(record->data[0]) + sizeof(record->data[1]);
+#endif
+
+       /* Mark end of tags. */
+       record = (struct bi_record *) ((void *) record + record->size);
+       record->tag = 0;
+       record->data[0] = 0;
+       record->data[1] = 0;
+       record->size = sizeof(record->tag) + sizeof(record->size)
+               + sizeof(record->data[0]) + sizeof(record->data[1]);
+
+       /* Invalidate caches via CACR */
+       flush_bcache();
+       cacr_set(CACHE_DISABLE_MODE);
+
+       /* Turn on caches via CACR, enable EUSP */
+       cacr_set(CACHE_INITIAL_MODE);
+
+}
+
+#if defined(CONFIG_M5445X)
+void settimericr(unsigned int timer, unsigned int level)
+{
+       volatile unsigned char *icrp;
+       unsigned int icr;
+       unsigned char irq;
+
+       if (timer <= 2) {
+               switch (timer) {
+               case 2:  irq = 33; icr = MCFSIM_ICR_TIMER2; break;
+               default: irq = 32; icr = MCFSIM_ICR_TIMER1; break;
+               }
+
+               icrp = (volatile unsigned char *) (icr);
+               *icrp = level;
+               coldfire_enable_irq0(irq);
+       }
+}
+#endif
+
+/* Assembler routines */
+asmlinkage void buserr(void);
+asmlinkage void trap(void);
+asmlinkage void system_call(void);
+asmlinkage void inthandler(void);
+
+void __init coldfire_trap_init(void)
+{
+       int i = 0;
+       e_vector *vectors;
+
+#if defined(CONFIG_M5445X)
+       vectors = (e_vector *)MCF_RAMBAR1;
+#elif defined(CONFIG_M547X_8X)
+       vectors = (e_vector *)MCF_RAMBAR0;
+#endif
+       /*
+        * There is a common trap handler and common interrupt
+        * handler that handle almost every vector. We treat
+        * the system call and bus error special, they get their
+        * own first level handlers.
+        */
+       for (i = 3; (i <= 23); i++)
+               vectors[i] = trap;
+       for (i = 33; (i <= 63); i++)
+               vectors[i] = trap;
+       for (i = 24; (i <= 31); i++)
+               vectors[i] = inthandler;
+       for (i = 64; (i < 255); i++)
+               vectors[i] = inthandler;
+
+       vectors[255] = 0;
+       vectors[2] = buserr;
+       vectors[32] = system_call;
+}
+
+#if defined(CONFIG_M5445X)
+
+void coldfire_tick(void)
+{
+       /* Reset the ColdFire timer */
+       __raw_writeb(MCF_DTIM_DTER_CAP | MCF_DTIM_DTER_REF, MCF_DTIM0_DTER);
+}
+
+void __init coldfire_sched_init(irq_handler_t handler)
+{
+       unsigned int    mcf_timerlevel = 5;
+       unsigned int    mcf_timervector = 64+32;
+
+       __raw_writew(MCF_DTIM_DTMR_RST_RST, MCF_DTIM0_DTMR);
+       __raw_writel(((MCF_BUSCLK / 16) / HZ), MCF_DTIM0_DTRR);
+       __raw_writew(MCF_DTIM_DTMR_ORRI | MCF_DTIM_DTMR_CLK_DIV16 |
+                    MCF_DTIM_DTMR_FRR  | MCF_DTIM_DTMR_RST_EN, \
+                    MCF_DTIM0_DTMR);
+
+       request_irq(mcf_timervector, handler, IRQF_DISABLED, \
+                   "timer", (void *)MCF_DTIM0_DTMR);
+
+       settimericr(1, mcf_timerlevel);
+}
+
+int timerirqpending(int timer)
+{
+       unsigned int imr = 0;
+
+       switch (timer) {
+       case 1:  imr = 0x1; break;
+       case 2:  imr = 0x2; break;
+       default: break;
+       }
+
+       return (getiprh() & imr);
+}
+
+unsigned long coldfire_gettimeoffset(void)
+{
+       volatile unsigned long trr, tcn, offset;
+
+       tcn = __raw_readw(MCF_DTIM0_DTCN);
+       trr = __raw_readl(MCF_DTIM0_DTRR);
+       offset = (tcn * (1000000 / HZ)) / trr;
+
+       /* Check if we just wrapped the counters and maybe missed a tick */
+       if ((offset < (1000000 / HZ / 2)) && timerirqpending(1))
+               offset += 1000000 / HZ;
+       return offset;
+}
+
+#elif defined(CONFIG_M547X_8X)
+
+void coldfire_tick(void)
+{
+       /* Reset the ColdFire timer */
+       MCF_SSR(0) = MCF_SSR_ST;
+}
+
+void __init coldfire_sched_init(irq_handler_t handler)
+{
+       int irq = ISC_SLTn(0);
+
+       MCF_SCR(0) = 0;
+       MCF_ICR(irq) = ILP_SLT0;
+       request_irq(64 + irq, handler, IRQF_DISABLED, "ColdFire Timer 0", NULL);
+       MCF_SLTCNT(0) = MCF_BUSCLK / HZ;
+       MCF_SCR(0) |=  MCF_SCR_TEN | MCF_SCR_IEN | MCF_SCR_RUN;
+}
+
+unsigned long coldfire_gettimeoffset(void)
+{
+       volatile unsigned long trr, tcn, offset;
+       trr = MCF_SLTCNT(0);
+       tcn = MCF_SCNT(0);
+
+       offset = (trr - tcn) * ((1000000 >> 3) / HZ) / (trr >> 3);
+       if (MCF_SSR(0) & MCF_SSR_ST)
+               offset += 1000000 / HZ;
+
+       return offset;
+}
+
+#endif
+
+void coldfire_reboot(void)
+{
+#if defined(CONFIG_M5445X)
+       /* disable interrupts and do a software reset */
+       asm("movew #0x2700, %%sr\n\t"
+           "moveb #0x80, %%d0\n\t"
+           "moveb %%d0, 0xfc0a0000\n\t"
+           : : : "%d0");
+#elif defined(CONFIG_M547X_8X)
+       /* disable interrupts and enable the watchdog */
+       printk(KERN_INFO "Rebooting\n");
+       asm("movew #0x2700, %sr\n");
+       MCF_GPT_GMS0 = MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS(4);
+#endif
+}
+
+static void coldfire_get_model(char *model)
+{
+       sprintf(model, "Version 4 ColdFire");
+}
+
+static void __init
+coldfire_bootmem_alloc(unsigned long memory_start, unsigned long memory_end)
+{
+       unsigned long base_pfn;
+
+       /* compute total pages in system */
+       num_pages = PAGE_ALIGN(memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
+
+       /* align start/end to page boundries */
+       memory_start = PAGE_ALIGN(memory_start);
+       memory_end = memory_end & PAGE_MASK;
+
+       /* page numbers */
+       base_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT;
+       min_low_pfn = __pa(memory_start) >> PAGE_SHIFT;
+       max_low_pfn = __pa(memory_end) >> PAGE_SHIFT;
+
+       high_memory = (void *)memory_end;
+       availmem = memory_start;
+
+       /* setup bootmem data */
+       m68k_setup_node(0);
+       availmem += init_bootmem_node(NODE_DATA(0), min_low_pfn,
+               base_pfn, max_low_pfn);
+       availmem = PAGE_ALIGN(availmem);
+       free_bootmem(__pa(availmem), memory_end - (availmem));
+}
+
+void __init config_coldfire(void)
+{
+       unsigned long endmem, startmem;
+       int i;
+
+       /*
+        * Calculate endmem from m68k_memory, assume all are contiguous
+        */
+       startmem = ((((int) &_end) + (PAGE_SIZE - 1)) & PAGE_MASK);
+       endmem = PAGE_OFFSET;
+       for (i = 0; i < m68k_num_memory; ++i)
+               endmem += m68k_memory[i].size;
+
+       printk(KERN_INFO "starting up linux startmem 0x%lx, endmem 0x%lx, \
+               size %luMB\n", startmem,  endmem, (endmem - startmem) >> 20);
+
+       memset(irq_enable, 0, sizeof(irq_enable));
+
+       /*
+        * Setup coldfire mach-specific handlers
+        */
+       mach_max_dma_address    = 0xffffffff;
+       mach_sched_init         = coldfire_sched_init;
+       mach_tick               = coldfire_tick;
+       mach_gettimeoffset      = coldfire_gettimeoffset;
+       mach_reset              = coldfire_reboot;
+/*     mach_hwclk              = coldfire_hwclk; to be done */
+       mach_get_model          = coldfire_get_model;
+
+       coldfire_bootmem_alloc(startmem, endmem-1);
+
+       /*
+        * initrd setup
+        */
+/* #ifdef CONFIG_BLK_DEV_INITRD
+       if (m68k_ramdisk.size)  {
+               reserve_bootmem (__pa(m68k_ramdisk.addr), m68k_ramdisk.size);
+               initrd_start = (unsigned long) m68k_ramdisk.addr;
+               initrd_end = initrd_start + m68k_ramdisk.size;
+               printk (KERN_DEBUG "initrd: %08lx - %08lx\n", initrd_start,
+                       initrd_end);
+       }
+#endif */
+
+#if defined(CONFIG_DUMMY_CONSOLE) || defined(CONFIG_FRAMEBUFFER_CONSOLE)
+       conswitchp = &dummy_con;
+#endif
+
+}
diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
new file mode 100644 (file)
index 0000000..6360c43
--- /dev/null
@@ -0,0 +1,771 @@
+/* -*- mode: asm -*-
+ *
+ *  linux/arch/m68k/kernel/entry.S
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file README.legal in the main directory of this archive
+ * for more details.
+ *
+ * Linux/m68k support by Hamish Macdonald
+ *
+ * 68060 fixes by Jesper Skov
+ *
+ */
+
+/*
+ * entry.S  contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ */
+
+/*
+ * 12/03/96 Jes: Currently we only support m68k single-cpu systems, so
+ *               all pointers that used to be 'current' are now entry
+ *               number 0 in the 'current_set' list.
+ *
+ *  6/05/00 RZ:         addedd writeback completion after return from sighandler
+ *              for 68040
+ */
+
+#include <linux/linkage.h>
+#include <asm/entry.h>
+#include <asm/errno.h>
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+#include <asm/unistd.h>
+
+#include <asm/asm-offsets.h>
+
+.globl system_call, buserr, trap, resume
+.globl sys_call_table
+.globl sys_fork, sys_clone, sys_vfork
+.globl ret_from_interrupt, bad_interrupt
+.globl auto_irqhandler_fixup
+.globl user_irqvec_fixup, user_irqhandler_fixup
+
+.text
+ENTRY(buserr)
+       SAVE_ALL_INT
+       GET_CURRENT(%d0)
+       movel   %sp,%sp@-               | stack frame pointer argument
+       bsrl    buserr_c
+       addql   #4,%sp
+       jra     .Lret_from_exception
+
+ENTRY(trap)
+       SAVE_ALL_INT
+       GET_CURRENT(%d0)
+       movel   %sp,%sp@-               | stack frame pointer argument
+       bsrl    trap_c
+       addql   #4,%sp
+       jra     .Lret_from_exception
+
+       | After a fork we jump here directly from resume,
+       | so that %d1 contains the previous task
+       | schedule_tail now used regardless of CONFIG_SMP
+ENTRY(ret_from_fork)
+       movel   %d1,%sp@-
+       jsr     schedule_tail
+       addql   #4,%sp
+       jra     .Lret_from_exception
+
+do_trace_entry:
+       movel   #-ENOSYS,%sp@(PT_OFF_D0)| needed for strace
+       subql   #4,%sp
+       SAVE_SWITCH_STACK
+       jbsr    syscall_trace
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       movel   %sp@(PT_OFF_ORIG_D0),%d0
+       cmpl    #NR_syscalls,%d0
+       jcs     syscall
+badsys:
+       movel   #-ENOSYS,%sp@(PT_OFF_D0)
+       jra     ret_from_syscall
+
+do_trace_exit:
+       subql   #4,%sp
+       SAVE_SWITCH_STACK
+       jbsr    syscall_trace
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       jra     .Lret_from_exception
+
+ENTRY(ret_from_signal)
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+/* on 68040 complete pending writebacks if any */
+#ifdef CONFIG_M68040
+       bfextu  %sp@(PT_OFF_FORMATVEC){#0,#4},%d0
+       subql   #7,%d0                          | bus error frame ?
+       jbne    1f
+       movel   %sp,%sp@-
+       jbsr    berr_040cleanup
+       addql   #4,%sp
+1:
+#endif
+       jra     .Lret_from_exception
+
+ENTRY(system_call)
+       SAVE_ALL_SYS
+
+       GET_CURRENT(%d1)
+       | save top of frame
+       movel   %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+
+       | syscall trace?
+       tstb    %curptr@(TASK_INFO+TINFO_FLAGS+2)
+       jmi     do_trace_entry
+       cmpl    #NR_syscalls,%d0
+       jcc     badsys
+syscall:
+       jbsr    @(sys_call_table,%d0:l:4)@(0)
+       movel   %d0,%sp@(PT_OFF_D0)     | save the return value
+ret_from_syscall:
+       |oriw   #0x0700,%sr
+       movew   %curptr@(TASK_INFO+TINFO_FLAGS+2),%d0
+       jne     syscall_exit_work
+1:     RESTORE_ALL
+
+syscall_exit_work:
+       btst    #5,%sp@(PT_OFF_SR)      | check if returning to kernel
+       bnes    1b                      | if so, skip resched, signals
+       lslw    #1,%d0
+       jcs     do_trace_exit
+       jmi     do_delayed_trace
+       lslw    #8,%d0
+       jmi     do_signal_return
+       pea     resume_userspace
+       jra     schedule
+
+
+ENTRY(ret_from_exception)
+.Lret_from_exception:
+       btst    #5,%sp@(PT_OFF_SR)      | check if returning to kernel
+       bnes    1f                      | if so, skip resched, signals
+       | only allow interrupts when we are really the last one on the
+       | kernel stack, otherwise stack overflow can occur during
+       | heavy interrupt load
+       andw    #ALLOWINT,%sr
+
+resume_userspace:
+       moveb   %curptr@(TASK_INFO+TINFO_FLAGS+3),%d0
+       jne     exit_work
+1:     RESTORE_ALL
+
+exit_work:
+       | save top of frame
+       movel   %sp,%curptr@(TASK_THREAD+THREAD_ESP0)
+       lslb    #1,%d0
+       jmi     do_signal_return
+       pea     resume_userspace
+       jra     schedule
+
+
+do_signal_return:
+       |andw   #ALLOWINT,%sr
+       subql   #4,%sp                  | dummy return address
+       SAVE_SWITCH_STACK
+       pea     %sp@(SWITCH_STACK_SIZE)
+       clrl    %sp@-
+       bsrl    do_signal
+       addql   #8,%sp
+       RESTORE_SWITCH_STACK
+       addql   #4,%sp
+       tstl    %d0
+       jeq     resume_userspace
+       | when single stepping into handler stop at the first insn
+       btst    #6,%curptr@(TASK_INFO+TINFO_FLAGS+2)
+       jeq     resume_userspace
+
+do_delayed_trace:
+       bclr    #7,%sp@(PT_OFF_SR)      | clear trace bit in SR
+       pea     1                       | send SIGTRAP
+       movel   %curptr,%sp@-
+       pea     LSIGTRAP
+       jbsr    send_sig
+       addql   #8,%sp
+       addql   #4,%sp
+       jbra    resume_userspace
+
+
+/* This is the main interrupt handler for autovector interrupts */
+
+ENTRY(auto_inthandler)
+       SAVE_ALL_INT
+       GET_CURRENT(%d0)
+       addqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+                                       |  put exception # in d0
+       bfextu  %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
+       subw    #VEC_SPUR,%d0
+
+       movel   %sp,%sp@-
+       movel   %d0,%sp@-               |  put vector # on stack
+auto_irqhandler_fixup = . + 2
+       jsr     __m68k_handle_int       |  process the IRQ
+       addql   #8,%sp                  |  pop parameters off stack
+
+ret_from_interrupt:
+       subqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+       jeq     ret_from_last_interrupt
+2:     RESTORE_ALL
+
+       ALIGN
+ret_from_last_interrupt:
+       moveq   #(~ALLOWINT>>8)&0xff,%d0
+       andb    %sp@(PT_OFF_SR),%d0
+       jne     2b
+
+       /* check if we need to do software interrupts */
+       tstl    irq_stat+CPUSTAT_SOFTIRQ_PENDING
+       jeq     .Lret_from_exception
+       pea     ret_from_exception
+       jra     do_softirq
+
+/* Handler for user defined interrupt vectors */
+
+ENTRY(user_inthandler)
+       SAVE_ALL_INT
+       GET_CURRENT(%d0)
+       addqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+                                       |  put exception # in d0
+       bfextu  %sp@(PT_OFF_FORMATVEC){#4,#10},%d0
+user_irqvec_fixup = . + 2
+       subw    #VEC_USER,%d0
+
+       movel   %sp,%sp@-
+       movel   %d0,%sp@-               |  put vector # on stack
+user_irqhandler_fixup = . + 2
+       jsr     __m68k_handle_int       |  process the IRQ
+       addql   #8,%sp                  |  pop parameters off stack
+
+       subqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+       jeq     ret_from_last_interrupt
+       RESTORE_ALL
+
+/* Handler for uninitialized and spurious interrupts */
+
+ENTRY(bad_inthandler)
+       SAVE_ALL_INT
+       GET_CURRENT(%d0)
+       addqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+
+       movel   %sp,%sp@-
+       jsr     handle_badint
+       addql   #4,%sp
+
+       subqb   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
+       jeq     ret_from_last_interrupt
+       RESTORE_ALL
+
+
+ENTRY(sys_fork)
+       SAVE_SWITCH_STACK
+       pea     %sp@(SWITCH_STACK_SIZE)
+       jbsr    m68k_fork
+       addql   #4,%sp
+       RESTORE_SWITCH_STACK
+       rts
+
+ENTRY(sys_clone)
+       SAVE_SWITCH_STACK
+       pea     %sp@(SWITCH_STACK_SIZE)
+       jbsr    m68k_clone
+       addql   #4,%sp
+       RESTORE_SWITCH_STACK
+       rts
+
+ENTRY(sys_vfork)
+       SAVE_SWITCH_STACK
+       pea     %sp@(SWITCH_STACK_SIZE)
+       jbsr    m68k_vfork
+       addql   #4,%sp
+       RESTORE_SWITCH_STACK
+       rts
+
+ENTRY(sys_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
+
+resume:
+       /*
+        * Beware - when entering resume, prev (the current task) is
+        * in a0, next (the new task) is in a1,so don't change these
+        * registers until their contents are no longer needed.
+        */
+
+       /* save sr */
+       movew   %sr,%a0@(TASK_THREAD+THREAD_SR)
+
+       /* save fs (sfc,%dfc) (may be pointing to kernel memory) */
+       movec   %sfc,%d0
+       movew   %d0,%a0@(TASK_THREAD+THREAD_FS)
+
+       /* save usp */
+       /* it is better to use a movel here instead of a movew 8*) */
+       movec   %usp,%d0
+       movel   %d0,%a0@(TASK_THREAD+THREAD_USP)
+
+       /* save non-scratch registers on stack */
+       SAVE_SWITCH_STACK
+
+       /* save current kernel stack pointer */
+       movel   %sp,%a0@(TASK_THREAD+THREAD_KSP)
+
+       /* save floating point context */
+#ifndef CONFIG_M68KFPU_EMU_ONLY
+#ifdef CONFIG_M68KFPU_EMU
+       tstl    m68k_fputype
+       jeq     3f
+#endif
+       fsave   %a0@(TASK_THREAD+THREAD_FPSTATE)
+
+#if defined(CONFIG_M68060)
+#if !defined(CPU_M68060_ONLY)
+       btst    #3,m68k_cputype+3
+       beqs    1f
+#endif
+       /* The 060 FPU keeps status in bits 15-8 of the first longword */
+       tstb    %a0@(TASK_THREAD+THREAD_FPSTATE+2)
+       jeq     3f
+#if !defined(CPU_M68060_ONLY)
+       jra     2f
+#endif
+#endif /* CONFIG_M68060 */
+#if !defined(CPU_M68060_ONLY)
+1:     tstb    %a0@(TASK_THREAD+THREAD_FPSTATE)
+       jeq     3f
+#endif
+2:     fmovemx %fp0-%fp7,%a0@(TASK_THREAD+THREAD_FPREG)
+       fmoveml %fpcr/%fpsr/%fpiar,%a0@(TASK_THREAD+THREAD_FPCNTL)
+3:
+#endif /* CONFIG_M68KFPU_EMU_ONLY */
+       /* Return previous task in %d1 */
+       movel   %curptr,%d1
+
+       /* switch to new task (a1 contains new task) */
+       movel   %a1,%curptr
+
+       /* restore floating point context */
+#ifndef CONFIG_M68KFPU_EMU_ONLY
+#ifdef CONFIG_M68KFPU_EMU
+       tstl    m68k_fputype
+       jeq     4f
+#endif
+#if defined(CONFIG_M68060)
+#if !defined(CPU_M68060_ONLY)
+       btst    #3,m68k_cputype+3
+       beqs    1f
+#endif
+       /* The 060 FPU keeps status in bits 15-8 of the first longword */
+       tstb    %a1@(TASK_THREAD+THREAD_FPSTATE+2)
+       jeq     3f
+#if !defined(CPU_M68060_ONLY)
+       jra     2f
+#endif
+#endif /* CONFIG_M68060 */
+#if !defined(CPU_M68060_ONLY)
+1:     tstb    %a1@(TASK_THREAD+THREAD_FPSTATE)
+       jeq     3f
+#endif
+2:     fmovemx %a1@(TASK_THREAD+THREAD_FPREG),%fp0-%fp7
+       fmoveml %a1@(TASK_THREAD+THREAD_FPCNTL),%fpcr/%fpsr/%fpiar
+3:     frestore %a1@(TASK_THREAD+THREAD_FPSTATE)
+4:
+#endif /* CONFIG_M68KFPU_EMU_ONLY */
+
+       /* restore the kernel stack pointer */
+       movel   %a1@(TASK_THREAD+THREAD_KSP),%sp
+
+       /* restore non-scratch registers */
+       RESTORE_SWITCH_STACK
+
+       /* restore user stack pointer */
+       movel   %a1@(TASK_THREAD+THREAD_USP),%a0
+       movel   %a0,%usp
+
+       /* restore fs (sfc,%dfc) */
+       movew   %a1@(TASK_THREAD+THREAD_FS),%a0
+       movec   %a0,%sfc
+       movec   %a0,%dfc
+
+       /* restore status register */
+       movew   %a1@(TASK_THREAD+THREAD_SR),%sr
+
+       rts
+
+.data
+ALIGN
+sys_call_table:
+       .long sys_restart_syscall       /* 0 - old "setup()" system call, used for restarting */
+       .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 sys_old_select
+       .long sys_symlink
+       .long sys_lstat
+       .long sys_readlink      /* 85 */
+       .long sys_uselib
+       .long sys_swapon
+       .long sys_reboot
+       .long sys_old_readdir
+       .long sys_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    /* 110 */       /* iopl for i386 */
+       .long sys_vhangup
+       .long sys_ni_syscall                            /* obsolete idle() syscall */
+       .long sys_ni_syscall                            /* vm86old for i386 */
+       .long sys_wait4
+       .long sys_swapoff       /* 115 */
+       .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_mprotect      /* 125 */
+       .long sys_sigprocmask
+       .long sys_ni_syscall            /* old "create_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_msync
+       .long sys_readv         /* 145 */
+       .long sys_writev
+       .long sys_getsid
+       .long sys_fdatasync
+       .long sys_sysctl
+       .long sys_mlock         /* 150 */
+       .long sys_munlock
+       .long sys_mlockall
+       .long 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_mremap
+       .long sys_setresuid16
+       .long sys_getresuid16   /* 165 */
+       .long sys_getpagesize
+       .long sys_ni_syscall            /* old sys_query_module */
+       .long sys_poll
+       .long 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_mincore
+       .long 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_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    /* for sys_vserver */
+       .long sys_add_key
+       .long sys_request_key   /* 280 */
+       .long sys_keyctl
+       .long sys_ioprio_set
+       .long sys_ioprio_get
+       .long sys_inotify_init
+       .long sys_inotify_add_watch     /* 285 */
+       .long sys_inotify_rm_watch
+       .long sys_migrate_pages
+       .long sys_openat
+       .long sys_mkdirat
+       .long sys_mknodat               /* 290 */
+       .long sys_fchownat
+       .long sys_futimesat
+       .long sys_fstatat64
+       .long sys_unlinkat
+       .long sys_renameat              /* 295 */
+       .long sys_linkat
+       .long sys_symlinkat
+       .long sys_readlinkat
+       .long sys_fchmodat
+       .long sys_faccessat             /* 300 */
+       .long sys_ni_syscall            /* Reserved for pselect6 */
+       .long sys_ni_syscall            /* Reserved for ppoll */
+       .long sys_unshare
+       .long sys_set_robust_list
+       .long sys_get_robust_list       /* 305 */
+       .long sys_splice
+       .long sys_sync_file_range
+       .long sys_tee
+       .long sys_vmsplice
+       .long sys_move_pages            /* 310 */
+       .long sys_sched_setaffinity
+       .long sys_sched_getaffinity
+       .long sys_kexec_load
+       .long sys_getcpu
+       .long sys_epoll_pwait           /* 315 */
+       .long sys_utimensat
+       .long sys_signalfd
+       .long sys_timerfd_create
+       .long sys_eventfd
+       .long sys_fallocate             /* 320 */
+       .long sys_timerfd_settime
+       .long sys_timerfd_gettime
+       .long sys_signalfd4
+       .long sys_eventfd2
+       .long sys_epoll_create1         /* 325 */
+       .long sys_dup3
+       .long sys_pipe2
+       .long sys_inotify_init1
+       .long sys_preadv
+       .long sys_pwritev               /* 330 */
+       .long sys_rt_tgsigqueueinfo
+       .long sys_perf_event_open
+       .long sys_get_thread_area
+       .long sys_set_thread_area
+       .long sys_atomic_cmpxchg_32     /* 335 */
+       .long sys_atomic_barrier
+       .long sys_fanotify_init
+       .long sys_fanotify_mark
+       .long sys_prlimit64
+
diff --git a/arch/m68k/coldfire/head.S b/arch/m68k/coldfire/head.S
new file mode 100644 (file)
index 0000000..ff329b7
--- /dev/null
@@ -0,0 +1,679 @@
+/*
+ *  head.S is the MMU enabled ColdFire specific initial boot code
+ *
+ *  Ported to ColdFire by
+ *    Matt Waddel Matt.Waddel@freescale.com
+ *    Kurt Mahan kmahan@freescale.com
+ *  Copyright Freescale Semiconductor, Inc. 2007, 2008
+ *  Phys kernel mapping Copyright Daniel Krueger, SYSTEC electornic GmbH 2008
+ *
+ *  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.
+ *
+ *  Parts of this code came from arch/m68k/kernel/head.S
+ */
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/bootinfo.h>
+#include <asm/setup.h>
+#include <asm/entry.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/coldfire.h>
+#include <asm/mcfuart.h>
+#include <asm/mcfcache.h>
+#include <asm/thread_info.h>
+
+#define DEBUG
+
+.globl kernel_pg_dir
+.globl availmem
+.globl set_context
+.globl set_fpga
+#if defined(CONFIG_UBOOT)
+.global        uboot_init_sp
+#endif
+
+
+#ifdef DEBUG
+/* When debugging use readable names for labels */
+#ifdef __STDC__
+#define L(name) .head.S.##name
+#else
+#define L(name) .head.S./**/name
+#endif
+#else
+#ifdef __STDC__
+#define L(name) .L##name
+#else
+#define L(name) .L/**/name
+#endif
+#endif
+
+/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
+#ifndef __INITDATA
+#define __INITDATA     .data
+#define __FINIT                .previous
+#endif
+
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+/*
+ * Kernel mapped to virtual ram address.
+ *
+ * M5445x:
+ *    Data[0]: 0xF0000000 -> 0xFFFFFFFF        System regs
+ *    Data[1]: 0xA0000000 -> 0xAFFFFFFF        PCI
+ *    Code[0]: Not Mapped
+ *    Code[1]: Not Mapped
+ *
+ * M547x/M548x
+ *    Data[0]: 0xF0000000 -> 0xFFFFFFFF        System regs
+ *    Data[1]: Not Mapped
+ *    Code[0]: Not Mapped
+ *    Code[1]: Not Mapped
+ */
+#if defined(CONFIG_M5445X)
+#define ACR0_DEFAULT   #0xF00FA048   /* System regs */
+#define ACR1_DEFAULT   #0xA00FA048   /* PCI */
+#define ACR2_DEFAULT   #0x00000000   /* Not Mapped */
+#define ACR3_DEFAULT   #0x00000000   /* Not Mapped */
+#elif defined(CONFIG_M547X_8X)
+#define ACR0_DEFAULT   #0xF00FA048   /* System Regs */
+#define ACR1_DEFAULT   #0x00000000   /* Not Mapped */
+#define ACR2_DEFAULT   #0x00000000   /* Not Mapped */
+#define ACR3_DEFAULT   #0x00000000   /* Not Mapped */
+#endif
+
+#else /* CONFIG_SDRAM_BASE = PAGE_OFFSET */
+/*
+ * Kernel mapped to physical ram address.
+ *
+ * M5445x:
+ *    Data[0]: 0xF0000000 -> 0xFFFFFFFF        System regs
+ *    Data[1]: 0x40000000 -> 0x4FFFFFFF        SDRAM - uncached
+ *    Code[0]: Not Mapped
+ *    Code[1]: 0x40000000 -> 0x4FFFFFFF        SDRAM - cached
+ *
+ * M547x/M548x
+ *    Data[0]: 0xF0000000 -> 0xFFFFFFFF        System regs
+ *    Data[1]: 0x00000000 -> 0x0FFFFFFF        SDRAM - uncached
+ *    Code[0]: Not Mapped
+ *    Code[1]: 0x00000000 -> 0x0FFFFFFF        SDRAM - cached
+ */
+#if defined(CONFIG_M5445X)
+#define ACR0_DEFAULT   #0xF00FA048   /* System Regs */
+#define ACR1_DEFAULT   #0x400FA048   /* SDRAM uncached */
+#define ACR2_DEFAULT   #0x00000000   /* Not mapped */
+#define ACR3_DEFAULT   #0x400FA008   /* SDRAM cached */
+#elif defined(CONFIG_M547X_8X)
+#define ACR0_DEFAULT   #0xF00FA048   /* System Regs */
+#define ACR1_DEFAULT   #0x000FA048   /* SDRAM uncached */
+#define ACR2_DEFAULT   #0x00000000   /* Not mapped */
+#define ACR3_DEFAULT   #0x000FA008   /* SDRAM cached */
+#endif
+#endif
+
+/* Several macros to make the writing of subroutines easier:
+ * - func_start marks the beginning of the routine which setups the frame
+ *   register and saves the registers, it also defines another macro
+ *   to automatically restore the registers again.
+ * - func_return marks the end of the routine and simply calls the prepared
+ *   macro to restore registers and jump back to the caller.
+ * - func_define generates another macro to automatically put arguments
+ *   onto the stack call the subroutine and cleanup the stack again.
+ */
+
+.macro load_symbol_address     symbol,register
+       movel   #\symbol,\register
+.endm
+       
+.macro func_start      name,saveregs,savesize,stack=0
+L(\name):
+       linkw   %a6,#-\stack
+       subal   #(\savesize),%sp
+       moveml  \saveregs,%sp@
+.set   stackstart,-\stack
+
+.macro func_return_\name
+       moveml  %sp@,\saveregs
+       addal   #(\savesize),%sp
+       unlk    %a6
+       rts
+.endm
+.endm
+
+.macro func_return     name
+       func_return_\name
+.endm
+
+.macro func_call       name
+       jbsr    L(\name)
+.endm
+
+.macro move_stack      nr,arg1,arg2,arg3,arg4
+.if    \nr
+       move_stack      "(\nr-1)",\arg2,\arg3,\arg4
+       movel   \arg1,%sp@-
+.endif
+.endm
+
+.macro func_define     name,nr=0
+.macro \name   arg1,arg2,arg3,arg4
+       move_stack      \nr,\arg1,\arg2,\arg3,\arg4
+       func_call       \name
+.if    \nr
+       lea     %sp@(\nr*4),%sp
+.endif
+.endm
+.endm
+
+func_define    serial_putc,1
+
+.macro putc    ch
+       pea     \ch
+       func_call       serial_putc
+       addql   #4,%sp
+.endm
+
+.macro dputc   ch
+#ifdef DEBUG
+       putc    \ch
+#endif
+.endm
+
+func_define    putn,1
+
+.macro dputn   nr
+#ifdef DEBUG
+       putn    \nr
+#endif
+.endm
+
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+/*
+       mmu_map  -  creates a new TLB entry
+
+       virt_addr      Must be on proper boundary
+       phys_addr      Must be on proper boundary
+       itlb           MMUOR_ITLB if instruction TLB or 0
+       asid           address space ID
+       shared_global  MMUTR_SG if shared between different ASIDs or 0
+       size_code      MMUDR_SZ1M  1 MB
+                      MMUDR_SZ4K  4 KB
+                      MMUDR_SZ8K  8 KB
+                      MMUDR_SZ16M 16 MB
+       cache_mode     MMUDR_INC   instruction non-cacheable
+                       MMUDR_IC    instruction cacheable
+                       MMUDR_DWT   data writethrough
+                      MMUDR_DCB   data copyback
+                      MMUDR_DNCP  data non-cacheable, precise
+                      MMUDR_DNCIP data non-cacheable, imprecise
+       super_prot     MMUDR_SP if user mode generates exception or 0
+       readable       MMUDR_R if permits read access (data TLB) or 0
+       writable       MMUDR_W if permits write access (data TLB) or 0
+       executable     MMUDR_X if permits execute access (instruction TLB) or 0
+       locked         MMUDR_LK prevents TLB entry from being replaced or 0
+       temp_data_reg  a data register to use for temporary values
+*/
+.macro mmu_map virt_addr,phys_addr,itlb,asid,shared_global,size_code,cache_mode,super_prot,readable,writable,executable,locked,temp_data_reg
+       /* Set up search of TLB. */
+       movel   #(\virt_addr+1), \temp_data_reg
+       movel   \temp_data_reg, MMUAR
+       /* Search.  */
+       movel   #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
+       movew   \temp_data_reg, (MMUOR)
+       /* Set up tag value.  */
+       movel   #(\virt_addr + \asid + \shared_global + MMUTR_V), \temp_data_reg
+       movel   \temp_data_reg, MMUTR
+       /* Set up data value.  */
+       movel   #(\phys_addr + \size_code + \cache_mode + \super_prot + \readable + \writable + \executable + \locked), \temp_data_reg
+       movel   \temp_data_reg, MMUDR
+       /* Save it.  */
+       movel   #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
+       movew   \temp_data_reg, (MMUOR)
+.endm  /* mmu_map */
+
+.macro mmu_unmap       virt_addr,itlb,temp_data_reg
+       /* Set up search of TLB. */
+       movel   #(\virt_addr+1), \temp_data_reg
+       movel   \temp_data_reg, MMUAR
+       /* Search.  */
+       movel   #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
+       movew   \temp_data_reg, (MMUOR)
+       /* Test for hit.  */
+       movel   MMUSR,\temp_data_reg
+       btst    #MMUSR_HITN,\temp_data_reg
+       beq     1f
+       /* Read the TLB.  */
+       movel   #(MMUOR_RW + MMUOR_ACC +\itlb), \temp_data_reg
+       movew   \temp_data_reg, (MMUOR)
+       movel   MMUSR,\temp_data_reg
+       /* Set up tag value.  */
+       movel   #0, \temp_data_reg
+       movel   \temp_data_reg, MMUTR
+       /* Set up data value.  */
+       movel   #0, \temp_data_reg
+       movel   \temp_data_reg, MMUDR
+       /* Save it.  */
+       movel   #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
+       movew   \temp_data_reg, (MMUOR)
+1:     
+.endm  /* mmu_unmap */
+#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
+
+/* .text */
+.section ".text.head","ax"
+ENTRY(_stext)
+/* Version numbers of the bootinfo interface -- if we later pass info
+ * from boot ROM we might want to put something real here.
+ *
+ * The area from _stext to _start will later be used as kernel pointer table
+ */
+       bras    1f      /* Jump over bootinfo version numbers */
+
+       .long   BOOTINFOV_MAGIC
+       .long   0
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+1:     jmp     __start-(0xc0000000-CONFIG_SDRAM_BASE)
+#else
+1:     jmp     __start
+#endif
+
+.equ   kernel_pg_dir,_stext
+.equ   .,_stext+0x1000
+
+ENTRY(_start)
+       jra     __start
+__INIT
+ENTRY(__start)
+       movew   #0x2700,%sr                             /* no interrupts */
+#if defined(CONFIG_UBOOT)
+       movel   %sp,uboot_init_sp                       /* save initial stack pointer */
+#endif
+
+/* Setup initial stack pointer */
+       movel   #CONFIG_SDRAM_BASE+0x1000,%sp
+
+/* Setup usp */
+       subl    %a0,%a0
+       movel   %a0,%usp
+
+#if defined(CONFIG_M5445X)
+       movel   #0x80000000, %d0
+       movec   %d0, %rambar1
+#elif defined(CONFIG_M547X_8X)
+       movel   #MCF_MBAR, %d0
+       movec   %d0, %mbar
+       move.l  #(MCF_RAMBAR0 + 0x21), %d0
+       movec   %d0, %rambar0
+       move.l  #(MCF_RAMBAR1 + 0x21), %d0
+       movec   %d0, %rambar1
+#endif
+
+/* reset cache */
+       movel   #(CF_CACR_ICINVA + CF_CACR_DCINVA),%d0
+       movecl  %d0,%cacr
+
+       movel   #(MMU_BASE+1),%d0
+       movecl  %d0,%mmubar
+       movel   #MMUOR_CA,%a0                   /* Clear tlb entries */
+       movew   %a0,(MMUOR)
+       movel   #(MMUOR_CA + MMUOR_ITLB),%a0    /* Use ITLB for searches */
+       movew   %a0,(MMUOR)
+       movel   #0,%a0                          /* Clear Addr Space User ID */
+       movecl  %a0,%asid 
+
+/* setup ACRs */
+       movel   ACR0_DEFAULT, %d0               /* ACR0 (DATA) setup */
+       movec   %d0, %acr0
+       nop
+       movel   ACR1_DEFAULT, %d0               /* ACR1 (DATA) setup */
+       movec   %d0, %acr1
+       nop
+       movel   ACR2_DEFAULT, %d0               /* ACR2 (CODE) setup */
+       movec   %d0, %acr2
+       nop
+       movel   ACR3_DEFAULT, %d0               /* ACR3 (CODE) setup */
+       movec   %d0, %acr3
+       nop
+
+       /* If you change the memory size to another value make a matching 
+          change in paging_init(cf-mmu.c) to zones_size[]. */
+
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+#if defined(CONFIG_M5445X)
+       /* Map 256MB as code */
+       mmu_map (PAGE_OFFSET+0*0x1000000),  (PHYS_OFFSET+0*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+1*0x1000000),  (PHYS_OFFSET+1*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+2*0x1000000),  (PHYS_OFFSET+2*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+3*0x1000000),  (PHYS_OFFSET+3*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+4*0x1000000),  (PHYS_OFFSET+4*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+5*0x1000000),  (PHYS_OFFSET+5*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+6*0x1000000),  (PHYS_OFFSET+6*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+7*0x1000000),  (PHYS_OFFSET+7*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+8*0x1000000),  (PHYS_OFFSET+8*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+9*0x1000000),  (PHYS_OFFSET+9*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
+               0, 0, MMUDR_X, MMUDR_LK, %d0
+
+       /* Map 256MB as data also */
+       mmu_map (PAGE_OFFSET+0*0x1000000),  (PHYS_OFFSET+0*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+1*0x1000000),  (PHYS_OFFSET+1*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+2*0x1000000),  (PHYS_OFFSET+2*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+3*0x1000000),  (PHYS_OFFSET+3*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+4*0x1000000),  (PHYS_OFFSET+4*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+5*0x1000000),  (PHYS_OFFSET+5*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+6*0x1000000),  (PHYS_OFFSET+6*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+7*0x1000000),  (PHYS_OFFSET+7*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+8*0x1000000),  (PHYS_OFFSET+8*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+9*0x1000000),  (PHYS_OFFSET+9*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+
+       /* Map ATA registers -- sacrifice a data TLB due to the hw design */
+       mmu_map (0x90000000), (0x90000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, MMUDR_LK, %d0
+
+#elif defined(CONFIG_M547X_8X)
+
+       /* Map first 8 MB as code */
+       mmu_map (PAGE_OFFSET+0*1024*1024),  (0*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+1*1024*1024),  (1*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+2*1024*1024),  (2*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+3*1024*1024),  (3*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+4*1024*1024),  (4*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+5*1024*1024),  (5*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+6*1024*1024),  (6*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+7*1024*1024),  (7*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
+               MMUDR_LK, %d0
+
+       /* Map first 8 MB as data */
+       mmu_map (PAGE_OFFSET+0*1024*1024),  (0*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+1*1024*1024),  (1*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+2*1024*1024),  (2*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+3*1024*1024),  (3*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+4*1024*1024),  (4*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+5*1024*1024),  (5*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+6*1024*1024),  (6*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+       mmu_map (PAGE_OFFSET+7*1024*1024),  (7*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, MMUDR_LK, %d0
+#endif
+       /*
+        * Do unity mapping to enable the MMU.  Map first chunk of memory
+        * in place as code/data.  The TLBs will be deleted after the MMU is
+        * enabled and we are executing in high memory.
+        */
+
+#if defined(CONFIG_M5445X)
+       /* Map first 16 MB as code */
+       mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
+               MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_INC,  MMUDR_SP, 0, \
+               0, MMUDR_X, 0, %d0
+       /* Map first 16 MB as data too  */
+       mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
+               MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
+               0, 0, %d0
+#elif defined(CONFIG_M547X_8X)
+       /* Map first 4 MB as code */
+       mmu_map (0*1024*1024), (0*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
+               MMUDR_X, 0, %d0
+       mmu_map (1*1024*1024), (1*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
+               MMUDR_X, 0, %d0
+       mmu_map (2*1024*1024), (2*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
+               MMUDR_X, 0, %d0
+       mmu_map (3*1024*1024), (3*1024*1024), MMUOR_ITLB, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
+               MMUDR_X, 0, %d0
+
+       /* Map first 4 MB as data too */
+       mmu_map (0*1024*1024), (0*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, 0, %d0
+       mmu_map (1*1024*1024), (1*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, 0, %d0
+       mmu_map (2*1024*1024), (2*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, 0, %d0
+       mmu_map (3*1024*1024), (3*1024*1024), 0, 0, \
+               MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
+               MMUDR_W, 0, 0, %d0
+#endif
+#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
+
+       /* Turn on MMU */
+       movel   #(MMUCR_EN),%a0
+       movel   %a0,MMUCR
+       nop     /* This synchs the pipeline after a write to MMUCR */
+
+       movel   #__running_high,%a0  /* Get around PC-relative addressing. */
+       jmp     %a0@
+
+ENTRY(__running_high)
+       load_symbol_address _stext,%sp
+       movel   L(memory_start),%a0
+       movel   %a0,availmem
+       load_symbol_address L(phys_kernel_start),%a0
+       load_symbol_address _stext,%a1
+       subl    #_stext,%a1
+       addl    #PAGE_OFFSET,%a1
+       movel   %a1,%a0@
+
+/* zero bss */
+       lea     _sbss,%a0
+       lea     _ebss,%a1
+       clrl    %d0
+_loop_bss:
+       movel   %d0,(%a0)+
+       cmpl    %a0,%a1
+       bne     _loop_bss
+
+       /* Unmap unity mappings */
+#if CONFIG_SDRAM_BASE != PAGE_OFFSET
+#if defined(CONFIG_M5445X)
+       mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
+       mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
+#elif defined(CONFIG_M547X_8X)
+       mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
+       mmu_unmap (PHYS_OFFSET+1*0x1000000), MMUOR_ITLB, %d0
+       mmu_unmap (PHYS_OFFSET+2*0x1000000), MMUOR_ITLB, %d0
+       mmu_unmap (PHYS_OFFSET+3*0x1000000), MMUOR_ITLB, %d0
+       mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
+       mmu_unmap (PHYS_OFFSET+1*0x1000000), 0, %d0
+       mmu_unmap (PHYS_OFFSET+2*0x1000000), 0, %d0
+       mmu_unmap (PHYS_OFFSET+3*0x1000000), 0, %d0
+#endif
+#endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
+
+       /*
+        *      Load the current task pointer and stack.
+        */
+       lea     init_thread_union,%a0
+       lea     THREAD_SIZE(%a0),%sp
+
+#ifdef CONFIG_MCF_USER_HALT
+/* Setup debug control reg to allow halts from user space */
+       lea     wdbg_uhe,%a0
+       wdebug  (%a0)
+#endif
+
+
+#ifdef CONFIG_UBOOT
+       /* save the uboot structure to variable */
+       mov             uboot_init_sp, %a4
+       addl    #0x00000004,%a4 /* offset past top */
+       addl    #(PAGE_OFFSET-CONFIG_SDRAM_BASE),%a4    /* high mem offset */
+       movel   %a4,uboot_info_stk /* save uboot info to variable */
+#endif
+
+       /* Continuing in C code */
+       bsr     cf_early_init
+       jmp     start_kernel
+
+.section ".text.head","ax"
+set_context:
+func_start     set_context,%d0,(1*4)
+       movel   12(%sp),%d0
+       movec   %d0,%asid
+func_return    set_context
+
+#ifdef CONFIG_M5445X
+/*
+ * set_fpga(addr,val) on the M5445X
+ *
+ * Map in 0x00000000 -> 0x0fffffff and then do the write.
+ */
+set_fpga:
+#if 0
+       movew   %sr,%d1
+       movew   #0x2700,%sr
+       movel   ACR0_FPGA, %d0
+       movec   %d0, %acr0
+       nop
+       moveal  4(%sp),%a0
+       movel   8(%sp),%a0@
+       movel   ACR0_DEFAULT, %d0
+       movec   %d0, %acr0
+       nop
+       movew   %d1,%sr
+#endif
+       rts
+#endif
+
+       .data
+       .align  4
+
+availmem:
+       .long   0
+L(phys_kernel_start):
+       .long   PAGE_OFFSET
+L(kernel_end):
+       .long   0
+L(memory_start):
+       .long   PAGE_OFFSET_RAW
+
+#if defined(CONFIG_UBOOT)
+L(uboot_init_sp):
+.long  0
+#endif
+
+#ifdef CONFIG_MCF_USER_HALT
+/*
+ * Enable User Halt Enable in the debug control register.
+ */
+wdbg_uhe:
+       .word   0x2c80  /* DR0 */
+       .word   0x00b0  /* 31:16 */
+       .word   0x0400  /* 15:0 -- enable UHE */
+       .word   0x0000  /* unused */
+#endif
+
+
diff --git a/arch/m68k/include/asm/mcfdspi.h b/arch/m68k/include/asm/mcfdspi.h
new file mode 100644 (file)
index 0000000..2bef5d5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * mcfdspi.h-DSPI controller for the ColdFire processors.
+ *
+ * Andrey Butok
+ * Copyright Freescale Semiconductor, Inc. 2008
+ *
+ *    This file is based on mcfqspi.h
+ *
+ * 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
+ *
+ ***************************************************************************
+ * Changes:
+ *   v0.001    25 March 2008           Andrey Butok
+ *             Initial Release - developed on uClinux with 2.6.23 kernel.
+ *
+ */
+
+#ifndef MCFDSPI_H_
+#define MCFDSPI_H_
+
+struct coldfire_dspi_chip {
+       u8 mode;
+       u8 bits_per_word;
+       u16 void_write_data;
+       /* Only used in master mode */
+       u8 dbr;         /* Double baud rate */
+       u8 pbr;         /* Baud rate prescaler */
+       u8 br;          /* Baud rate scaler */
+       u8 pcssck;      /* PCS to SCK delay prescaler */
+       u8 pasc;        /* After SCK delay prescaler */
+       u8 pdt;         /* Delay after transfer prescaler */
+       u8 cssck;       /* PCS to SCK delay scaler */
+       u8 asc;         /* After SCK delay scaler */
+       u8 dt;          /* Delay after transfer scaler */
+};
+#endif /*MCFDSPI_H_*/
index 6901fd68165bd333b79b3dc1dc113b7a15275f72..e0617b3f9a14793232237581d3d80530dea5285d 100644 (file)
 #define        mcfsim_h
 /****************************************************************************/
 
+#if defined(CONFIG_COLDFIRE)
+#include <asm/coldfire.h>
+#endif
+
 /*
  * Include the appropriate ColdFire CPU specific System Integration Module
  * (SIM) definitions.