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