relayd: move the interface fixup to the right place
[openwrt.git] / target / linux / coldfire / files-2.6.31 / arch / m68k / coldfire / common / head.S
1 /*
2  *  head.S is the MMU enabled ColdFire specific initial boot code
3  *
4  *  Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
5  *  Matt Waddel Matt.Waddel@freescale.com
6  *  Kurt Mahan kmahan@freescale.com
7  *  Jason Jin Jason.Jin@freescale.com
8  *  Shrek Wu B16972@freescale.com
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  Parts of this code came from arch/m68k/kernel/head.S
16  */
17 #include <linux/linkage.h>
18 #include <linux/init.h>
19 #include <asm/bootinfo.h>
20 #include <asm/setup.h>
21 #include <asm/entry.h>
22 #include <asm/pgtable.h>
23 #include <asm/page.h>
24 #include <asm/coldfire.h>
25 #include <asm/cfcache.h>
26
27 #define DEBUG
28
29 .globl kernel_pg_dir
30 .globl availmem
31 .globl set_context
32 .globl set_fpga
33
34 #ifdef DEBUG
35 /* When debugging use readable names for labels */
36 #ifdef __STDC__
37 #define L(name) .head.S.##name
38 #else
39 #define L(name) .head.S./**/name
40 #endif
41 #else
42 #ifdef __STDC__
43 #define L(name) .L##name
44 #else
45 #define L(name) .L/**/name
46 #endif
47 #endif
48
49 /* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
50 #ifndef __INITDATA
51 #define __INITDATA      .data
52 #define __FINIT         .previous
53 #endif
54
55 #if CONFIG_SDRAM_BASE != PAGE_OFFSET
56 /*
57  * Kernel mapped to virtual ram address.
58  *
59  * M5445x:
60  *    Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
61  *    Data[1]: 0xA0000000 -> 0xAFFFFFFF PCI
62  *    Code[0]: Not Mapped
63  *    Code[1]: Not Mapped
64  *
65  * M547x/M548x
66  *    Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
67  *    Data[1]: Not Mapped
68  *    Code[0]: Not Mapped
69  *    Code[1]: Not Mapped
70  */
71 #if defined(CONFIG_M5445X)
72 #define ACR0_DEFAULT    #0xF00FA048   /* System regs */
73 #define ACR1_DEFAULT    #0xA00FA048   /* PCI */
74 #define ACR2_DEFAULT    #0x00000000   /* Not Mapped */
75 #define ACR3_DEFAULT    #0x00000000   /* Not Mapped */
76 #elif defined(CONFIG_M547X_8X)
77 #define ACR0_DEFAULT    #0xF00FA048   /* System Regs */
78 #define ACR1_DEFAULT    #0x00000000   /* Not Mapped */
79 #define ACR2_DEFAULT    #0x00000000   /* Not Mapped */
80 #define ACR3_DEFAULT    #0x00000000   /* Not Mapped */
81 #endif
82
83 #else /* CONFIG_SDRAM_BASE = PAGE_OFFSET */
84 /*
85  * Kernel mapped to physical ram address.
86  *
87  * M5445x:
88  *    Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
89  *    Data[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - uncached
90  *    Code[0]: Not Mapped
91  *    Code[1]: 0x40000000 -> 0x4FFFFFFF SDRAM - cached
92  *
93  * M547x/M548x
94  *    Data[0]: 0xF0000000 -> 0xFFFFFFFF System regs
95  *    Data[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - uncached
96  *    Code[0]: Not Mapped
97  *    Code[1]: 0x00000000 -> 0x0FFFFFFF SDRAM - cached
98  */
99 #if defined(CONFIG_M5445X)
100 #define ACR0_DEFAULT    #0xF00FA048   /* System Regs uncached/precise */
101 #define ACR1_DEFAULT    #0x400FA028   /* SDRAM cached/copyback */
102 #define ACR2_DEFAULT    #0x00000000   /* Not mapped */
103 #define ACR3_DEFAULT    #0x400FA028   /* SDRAM cached/copyback */
104 #elif defined(CONFIG_M547X_8X)
105 #define ACR0_DEFAULT    #0xF00FA048   /* System Regs */
106 #define ACR1_DEFAULT    #0x000FA028   /* SDRAM cached/copy-back */
107 #define ACR2_DEFAULT    #0x00000000   /* Not mapped */
108 #define ACR3_DEFAULT    #0x000FA028   /* Instruction cached/copy-back */
109 #endif
110 #endif
111
112 /* ACR mapping for FPGA (maps 0) */
113 #define ACR0_FPGA       #0x000FA048   /* ACR0 enable FPGA */
114
115 /* Several macros to make the writing of subroutines easier:
116  * - func_start marks the beginning of the routine which setups the frame
117  *   register and saves the registers, it also defines another macro
118  *   to automatically restore the registers again.
119  * - func_return marks the end of the routine and simply calls the prepared
120  *   macro to restore registers and jump back to the caller.
121  * - func_define generates another macro to automatically put arguments
122  *   onto the stack call the subroutine and cleanup the stack again.
123  */
124
125 .macro  load_symbol_address     symbol,register
126         movel   #\symbol,\register
127 .endm
128         
129 .macro  func_start      name,saveregs,savesize,stack=0
130 L(\name):
131         linkw   %a6,#-\stack
132         subal   #(\savesize),%sp
133         moveml  \saveregs,%sp@
134 .set    stackstart,-\stack
135
136 .macro  func_return_\name
137         moveml  %sp@,\saveregs
138         addal   #(\savesize),%sp
139         unlk    %a6
140         rts
141 .endm
142 .endm
143
144 .macro  func_return     name
145         func_return_\name
146 .endm
147
148 .macro  func_call       name
149         jbsr    L(\name)
150 .endm
151
152 .macro  move_stack      nr,arg1,arg2,arg3,arg4
153 .if     \nr
154         move_stack      "(\nr-1)",\arg2,\arg3,\arg4
155         movel   \arg1,%sp@-
156 .endif
157 .endm
158
159 .macro  func_define     name,nr=0
160 .macro  \name   arg1,arg2,arg3,arg4
161         move_stack      \nr,\arg1,\arg2,\arg3,\arg4
162         func_call       \name
163 .if     \nr
164         lea     %sp@(\nr*4),%sp
165 .endif
166 .endm
167 .endm
168
169 func_define     serial_putc,1
170
171 .macro  putc    ch
172         pea     \ch
173         func_call       serial_putc
174         addql   #4,%sp
175 .endm
176
177 .macro  dputc   ch
178 #ifdef DEBUG
179         putc    \ch
180 #endif
181 .endm
182
183 func_define     putn,1
184
185 .macro  dputn   nr
186 #ifdef DEBUG
187         putn    \nr
188 #endif
189 .endm
190
191 /*
192         mmu_map  -  creates a new TLB entry
193
194         virt_addr      Must be on proper boundary
195         phys_addr      Must be on proper boundary
196         itlb           MMUOR_ITLB if instruction TLB or 0
197         asid           address space ID
198         shared_global  MMUTR_SG if shared between different ASIDs or 0
199         size_code      MMUDR_SZ1M  1 MB
200                        MMUDR_SZ4K  4 KB
201                        MMUDR_SZ8K  8 KB
202                        MMUDR_SZ16M 16 MB
203         cache_mode     MMUDR_INC   instruction non-cacheable
204                        MMUDR_IC    instruction cacheable
205                        MMUDR_DWT   data writethrough
206                        MMUDR_DCB   data copyback
207                        MMUDR_DNCP  data non-cacheable, precise
208                        MMUDR_DNCIP data non-cacheable, imprecise
209         super_prot     MMUDR_SP if user mode generates exception or 0
210         readable       MMUDR_R if permits read access (data TLB) or 0
211         writable       MMUDR_W if permits write access (data TLB) or 0
212         executable     MMUDR_X if permits execute access (instruction TLB) or 0
213         locked         MMUDR_LK prevents TLB entry from being replaced or 0
214         temp_data_reg  a data register to use for temporary values
215 */
216 .macro mmu_map  virt_addr,phys_addr,itlb,asid,shared_global,size_code,cache_mode,super_prot,readable,writable,executable,locked,temp_data_reg
217         /* Set up search of TLB. */
218         movel   #(\virt_addr+1), \temp_data_reg
219         movel   \temp_data_reg, MMUAR
220         /* Search.  */
221         movel   #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
222         movew   \temp_data_reg, (MMUOR)
223         /* Set up tag value.  */
224         movel   #(\virt_addr + \asid + \shared_global + MMUTR_V), \temp_data_reg
225         movel   \temp_data_reg, MMUTR
226         /* Set up data value.  */
227         movel   #(\phys_addr + \size_code + \cache_mode + \super_prot + \readable + \writable + \executable + \locked), \temp_data_reg
228         movel   \temp_data_reg, MMUDR
229         /* Save it.  */
230         movel   #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
231         movew   \temp_data_reg, (MMUOR)
232 .endm   /* mmu_map */
233
234 .macro mmu_unmap        virt_addr,itlb,temp_data_reg
235         /* Set up search of TLB. */
236         movel   #(\virt_addr+1), \temp_data_reg
237         movel   \temp_data_reg, MMUAR
238         /* Search.  */
239         movel   #(MMUOR_STLB + MMUOR_ADR +\itlb), \temp_data_reg
240         movew   \temp_data_reg, (MMUOR)
241         /* Test for hit.  */
242         movel   MMUSR,\temp_data_reg
243         btst    #MMUSR_HITN,\temp_data_reg
244         beq     1f
245         /* Read the TLB.  */
246         movel   #(MMUOR_RW + MMUOR_ACC +\itlb), \temp_data_reg
247         movew   \temp_data_reg, (MMUOR)
248         movel   MMUSR,\temp_data_reg
249         /* Set up tag value.  */
250         movel   #0, \temp_data_reg
251         movel   \temp_data_reg, MMUTR
252         /* Set up data value.  */
253         movel   #0, \temp_data_reg
254         movel   \temp_data_reg, MMUDR
255         /* Save it.  */
256         movel   #(MMUOR_ACC + MMUOR_UAA + \itlb), \temp_data_reg
257         movew   \temp_data_reg, (MMUOR)
258 1:      
259 .endm   /* mmu_unmap */
260
261 /* .text */
262 .section ".text.head","ax"
263 ENTRY(_stext)
264 /* Version numbers of the bootinfo interface -- if we later pass info
265  * from boot ROM we might want to put something real here.
266  *
267  * The area from _stext to _start will later be used as kernel pointer table
268  */
269         bras    1f      /* Jump over bootinfo version numbers */
270
271         .long   BOOTINFOV_MAGIC
272         .long   0
273 1:      jmp     __start
274
275 .equ    kernel_pg_dir,_stext
276 .equ    .,_stext+0x1000
277
278 ENTRY(_start)
279         jra     __start
280 __INIT
281 ENTRY(__start)
282 /* Save the location of u-boot info - cmd line, bd_info, etc. */
283         movel   %a7,%a4         /* Don't use %a4 before cf_early_init */
284         addl    #0x00000004,%a4 /* offset past top */
285         addl    #(PAGE_OFFSET-CONFIG_SDRAM_BASE),%a4    /* high mem offset */
286
287 /* Setup initial stack pointer */
288         movel   #CONFIG_SDRAM_BASE+0x1000,%sp
289
290 /* Setup usp */
291         subl    %a0,%a0
292         movel   %a0,%usp
293
294 #if defined(CONFIG_M5445X)
295 #if defined(CONFIG_SRAM)
296         movel   #(CONFIG_SRAM_BASE+0x221), %d0
297 #else
298         movel   #0x80000000, %d0
299 #endif
300         movec   %d0, %rambar1
301 #elif defined(CONFIG_M547X_8X)
302         movel   #MCF_MBAR, %d0
303         movec   %d0, %mbar
304         move.l  #(MCF_RAMBAR0 + 0x21), %d0
305         movec   %d0, %rambar0
306         move.l  #(MCF_RAMBAR1 + 0x21), %d0
307         movec   %d0, %rambar1
308 #endif
309
310         movew   #0x2700,%sr
311
312 /* reset cache */
313         movel   #(CF_CACR_ICINVA + CF_CACR_DCINVA),%d0
314         movecl  %d0,%cacr
315
316         movel   #(MMU_BASE+1),%d0
317         movecl  %d0,%mmubar
318         movel   #MMUOR_CA,%a0                   /* Clear tlb entries */
319         movew   %a0,(MMUOR)
320         movel   #(MMUOR_CA + MMUOR_ITLB),%a0    /* Use ITLB for searches */
321         movew   %a0,(MMUOR)
322         movel   #0,%a0                          /* Clear Addr Space User ID */
323         movecl  %a0,%asid 
324
325 /* setup ACRs */
326         movel   ACR0_DEFAULT, %d0               /* ACR0 (DATA) setup */
327         movec   %d0, %acr0
328         nop
329         movel   ACR1_DEFAULT, %d0               /* ACR1 (DATA) setup */
330         movec   %d0, %acr1
331         nop
332         movel   ACR2_DEFAULT, %d0               /* ACR2 (CODE) setup */
333         movec   %d0, %acr2
334         nop
335         movel   ACR3_DEFAULT, %d0               /* ACR3 (CODE) setup */
336         movec   %d0, %acr3
337         nop
338
339         /* If you change the memory size to another value make a matching 
340            change in paging_init(cf-mmu.c) to zones_size[]. */
341
342 #if CONFIG_SDRAM_BASE != PAGE_OFFSET
343 #if defined(CONFIG_M5445X)
344         /* Map 256MB as code */
345         mmu_map (PAGE_OFFSET+0*0x1000000),  (PHYS_OFFSET+0*0x1000000), \
346                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
347                 0, 0, MMUDR_X, MMUDR_LK, %d0
348         mmu_map (PAGE_OFFSET+1*0x1000000),  (PHYS_OFFSET+1*0x1000000), \
349                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
350                 0, 0, MMUDR_X, MMUDR_LK, %d0
351         mmu_map (PAGE_OFFSET+2*0x1000000),  (PHYS_OFFSET+2*0x1000000), \
352                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
353                 0, 0, MMUDR_X, MMUDR_LK, %d0
354         mmu_map (PAGE_OFFSET+3*0x1000000),  (PHYS_OFFSET+3*0x1000000), \
355                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
356                 0, 0, MMUDR_X, MMUDR_LK, %d0
357         mmu_map (PAGE_OFFSET+4*0x1000000),  (PHYS_OFFSET+4*0x1000000), \
358                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
359                 0, 0, MMUDR_X, MMUDR_LK, %d0
360         mmu_map (PAGE_OFFSET+5*0x1000000),  (PHYS_OFFSET+5*0x1000000), \
361                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
362                 0, 0, MMUDR_X, MMUDR_LK, %d0
363         mmu_map (PAGE_OFFSET+6*0x1000000),  (PHYS_OFFSET+6*0x1000000), \
364                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
365                 0, 0, MMUDR_X, MMUDR_LK, %d0
366         mmu_map (PAGE_OFFSET+7*0x1000000),  (PHYS_OFFSET+7*0x1000000), \
367                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
368                 0, 0, MMUDR_X, MMUDR_LK, %d0
369         mmu_map (PAGE_OFFSET+8*0x1000000),  (PHYS_OFFSET+8*0x1000000), \
370                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
371                 0, 0, MMUDR_X, MMUDR_LK, %d0
372         mmu_map (PAGE_OFFSET+9*0x1000000),  (PHYS_OFFSET+9*0x1000000), \
373                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
374                 0, 0, MMUDR_X, MMUDR_LK, %d0
375         mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), \
376                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
377                 0, 0, MMUDR_X, MMUDR_LK, %d0
378         mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), \
379                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
380                 0, 0, MMUDR_X, MMUDR_LK, %d0
381         mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), \
382                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
383                 0, 0, MMUDR_X, MMUDR_LK, %d0
384         mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), \
385                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
386                 0, 0, MMUDR_X, MMUDR_LK, %d0
387         mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), \
388                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
389                 0, 0, MMUDR_X, MMUDR_LK, %d0
390         mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), \
391                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_IC,  MMUDR_SP, \
392                 0, 0, MMUDR_X, MMUDR_LK, %d0
393
394         /* Map 256MB as data also */
395         mmu_map (PAGE_OFFSET+0*0x1000000),  (PHYS_OFFSET+0*0x1000000), 0, 0, \
396                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
397                 0, MMUDR_LK, %d0
398         mmu_map (PAGE_OFFSET+1*0x1000000),  (PHYS_OFFSET+1*0x1000000), 0, 0, \
399                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
400                 0, MMUDR_LK, %d0
401         mmu_map (PAGE_OFFSET+2*0x1000000),  (PHYS_OFFSET+2*0x1000000), 0, 0, \
402                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
403                 0, MMUDR_LK, %d0
404         mmu_map (PAGE_OFFSET+3*0x1000000),  (PHYS_OFFSET+3*0x1000000), 0, 0, \
405                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
406                 0, MMUDR_LK, %d0
407         mmu_map (PAGE_OFFSET+4*0x1000000),  (PHYS_OFFSET+4*0x1000000), 0, 0, \
408                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
409                 0, MMUDR_LK, %d0
410         mmu_map (PAGE_OFFSET+5*0x1000000),  (PHYS_OFFSET+5*0x1000000), 0, 0, \
411                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
412                 0, MMUDR_LK, %d0
413         mmu_map (PAGE_OFFSET+6*0x1000000),  (PHYS_OFFSET+6*0x1000000), 0, 0, \
414                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
415                 0, MMUDR_LK, %d0
416         mmu_map (PAGE_OFFSET+7*0x1000000),  (PHYS_OFFSET+7*0x1000000), 0, 0, \
417                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
418                 0, MMUDR_LK, %d0
419         mmu_map (PAGE_OFFSET+8*0x1000000),  (PHYS_OFFSET+8*0x1000000), 0, 0, \
420                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
421                 0, MMUDR_LK, %d0
422         mmu_map (PAGE_OFFSET+9*0x1000000),  (PHYS_OFFSET+9*0x1000000), 0, 0, \
423                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
424                 0, MMUDR_LK, %d0
425         mmu_map (PAGE_OFFSET+10*0x1000000), (PHYS_OFFSET+10*0x1000000), 0, 0, \
426                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
427                 0, MMUDR_LK, %d0
428         mmu_map (PAGE_OFFSET+11*0x1000000), (PHYS_OFFSET+11*0x1000000), 0, 0, \
429                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
430                 0, MMUDR_LK, %d0
431         mmu_map (PAGE_OFFSET+12*0x1000000), (PHYS_OFFSET+12*0x1000000), 0, 0, \
432                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
433                 0, MMUDR_LK, %d0
434         mmu_map (PAGE_OFFSET+13*0x1000000), (PHYS_OFFSET+13*0x1000000), 0, 0, \
435                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
436                 0, MMUDR_LK, %d0
437         mmu_map (PAGE_OFFSET+14*0x1000000), (PHYS_OFFSET+14*0x1000000), 0, 0, \
438                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
439                 0, MMUDR_LK, %d0
440         mmu_map (PAGE_OFFSET+15*0x1000000), (PHYS_OFFSET+15*0x1000000), 0, 0, \
441                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
442                 0, MMUDR_LK, %d0
443
444         /* Map ATA registers -- sacrifice a data TLB due to the hw design */
445         mmu_map (0x90000000), (0x90000000), 0, 0, \
446                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
447                 0, MMUDR_LK, %d0
448
449 #elif defined(CONFIG_M547X_8X)
450
451         /* Map first 8 MB as code */
452         mmu_map (PAGE_OFFSET+0*1024*1024),  (0*1024*1024), MMUOR_ITLB, 0, \
453                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
454                 MMUDR_LK, %d0
455         mmu_map (PAGE_OFFSET+1*1024*1024),  (1*1024*1024), MMUOR_ITLB, 0, \
456                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
457                 MMUDR_LK, %d0
458         mmu_map (PAGE_OFFSET+2*1024*1024),  (2*1024*1024), MMUOR_ITLB, 0, \
459                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
460                 MMUDR_LK, %d0
461         mmu_map (PAGE_OFFSET+3*1024*1024),  (3*1024*1024), MMUOR_ITLB, 0, \
462                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
463                 MMUDR_LK, %d0
464         mmu_map (PAGE_OFFSET+4*1024*1024),  (4*1024*1024), MMUOR_ITLB, 0, \
465                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
466                 MMUDR_LK, %d0
467         mmu_map (PAGE_OFFSET+5*1024*1024),  (5*1024*1024), MMUOR_ITLB, 0, \
468                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
469                 MMUDR_LK, %d0
470         mmu_map (PAGE_OFFSET+6*1024*1024),  (6*1024*1024), MMUOR_ITLB, 0, \
471                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
472                 MMUDR_LK, %d0
473         mmu_map (PAGE_OFFSET+7*1024*1024),  (7*1024*1024), MMUOR_ITLB, 0, \
474                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, MMUDR_X, \
475                 MMUDR_LK, %d0
476
477         /* Map first 8 MB as data */
478         mmu_map (PAGE_OFFSET+0*1024*1024),  (0*1024*1024), 0, 0, \
479                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
480                 MMUDR_W, 0, MMUDR_LK, %d0
481         mmu_map (PAGE_OFFSET+1*1024*1024),  (1*1024*1024), 0, 0, \
482                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
483                 MMUDR_W, 0, MMUDR_LK, %d0
484         mmu_map (PAGE_OFFSET+2*1024*1024),  (2*1024*1024), 0, 0, \
485                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
486                 MMUDR_W, 0, MMUDR_LK, %d0
487         mmu_map (PAGE_OFFSET+3*1024*1024),  (3*1024*1024), 0, 0, \
488                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
489                 MMUDR_W, 0, MMUDR_LK, %d0
490         mmu_map (PAGE_OFFSET+4*1024*1024),  (4*1024*1024), 0, 0, \
491                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
492                 MMUDR_W, 0, MMUDR_LK, %d0
493         mmu_map (PAGE_OFFSET+5*1024*1024),  (5*1024*1024), 0, 0, \
494                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
495                 MMUDR_W, 0, MMUDR_LK, %d0
496         mmu_map (PAGE_OFFSET+6*1024*1024),  (6*1024*1024), 0, 0, \
497                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
498                 MMUDR_W, 0, MMUDR_LK, %d0
499         mmu_map (PAGE_OFFSET+7*1024*1024),  (7*1024*1024), 0, 0, \
500                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
501                 MMUDR_W, 0, MMUDR_LK, %d0
502 #endif
503         /*
504          * Do unity mapping to enable the MMU.  Map first chunk of memory
505          * in place as code/data.  The TLBs will be deleted after the MMU is
506          * enabled and we are executing in high memory.
507          */
508
509 #if defined(CONFIG_M5445X)
510         /* Map first 16 MB as code */
511         mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), \
512                 MMUOR_ITLB, 0, MMUTR_SG, MMUDR_SZ16M, MMUDR_INC,  MMUDR_SP, 0, \
513                 0, MMUDR_X, 0, %d0
514         /* Map first 16 MB as data too  */
515         mmu_map (PHYS_OFFSET+0*0x1000000), (PHYS_OFFSET+0*0x1000000), 0, 0, \
516                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
517                 0, 0, %d0
518 #elif defined(CONFIG_M547X_8X)
519         /* Map first 4 MB as code */
520         mmu_map (0*1024*1024), (0*1024*1024), MMUOR_ITLB, 0, \
521                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
522                 MMUDR_X, 0, %d0
523         mmu_map (1*1024*1024), (1*1024*1024), MMUOR_ITLB, 0, \
524                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
525                 MMUDR_X, 0, %d0
526         mmu_map (2*1024*1024), (2*1024*1024), MMUOR_ITLB, 0, \
527                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
528                 MMUDR_X, 0, %d0
529         mmu_map (3*1024*1024), (3*1024*1024), MMUOR_ITLB, 0, \
530                 MMUTR_SG, MMUDR_SZ1M, MMUDR_IC,  MMUDR_SP, 0, 0, \
531                 MMUDR_X, 0, %d0
532
533         /* Map first 4 MB as data too */
534         mmu_map (0*1024*1024), (0*1024*1024), 0, 0, \
535                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
536                 MMUDR_W, 0, 0, %d0
537         mmu_map (1*1024*1024), (1*1024*1024), 0, 0, \
538                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
539                 MMUDR_W, 0, 0, %d0
540         mmu_map (2*1024*1024), (2*1024*1024), 0, 0, \
541                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
542                 MMUDR_W, 0, 0, %d0
543         mmu_map (3*1024*1024), (3*1024*1024), 0, 0, \
544                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DCB, MMUDR_SP, MMUDR_R, \
545                 MMUDR_W, 0, 0, %d0
546 #endif
547 #endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
548
549         /* Turn on MMU */
550         movel   #(MMUCR_EN),%a0
551         movel   %a0,MMUCR
552         nop     /* This synchs the pipeline after a write to MMUCR */
553
554         movel   #__running_high,%a0  /* Get around PC-relative addressing. */
555         jmp     %a0@
556
557 ENTRY(__running_high)
558         load_symbol_address _stext,%sp
559         movel   L(memory_start),%a0
560         movel   %a0,availmem
561         load_symbol_address L(phys_kernel_start),%a0
562         load_symbol_address _stext,%a1
563         subl    #_stext,%a1
564         addl    #PAGE_OFFSET,%a1
565         movel   %a1,%a0@
566
567 /* zero bss */
568         lea     _sbss,%a0
569         lea     _ebss,%a1
570         clrl    %d0
571 _loop_bss:
572         movel   %d0,(%a0)+
573         cmpl    %a0,%a1
574         bne     _loop_bss
575
576         /* Unmap unity mappings */
577 #if CONFIG_SDRAM_BASE != PAGE_OFFSET
578 #if defined(CONFIG_M5445X)
579         mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
580         mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
581 #elif defined(CONFIG_M547X_8X)
582         mmu_unmap (PHYS_OFFSET+0*0x1000000), MMUOR_ITLB, %d0
583         mmu_unmap (PHYS_OFFSET+1*0x1000000), MMUOR_ITLB, %d0
584         mmu_unmap (PHYS_OFFSET+2*0x1000000), MMUOR_ITLB, %d0
585         mmu_unmap (PHYS_OFFSET+3*0x1000000), MMUOR_ITLB, %d0
586         mmu_unmap (PHYS_OFFSET+0*0x1000000), 0, %d0
587         mmu_unmap (PHYS_OFFSET+1*0x1000000), 0, %d0
588         mmu_unmap (PHYS_OFFSET+2*0x1000000), 0, %d0
589         mmu_unmap (PHYS_OFFSET+3*0x1000000), 0, %d0
590 #endif
591 #endif /* CONFIG_SDRAM_BASE != PAGE_OFFSET */
592
593 /* create dma memory mirror TLB mapping */
594 #if defined(CONFIG_M5445X)
595         mmu_map CONFIG_DMA_BASE, \
596                 CONFIG_SDRAM_BASE, 0, 0, \
597                 MMUTR_SG, MMUDR_SZ16M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, MMUDR_W, \
598                 0, MMUDR_LK, %d0
599 #elif defined(CONFIG_M547X_8X)
600         mmu_map (CONFIG_DMA_BASE + 0*1024*1024), \
601                 (CONFIG_SDRAM_BASE + 0*1024*1024), 0, 0, \
602                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
603                 MMUDR_W, 0, MMUDR_LK, %d0
604         mmu_map (CONFIG_DMA_BASE + 1*1024*1024), \
605                 (CONFIG_SDRAM_BASE + 1*1024*1024), 0, 0, \
606                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
607                 MMUDR_W, 0, MMUDR_LK, %d0
608         mmu_map (CONFIG_DMA_BASE + 2*1024*1024), \
609                 (CONFIG_SDRAM_BASE + 2*1024*1024), 0, 0, \
610                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
611                 MMUDR_W, 0, MMUDR_LK, %d0
612         mmu_map (CONFIG_DMA_BASE + 3*1024*1024), \
613                 (CONFIG_SDRAM_BASE + 3*1024*1024), 0, 0, \
614                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
615                 MMUDR_W, 0, MMUDR_LK, %d0
616         mmu_map (CONFIG_DMA_BASE + 4*1024*1024), \
617                 (CONFIG_SDRAM_BASE + 4*1024*1024), 0, 0, \
618                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
619                 MMUDR_W, 0, MMUDR_LK, %d0
620         mmu_map (CONFIG_DMA_BASE + 5*1024*1024), \
621                 (CONFIG_SDRAM_BASE + 5*1024*1024), 0, 0, \
622                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
623                 MMUDR_W, 0, MMUDR_LK, %d0
624         mmu_map (CONFIG_DMA_BASE + 6*1024*1024), \
625                 (CONFIG_SDRAM_BASE + 6*1024*1024), 0, 0, \
626                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
627                 MMUDR_W, 0, MMUDR_LK, %d0
628         mmu_map (CONFIG_DMA_BASE + 7*1024*1024), \
629                 (CONFIG_SDRAM_BASE + 7*1024*1024), 0, 0, \
630                 MMUTR_SG, MMUDR_SZ1M, MMUDR_DNCP, MMUDR_SP, MMUDR_R, \
631                 MMUDR_W, 0, MMUDR_LK, %d0
632 #endif
633
634 /* Setup initial stack pointer */
635         lea     init_task,%a2 
636         lea     init_thread_union+THREAD_SIZE,%sp
637         subl    %a6,%a6         /* clear a6 for gdb */
638
639 #ifdef CONFIG_MCF_USER_HALT
640 /* Setup debug control reg to allow halts from user space */
641         lea     wdbg_uhe,%a0
642         wdebug  (%a0)
643 #endif
644
645         movel   %a4,uboot_info_stk /* save uboot info to variable */
646         jsr     cf_early_init
647         jmp     start_kernel
648
649 .section ".text.head","ax"
650 set_context:
651 func_start      set_context,%d0,(1*4)
652         movel   12(%sp),%d0
653         movec   %d0,%asid
654 func_return     set_context
655
656 #ifdef CONFIG_M5445X
657 /*
658  * set_fpga(addr,val) on the M5445X
659  *
660  * Map in 0x00000000 -> 0x0fffffff and then do the write.
661  */
662 set_fpga:
663         movew   %sr,%d1
664         movew   #0x2700,%sr
665         movel   ACR0_FPGA, %d0
666         movec   %d0, %acr0
667         nop
668         moveal  4(%sp),%a0
669         movel   8(%sp),%a0@
670         movel   ACR0_DEFAULT, %d0
671         movec   %d0, %acr0
672         nop
673         movew   %d1,%sr
674         rts
675 #endif
676
677         .data
678         .align  4
679
680 availmem:
681         .long   0
682 L(phys_kernel_start):
683         .long   PAGE_OFFSET
684 L(kernel_end):
685         .long   0
686 L(memory_start):
687         .long   PAGE_OFFSET_RAW
688
689 #ifdef CONFIG_MCF_USER_HALT
690 /*
691  * Enable User Halt Enable in the debug control register.
692  */
693 wdbg_uhe:
694         .word   0x2c80  /* DR0 */
695         .word   0x00b0  /* 31:16 */
696         .word   0x0400  /* 15:0 -- enable UHE */
697         .word   0x0000  /* unused */
698 #endif
699
700