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