1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
27d5f5fa2SGeert Uytterhoeven#include <linux/linkage.h>
37d5f5fa2SGeert Uytterhoeven
47d5f5fa2SGeert Uytterhoeven#include <asm/asm-offsets.h>
57d5f5fa2SGeert Uytterhoeven#include <asm/page.h>
67d5f5fa2SGeert Uytterhoeven#include <asm/setup.h>
77d5f5fa2SGeert Uytterhoeven
87d5f5fa2SGeert Uytterhoeven
97d5f5fa2SGeert Uytterhoeven#define MMU_BASE	8		/* MMU flags base in cpu_mmu_flags */
107d5f5fa2SGeert Uytterhoeven
117d5f5fa2SGeert Uytterhoeven.text
127d5f5fa2SGeert Uytterhoeven
137d5f5fa2SGeert UytterhoevenENTRY(relocate_new_kernel)
147d5f5fa2SGeert Uytterhoeven	movel %sp@(4),%a0		/* a0 = ptr */
157d5f5fa2SGeert Uytterhoeven	movel %sp@(8),%a1		/* a1 = start */
167d5f5fa2SGeert Uytterhoeven	movel %sp@(12),%d1		/* d1 = cpu_mmu_flags */
177d5f5fa2SGeert Uytterhoeven	movew #PAGE_MASK,%d2		/* d2 = PAGE_MASK */
187d5f5fa2SGeert Uytterhoeven
197d5f5fa2SGeert Uytterhoeven	/* Disable MMU */
207d5f5fa2SGeert Uytterhoeven
217d5f5fa2SGeert Uytterhoeven	btst #MMU_BASE + MMUB_68851,%d1
227d5f5fa2SGeert Uytterhoeven	jeq 3f
237d5f5fa2SGeert Uytterhoeven
247d5f5fa2SGeert Uytterhoeven1:	/* 68851 or 68030 */
257d5f5fa2SGeert Uytterhoeven
267d5f5fa2SGeert Uytterhoeven	lea %pc@(.Lcopy),%a4
277d5f5fa2SGeert Uytterhoeven2:	addl #0x00000000,%a4		/* virt_to_phys() */
287d5f5fa2SGeert Uytterhoeven
29*922a9bd1SBen Hutchings	.section .m68k_fixup,"aw"
307d5f5fa2SGeert Uytterhoeven	.long M68K_FIXUP_MEMOFFSET, 2b+2
317d5f5fa2SGeert Uytterhoeven	.previous
327d5f5fa2SGeert Uytterhoeven
337d5f5fa2SGeert Uytterhoeven	.chip 68030
347d5f5fa2SGeert Uytterhoeven	pmove %tc,%d0			/* Disable MMU */
357d5f5fa2SGeert Uytterhoeven	bclr #7,%d0
367d5f5fa2SGeert Uytterhoeven	pmove %d0,%tc
377d5f5fa2SGeert Uytterhoeven	jmp %a4@			/* Jump to physical .Lcopy */
387d5f5fa2SGeert Uytterhoeven	.chip 68k
397d5f5fa2SGeert Uytterhoeven
407d5f5fa2SGeert Uytterhoeven3:
417d5f5fa2SGeert Uytterhoeven	btst #MMU_BASE + MMUB_68030,%d1
427d5f5fa2SGeert Uytterhoeven	jne 1b
437d5f5fa2SGeert Uytterhoeven
447d5f5fa2SGeert Uytterhoeven	btst #MMU_BASE + MMUB_68040,%d1
457d5f5fa2SGeert Uytterhoeven	jeq 6f
467d5f5fa2SGeert Uytterhoeven
477d5f5fa2SGeert Uytterhoeven4:	/* 68040 or 68060 */
487d5f5fa2SGeert Uytterhoeven
497d5f5fa2SGeert Uytterhoeven	lea %pc@(.Lcont040),%a4
507d5f5fa2SGeert Uytterhoeven5:	addl #0x00000000,%a4		/* virt_to_phys() */
517d5f5fa2SGeert Uytterhoeven
52*922a9bd1SBen Hutchings	.section .m68k_fixup,"aw"
537d5f5fa2SGeert Uytterhoeven	.long M68K_FIXUP_MEMOFFSET, 5b+2
547d5f5fa2SGeert Uytterhoeven	.previous
557d5f5fa2SGeert Uytterhoeven
567d5f5fa2SGeert Uytterhoeven	movel %a4,%d0
577d5f5fa2SGeert Uytterhoeven	andl #0xff000000,%d0
587d5f5fa2SGeert Uytterhoeven	orw #0xe020,%d0			/* Map 16 MiB, enable, cacheable */
597d5f5fa2SGeert Uytterhoeven	.chip 68040
607d5f5fa2SGeert Uytterhoeven	movec %d0,%itt0
617d5f5fa2SGeert Uytterhoeven	movec %d0,%dtt0
627d5f5fa2SGeert Uytterhoeven	.chip 68k
637d5f5fa2SGeert Uytterhoeven	jmp %a4@			/* Jump to physical .Lcont040 */
647d5f5fa2SGeert Uytterhoeven
657d5f5fa2SGeert Uytterhoeven.Lcont040:
667d5f5fa2SGeert Uytterhoeven	moveq #0,%d0
677d5f5fa2SGeert Uytterhoeven	.chip 68040
687d5f5fa2SGeert Uytterhoeven	movec %d0,%tc			/* Disable MMU */
697d5f5fa2SGeert Uytterhoeven	movec %d0,%itt0
707d5f5fa2SGeert Uytterhoeven	movec %d0,%itt1
717d5f5fa2SGeert Uytterhoeven	movec %d0,%dtt0
727d5f5fa2SGeert Uytterhoeven	movec %d0,%dtt1
737d5f5fa2SGeert Uytterhoeven	.chip 68k
747d5f5fa2SGeert Uytterhoeven	jra .Lcopy
757d5f5fa2SGeert Uytterhoeven
767d5f5fa2SGeert Uytterhoeven6:
777d5f5fa2SGeert Uytterhoeven	btst #MMU_BASE + MMUB_68060,%d1
787d5f5fa2SGeert Uytterhoeven	jne 4b
797d5f5fa2SGeert Uytterhoeven
807d5f5fa2SGeert Uytterhoeven.Lcopy:
817d5f5fa2SGeert Uytterhoeven	movel %a0@+,%d0			/* d0 = entry = *ptr */
827d5f5fa2SGeert Uytterhoeven	jeq .Lflush
837d5f5fa2SGeert Uytterhoeven
847d5f5fa2SGeert Uytterhoeven	btst #2,%d0			/* entry & IND_DONE? */
857d5f5fa2SGeert Uytterhoeven	jne .Lflush
867d5f5fa2SGeert Uytterhoeven
877d5f5fa2SGeert Uytterhoeven	btst #1,%d0			/* entry & IND_INDIRECTION? */
887d5f5fa2SGeert Uytterhoeven	jeq 1f
897d5f5fa2SGeert Uytterhoeven	andw %d2,%d0
907d5f5fa2SGeert Uytterhoeven	movel %d0,%a0			/* ptr = entry & PAGE_MASK */
917d5f5fa2SGeert Uytterhoeven	jra .Lcopy
927d5f5fa2SGeert Uytterhoeven
937d5f5fa2SGeert Uytterhoeven1:
947d5f5fa2SGeert Uytterhoeven	btst #0,%d0			/* entry & IND_DESTINATION? */
957d5f5fa2SGeert Uytterhoeven	jeq 2f
967d5f5fa2SGeert Uytterhoeven	andw %d2,%d0
977d5f5fa2SGeert Uytterhoeven	movel %d0,%a2			/* a2 = dst = entry & PAGE_MASK */
987d5f5fa2SGeert Uytterhoeven	jra .Lcopy
997d5f5fa2SGeert Uytterhoeven
1007d5f5fa2SGeert Uytterhoeven2:
1017d5f5fa2SGeert Uytterhoeven	btst #3,%d0			/* entry & IND_SOURCE? */
1027d5f5fa2SGeert Uytterhoeven	jeq .Lcopy
1037d5f5fa2SGeert Uytterhoeven
1047d5f5fa2SGeert Uytterhoeven	andw %d2,%d0
1057d5f5fa2SGeert Uytterhoeven	movel %d0,%a3			/* a3 = src = entry & PAGE_MASK */
1067d5f5fa2SGeert Uytterhoeven	movew #PAGE_SIZE/32 - 1,%d0	/* d0 = PAGE_SIZE/32 - 1 */
1077d5f5fa2SGeert Uytterhoeven3:
1087d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1097d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1107d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1117d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1127d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1137d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1147d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1157d5f5fa2SGeert Uytterhoeven	movel %a3@+,%a2@+		/* *dst++ = *src++ */
1167d5f5fa2SGeert Uytterhoeven	dbf %d0, 3b
1177d5f5fa2SGeert Uytterhoeven	jra .Lcopy
1187d5f5fa2SGeert Uytterhoeven
1197d5f5fa2SGeert Uytterhoeven.Lflush:
1207d5f5fa2SGeert Uytterhoeven	/* Flush all caches */
1217d5f5fa2SGeert Uytterhoeven
1227d5f5fa2SGeert Uytterhoeven	btst #CPUB_68020,%d1
1237d5f5fa2SGeert Uytterhoeven	jeq 2f
1247d5f5fa2SGeert Uytterhoeven
1257d5f5fa2SGeert Uytterhoeven1:	/* 68020 or 68030 */
1267d5f5fa2SGeert Uytterhoeven	.chip 68030
1277d5f5fa2SGeert Uytterhoeven	movec %cacr,%d0
1287d5f5fa2SGeert Uytterhoeven	orw #0x808,%d0
1297d5f5fa2SGeert Uytterhoeven	movec %d0,%cacr
1307d5f5fa2SGeert Uytterhoeven	.chip 68k
1317d5f5fa2SGeert Uytterhoeven	jra .Lreincarnate
1327d5f5fa2SGeert Uytterhoeven
1337d5f5fa2SGeert Uytterhoeven2:
1347d5f5fa2SGeert Uytterhoeven	btst #CPUB_68030,%d1
1357d5f5fa2SGeert Uytterhoeven	jne 1b
1367d5f5fa2SGeert Uytterhoeven
1377d5f5fa2SGeert Uytterhoeven	btst #CPUB_68040,%d1
1387d5f5fa2SGeert Uytterhoeven	jeq 4f
1397d5f5fa2SGeert Uytterhoeven
1407d5f5fa2SGeert Uytterhoeven3:	/* 68040 or 68060 */
1417d5f5fa2SGeert Uytterhoeven	.chip 68040
1427d5f5fa2SGeert Uytterhoeven	nop
1437d5f5fa2SGeert Uytterhoeven	cpusha %bc
1447d5f5fa2SGeert Uytterhoeven	nop
1457d5f5fa2SGeert Uytterhoeven	cinva %bc
1467d5f5fa2SGeert Uytterhoeven	nop
1477d5f5fa2SGeert Uytterhoeven	.chip 68k
1487d5f5fa2SGeert Uytterhoeven	jra .Lreincarnate
1497d5f5fa2SGeert Uytterhoeven
1507d5f5fa2SGeert Uytterhoeven4:
1517d5f5fa2SGeert Uytterhoeven	btst #CPUB_68060,%d1
1527d5f5fa2SGeert Uytterhoeven	jne 3b
1537d5f5fa2SGeert Uytterhoeven
1547d5f5fa2SGeert Uytterhoeven.Lreincarnate:
1557d5f5fa2SGeert Uytterhoeven	jmp %a1@
1567d5f5fa2SGeert Uytterhoeven
1577d5f5fa2SGeert Uytterhoevenrelocate_new_kernel_end:
1587d5f5fa2SGeert Uytterhoeven
1597d5f5fa2SGeert UytterhoevenENTRY(relocate_new_kernel_size)
1607d5f5fa2SGeert Uytterhoeven	.long relocate_new_kernel_end - relocate_new_kernel
161