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