159 lines
		
	
	
	
		
			2.8 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			2.8 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| #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
 | 
