|
@@ -0,0 +1,159 @@
|
|
|
|
+#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
|