blob: 3e09a89067add5a5a5bde1d42d58b390a5ea2baa [file] [log] [blame]
Geert Uytterhoeven7d5f5fa2013-08-20 22:51:47 +02001#include <linux/linkage.h>
2
3#include <asm/asm-offsets.h>
4#include <asm/page.h>
5#include <asm/setup.h>
6
7
8#define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */
9
10.text
11
12ENTRY(relocate_new_kernel)
13 movel %sp@(4),%a0 /* a0 = ptr */
14 movel %sp@(8),%a1 /* a1 = start */
15 movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */
16 movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */
17
18 /* Disable MMU */
19
20 btst #MMU_BASE + MMUB_68851,%d1
21 jeq 3f
22
231: /* 68851 or 68030 */
24
25 lea %pc@(.Lcopy),%a4
262: addl #0x00000000,%a4 /* virt_to_phys() */
27
28 .section ".m68k_fixup","aw"
29 .long M68K_FIXUP_MEMOFFSET, 2b+2
30 .previous
31
32 .chip 68030
33 pmove %tc,%d0 /* Disable MMU */
34 bclr #7,%d0
35 pmove %d0,%tc
36 jmp %a4@ /* Jump to physical .Lcopy */
37 .chip 68k
38
393:
40 btst #MMU_BASE + MMUB_68030,%d1
41 jne 1b
42
43 btst #MMU_BASE + MMUB_68040,%d1
44 jeq 6f
45
464: /* 68040 or 68060 */
47
48 lea %pc@(.Lcont040),%a4
495: addl #0x00000000,%a4 /* virt_to_phys() */
50
51 .section ".m68k_fixup","aw"
52 .long M68K_FIXUP_MEMOFFSET, 5b+2
53 .previous
54
55 movel %a4,%d0
56 andl #0xff000000,%d0
57 orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */
58 .chip 68040
59 movec %d0,%itt0
60 movec %d0,%dtt0
61 .chip 68k
62 jmp %a4@ /* Jump to physical .Lcont040 */
63
64.Lcont040:
65 moveq #0,%d0
66 .chip 68040
67 movec %d0,%tc /* Disable MMU */
68 movec %d0,%itt0
69 movec %d0,%itt1
70 movec %d0,%dtt0
71 movec %d0,%dtt1
72 .chip 68k
73 jra .Lcopy
74
756:
76 btst #MMU_BASE + MMUB_68060,%d1
77 jne 4b
78
79.Lcopy:
80 movel %a0@+,%d0 /* d0 = entry = *ptr */
81 jeq .Lflush
82
83 btst #2,%d0 /* entry & IND_DONE? */
84 jne .Lflush
85
86 btst #1,%d0 /* entry & IND_INDIRECTION? */
87 jeq 1f
88 andw %d2,%d0
89 movel %d0,%a0 /* ptr = entry & PAGE_MASK */
90 jra .Lcopy
91
921:
93 btst #0,%d0 /* entry & IND_DESTINATION? */
94 jeq 2f
95 andw %d2,%d0
96 movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */
97 jra .Lcopy
98
992:
100 btst #3,%d0 /* entry & IND_SOURCE? */
101 jeq .Lcopy
102
103 andw %d2,%d0
104 movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */
105 movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */
1063:
107 movel %a3@+,%a2@+ /* *dst++ = *src++ */
108 movel %a3@+,%a2@+ /* *dst++ = *src++ */
109 movel %a3@+,%a2@+ /* *dst++ = *src++ */
110 movel %a3@+,%a2@+ /* *dst++ = *src++ */
111 movel %a3@+,%a2@+ /* *dst++ = *src++ */
112 movel %a3@+,%a2@+ /* *dst++ = *src++ */
113 movel %a3@+,%a2@+ /* *dst++ = *src++ */
114 movel %a3@+,%a2@+ /* *dst++ = *src++ */
115 dbf %d0, 3b
116 jra .Lcopy
117
118.Lflush:
119 /* Flush all caches */
120
121 btst #CPUB_68020,%d1
122 jeq 2f
123
1241: /* 68020 or 68030 */
125 .chip 68030
126 movec %cacr,%d0
127 orw #0x808,%d0
128 movec %d0,%cacr
129 .chip 68k
130 jra .Lreincarnate
131
1322:
133 btst #CPUB_68030,%d1
134 jne 1b
135
136 btst #CPUB_68040,%d1
137 jeq 4f
138
1393: /* 68040 or 68060 */
140 .chip 68040
141 nop
142 cpusha %bc
143 nop
144 cinva %bc
145 nop
146 .chip 68k
147 jra .Lreincarnate
148
1494:
150 btst #CPUB_68060,%d1
151 jne 3b
152
153.Lreincarnate:
154 jmp %a1@
155
156relocate_new_kernel_end:
157
158ENTRY(relocate_new_kernel_size)
159 .long relocate_new_kernel_end - relocate_new_kernel