1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* << 3 * Copyright IBM Corp. 2005 << 4 * << 5 * Author(s): Rolf Adelsberger << 6 * << 7 */ << 8 << 9 #include <linux/linkage.h> 2 #include <linux/linkage.h> >> 3 >> 4 #include <asm/asm-offsets.h> 10 #include <asm/page.h> 5 #include <asm/page.h> 11 #include <asm/sigp.h> !! 6 #include <asm/setup.h> >> 7 >> 8 >> 9 #define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */ >> 10 >> 11 .text >> 12 >> 13 ENTRY(relocate_new_kernel) >> 14 movel %sp@(4),%a0 /* a0 = ptr */ >> 15 movel %sp@(8),%a1 /* a1 = start */ >> 16 movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */ >> 17 movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */ >> 18 >> 19 /* Disable MMU */ >> 20 >> 21 btst #MMU_BASE + MMUB_68851,%d1 >> 22 jeq 3f >> 23 >> 24 1: /* 68851 or 68030 */ >> 25 >> 26 lea %pc@(.Lcopy),%a4 >> 27 2: addl #0x00000000,%a4 /* virt_to_phys() */ >> 28 >> 29 .section .m68k_fixup,"aw" >> 30 .long M68K_FIXUP_MEMOFFSET, 2b+2 >> 31 .previous >> 32 >> 33 .chip 68030 >> 34 pmove %tc,%d0 /* Disable MMU */ >> 35 bclr #7,%d0 >> 36 pmove %d0,%tc >> 37 jmp %a4@ /* Jump to physical .Lcopy */ >> 38 .chip 68k >> 39 >> 40 3: >> 41 btst #MMU_BASE + MMUB_68030,%d1 >> 42 jne 1b >> 43 >> 44 btst #MMU_BASE + MMUB_68040,%d1 >> 45 jeq 6f >> 46 >> 47 4: /* 68040 or 68060 */ >> 48 >> 49 lea %pc@(.Lcont040),%a4 >> 50 5: addl #0x00000000,%a4 /* virt_to_phys() */ >> 51 >> 52 .section .m68k_fixup,"aw" >> 53 .long M68K_FIXUP_MEMOFFSET, 5b+2 >> 54 .previous >> 55 >> 56 movel %a4,%d0 >> 57 andl #0xff000000,%d0 >> 58 orw #0xe020,%d0 /* Map 16 MiB, enable, cacheable */ >> 59 .chip 68040 >> 60 movec %d0,%itt0 >> 61 movec %d0,%dtt0 >> 62 .chip 68k >> 63 jmp %a4@ /* Jump to physical .Lcont040 */ >> 64 >> 65 .Lcont040: >> 66 moveq #0,%d0 >> 67 .chip 68040 >> 68 movec %d0,%tc /* Disable MMU */ >> 69 movec %d0,%itt0 >> 70 movec %d0,%itt1 >> 71 movec %d0,%dtt0 >> 72 movec %d0,%dtt1 >> 73 .chip 68k >> 74 jra .Lcopy >> 75 >> 76 6: >> 77 btst #MMU_BASE + MMUB_68060,%d1 >> 78 jne 4b >> 79 >> 80 .Lcopy: >> 81 movel %a0@+,%d0 /* d0 = entry = *ptr */ >> 82 jeq .Lflush >> 83 >> 84 btst #2,%d0 /* entry & IND_DONE? */ >> 85 jne .Lflush >> 86 >> 87 btst #1,%d0 /* entry & IND_INDIRECTION? */ >> 88 jeq 1f >> 89 andw %d2,%d0 >> 90 movel %d0,%a0 /* ptr = entry & PAGE_MASK */ >> 91 jra .Lcopy >> 92 >> 93 1: >> 94 btst #0,%d0 /* entry & IND_DESTINATION? */ >> 95 jeq 2f >> 96 andw %d2,%d0 >> 97 movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */ >> 98 jra .Lcopy >> 99 >> 100 2: >> 101 btst #3,%d0 /* entry & IND_SOURCE? */ >> 102 jeq .Lcopy >> 103 >> 104 andw %d2,%d0 >> 105 movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */ >> 106 movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */ >> 107 3: >> 108 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 109 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 110 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 111 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 112 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 113 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 114 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 115 movel %a3@+,%a2@+ /* *dst++ = *src++ */ >> 116 dbf %d0, 3b >> 117 jra .Lcopy >> 118 >> 119 .Lflush: >> 120 /* Flush all caches */ >> 121 >> 122 btst #CPUB_68020,%d1 >> 123 jeq 2f >> 124 >> 125 1: /* 68020 or 68030 */ >> 126 .chip 68030 >> 127 movec %cacr,%d0 >> 128 orw #0x808,%d0 >> 129 movec %d0,%cacr >> 130 .chip 68k >> 131 jra .Lreincarnate >> 132 >> 133 2: >> 134 btst #CPUB_68030,%d1 >> 135 jne 1b >> 136 >> 137 btst #CPUB_68040,%d1 >> 138 jeq 4f >> 139 >> 140 3: /* 68040 or 68060 */ >> 141 .chip 68040 >> 142 nop >> 143 cpusha %bc >> 144 nop >> 145 cinva %bc >> 146 nop >> 147 .chip 68k >> 148 jra .Lreincarnate >> 149 >> 150 4: >> 151 btst #CPUB_68060,%d1 >> 152 jne 3b >> 153 >> 154 .Lreincarnate: >> 155 jmp %a1@ >> 156 >> 157 relocate_new_kernel_end: 12 158 13 /* !! 159 ENTRY(relocate_new_kernel_size) 14 * moves the new kernel to its destination... !! 160 .long relocate_new_kernel_end - relocate_new_kernel 15 * %r2 = pointer to first kimage_entry_t << 16 * %r3 = start address - where to jump to afte << 17 * %r4 = subcode << 18 * << 19 * %r5 will be used as temp. storage << 20 * %r6 holds the destination address << 21 * %r7 = PAGE_SIZE << 22 * %r8 holds the source address << 23 * %r9 = PAGE_SIZE << 24 * << 25 * 0xf000 is a page_mask << 26 */ << 27 << 28 .text << 29 SYM_CODE_START(relocate_kernel) << 30 basr %r13,0 # base address << 31 .base: << 32 lghi %r7,PAGE_SIZE # load PAGE_SI << 33 lghi %r9,PAGE_SIZE # load PAGE_SI << 34 lg %r5,0(%r2) # read another << 35 aghi %r2,8 # increment po << 36 tml %r5,0x1 # is it a dest << 37 je .indir_check # NO, goto "in << 38 lgr %r6,%r5 # r6 = r5 << 39 nill %r6,0xf000 # mask it out << 40 j .base # ...next iter << 41 .indir_check: << 42 tml %r5,0x2 # is it a indi << 43 je .done_test # NO, goto "do << 44 nill %r5,0xf000 # YES, mask ou << 45 lgr %r2,%r5 # move it into << 46 j .base # and read nex << 47 .done_test: << 48 tml %r5,0x4 # is it the do << 49 je .source_test # NO! Well, th << 50 j .done # ok, lets fin << 51 .source_test: << 52 tml %r5,0x8 # it should be << 53 je .base # NO, ignore i << 54 lgr %r8,%r5 # r8 = r5 << 55 nill %r8,0xf000 # masking << 56 0: mvcle %r6,%r8,0x0 # copy PAGE_SI << 57 jo 0b << 58 j .base << 59 .done: << 60 lgr %r0,%r4 # subcode << 61 cghi %r3,0 << 62 je .diag << 63 la %r4,load_psw-.base(%r13) << 64 o %r3,4(%r4) # or load addr << 65 st %r3,4(%r4) << 66 mvc 0(8,%r0),0(%r4) # copy psw to << 67 .diag: << 68 diag %r0,%r0,0x308 << 69 SYM_CODE_END(relocate_kernel) << 70 << 71 .balign 8 << 72 SYM_DATA_START_LOCAL(load_psw) << 73 .long 0x00080000,0x80000000 << 74 SYM_DATA_END_LABEL(load_psw, SYM_L_LOCAL, relo << 75 .balign 8 << 76 SYM_DATA(relocate_kernel_len, .quad relocate_k <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.