Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | /* 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),%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 |