160 lines · 2.8 KB · Assembly
RawDownload
/* 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),%a42:	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),%a45:	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