/* SPDX-License-Identifier: GPL-2.0 */1#include <linux/linkage.h>23#include <asm/asm-offsets.h>4#include <asm/page.h>5#include <asm/setup.h>678#define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */910.text1112ENTRY(relocate_new_kernel)13movel %sp@(4),%a0 /* a0 = ptr */14movel %sp@(8),%a1 /* a1 = start */15movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */16movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */1718/* Disable MMU */1920btst #MMU_BASE + MMUB_68851,%d121jeq 3f22231: /* 68851 or 68030 */2425lea %pc@(.Lcopy),%a4262: addl #0x00000000,%a4 /* virt_to_phys() */2728.section .m68k_fixup,"aw"29.long M68K_FIXUP_MEMOFFSET, 2b+230.previous3132.chip 6803033pmove %tc,%d0 /* Disable MMU */34bclr #7,%d035pmove %d0,%tc36jmp %a4@ /* Jump to physical .Lcopy */37.chip 68k38393:40btst #MMU_BASE + MMUB_68030,%d141jne 1b4243btst #MMU_BASE + MMUB_68040,%d144jeq 6f45464: /* 68040 or 68060 */4748lea %pc@(.Lcont040),%a4495: addl #0x00000000,%a4 /* virt_to_phys() */5051.section .m68k_fixup,"aw"52.long M68K_FIXUP_MEMOFFSET, 5b+253.previous5455movel %a4,%d056andl #0xff000000,%d057orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */58.chip 6804059movec %d0,%itt060movec %d0,%dtt061.chip 68k62jmp %a4@ /* Jump to physical .Lcont040 */6364.Lcont040:65moveq #0,%d066.chip 6804067movec %d0,%tc /* Disable MMU */68movec %d0,%itt069movec %d0,%itt170movec %d0,%dtt071movec %d0,%dtt172.chip 68k73jra .Lcopy74756:76btst #MMU_BASE + MMUB_68060,%d177jne 4b7879.Lcopy:80movel %a0@+,%d0 /* d0 = entry = *ptr */81jeq .Lflush8283btst #2,%d0 /* entry & IND_DONE? */84jne .Lflush8586btst #1,%d0 /* entry & IND_INDIRECTION? */87jeq 1f88andw %d2,%d089movel %d0,%a0 /* ptr = entry & PAGE_MASK */90jra .Lcopy91921:93btst #0,%d0 /* entry & IND_DESTINATION? */94jeq 2f95andw %d2,%d096movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */97jra .Lcopy98992:100btst #3,%d0 /* entry & IND_SOURCE? */101jeq .Lcopy102103andw %d2,%d0104movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */105movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */1063:107movel %a3@+,%a2@+ /* *dst++ = *src++ */108movel %a3@+,%a2@+ /* *dst++ = *src++ */109movel %a3@+,%a2@+ /* *dst++ = *src++ */110movel %a3@+,%a2@+ /* *dst++ = *src++ */111movel %a3@+,%a2@+ /* *dst++ = *src++ */112movel %a3@+,%a2@+ /* *dst++ = *src++ */113movel %a3@+,%a2@+ /* *dst++ = *src++ */114movel %a3@+,%a2@+ /* *dst++ = *src++ */115dbf %d0, 3b116jra .Lcopy117118.Lflush:119/* Flush all caches */120121btst #CPUB_68020,%d1122jeq 2f1231241: /* 68020 or 68030 */125.chip 68030126movec %cacr,%d0127orw #0x808,%d0128movec %d0,%cacr129.chip 68k130jra .Lreincarnate1311322:133btst #CPUB_68030,%d1134jne 1b135136btst #CPUB_68040,%d1137jeq 4f1381393: /* 68040 or 68060 */140.chip 68040141nop142cpusha %bc143nop144cinva %bc145nop146.chip 68k147jra .Lreincarnate1481494:150btst #CPUB_68060,%d1151jne 3b152153.Lreincarnate:154jmp %a1@155156relocate_new_kernel_end:157158ENTRY(relocate_new_kernel_size)159.long relocate_new_kernel_end - relocate_new_kernel160161162