1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #include <linux/linkage.h> 2 #include <linux/linkage.h> 3 #include <linux/kexec.h> << 4 3 5 #include <asm/assembly.h> << 6 #include <asm/asm-offsets.h> 4 #include <asm/asm-offsets.h> 7 #include <asm/page.h> 5 #include <asm/page.h> 8 #include <asm/setup.h> 6 #include <asm/setup.h> 9 #include <asm/psw.h> << 10 7 11 .level PA_ASM_LEVEL << 12 8 13 .macro kexec_param name !! 9 #define MMU_BASE 8 /* MMU flags base in cpu_mmu_flags */ 14 .align 8 << 15 ENTRY(kexec\()_\name) << 16 #ifdef CONFIG_64BIT << 17 .dword 0 << 18 #else << 19 .word 0 << 20 #endif << 21 << 22 ENTRY(kexec\()_\name\()_offset) << 23 .word kexec\()_\name - relocate_new_ke << 24 .endm << 25 10 26 .text 11 .text 27 12 28 /* args: !! 13 ENTRY(relocate_new_kernel) 29 * r26 - kimage->head !! 14 movel %sp@(4),%a0 /* a0 = ptr */ 30 * r25 - start address of kernel !! 15 movel %sp@(8),%a1 /* a1 = start */ 31 * r24 - physical address of relocate code !! 16 movel %sp@(12),%d1 /* d1 = cpu_mmu_flags */ 32 */ !! 17 movew #PAGE_MASK,%d2 /* d2 = PAGE_MASK */ 33 !! 18 34 ENTRY_CFI(relocate_new_kernel) !! 19 /* Disable MMU */ 35 0: copy %arg1, %rp !! 20 36 /* disable I and Q bit, so we are allo !! 21 btst #MMU_BASE + MMUB_68851,%d1 37 rsm PSW_SM_I, %r0 !! 22 jeq 3f 38 nop !! 23 39 nop !! 24 1: /* 68851 or 68030 */ 40 nop !! 25 41 nop !! 26 lea %pc@(.Lcopy),%a4 42 nop !! 27 2: addl #0x00000000,%a4 /* virt_to_phys() */ 43 nop !! 28 44 nop !! 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 45 79 46 rsm PSW_SM_Q, %r0 !! 80 .Lcopy: 47 nop !! 81 movel %a0@+,%d0 /* d0 = entry = *ptr */ 48 nop !! 82 jeq .Lflush 49 nop << 50 nop << 51 nop << 52 nop << 53 nop << 54 83 55 /* !! 84 btst #2,%d0 /* entry & IND_DONE? */ 56 * After return-from-interrupt, we wan !! 85 jne .Lflush 57 * translation enabled just like on a << 58 */ << 59 << 60 /* calculate new physical execution ad << 61 ldo 1f-0b(%arg2), %r1 << 62 mtctl %r0, %cr17 /* IIASQ */ << 63 mtctl %r0, %cr17 /* IIASQ */ << 64 mtctl %r1, %cr18 /* IIAOQ */ << 65 ldo 4(%r1),%r1 << 66 mtctl %r1, %cr18 /* IIAOQ */ << 67 #ifdef CONFIG_64BIT << 68 depdi,z 1, PSW_W_BIT, 1, %r1 << 69 mtctl %r1, %cr22 /* IPSW */ << 70 #else << 71 mtctl %r0, %cr22 /* IPSW */ << 72 #endif << 73 /* lets go... */ << 74 rfi << 75 1: nop << 76 nop << 77 86 78 .Lloop: !! 87 btst #1,%d0 /* entry & IND_INDIRECTION? */ 79 LDREG,ma REG_SZ(%arg0), %r3 !! 88 jeq 1f 80 /* If crash kernel, no copy needed */ !! 89 andw %d2,%d0 81 cmpib,COND(=),n 0,%r3,boot !! 90 movel %d0,%a0 /* ptr = entry & PAGE_MASK */ 82 !! 91 jra .Lcopy 83 bb,<,n %r3, 31 - IND_DONE_BIT !! 92 84 bb,>=,n %r3, 31 - IND_INDIRECT !! 93 1: 85 /* indirection, load and restart */ !! 94 btst #0,%d0 /* entry & IND_DESTINATION? */ 86 movb %r3, %arg0, .Lloop !! 95 jeq 2f 87 depi 0, 31, PAGE_SHIFT, %ar !! 96 andw %d2,%d0 88 !! 97 movel %d0,%a2 /* a2 = dst = entry & PAGE_MASK */ 89 .Lnotind: !! 98 jra .Lcopy 90 bb,>=,n %r3, 31 - IND_DESTINAT !! 99 91 b .Lloop !! 100 2: 92 copy %r3, %r20 !! 101 btst #3,%d0 /* entry & IND_SOURCE? */ 93 !! 102 jeq .Lcopy 94 .Lnotdest: !! 103 95 bb,>= %r3, 31 - IND_SOURCE_B !! 104 andw %d2,%d0 96 depi 0, 31, PAGE_SHIFT, %r3 !! 105 movel %d0,%a3 /* a3 = src = entry & PAGE_MASK */ 97 copy %r3, %r21 !! 106 movew #PAGE_SIZE/32 - 1,%d0 /* d0 = PAGE_SIZE/32 - 1 */ 98 !! 107 3: 99 /* copy page */ !! 108 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 100 copy %r0, %r18 !! 109 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 101 zdepi 1, 31 - PAGE_SHIFT, 1, !! 110 movel %a3@+,%a2@+ /* *dst++ = *src++ */ 102 add %r20, %r18, %r17 !! 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 103 153 104 depi 0, 31, PAGE_SHIFT, %r2 !! 154 .Lreincarnate: 105 .Lcopy: !! 155 jmp %a1@ 106 copy %r20, %r12 << 107 LDREG,ma REG_SZ(%r21), %r8 << 108 LDREG,ma REG_SZ(%r21), %r9 << 109 LDREG,ma REG_SZ(%r21), %r10 << 110 LDREG,ma REG_SZ(%r21), %r11 << 111 STREG,ma %r8, REG_SZ(%r20) << 112 STREG,ma %r9, REG_SZ(%r20) << 113 STREG,ma %r10, REG_SZ(%r20) << 114 STREG,ma %r11, REG_SZ(%r20) << 115 << 116 #ifndef CONFIG_64BIT << 117 LDREG,ma REG_SZ(%r21), %r8 << 118 LDREG,ma REG_SZ(%r21), %r9 << 119 LDREG,ma REG_SZ(%r21), %r10 << 120 LDREG,ma REG_SZ(%r21), %r11 << 121 STREG,ma %r8, REG_SZ(%r20) << 122 STREG,ma %r9, REG_SZ(%r20) << 123 STREG,ma %r10, REG_SZ(%r20) << 124 STREG,ma %r11, REG_SZ(%r20) << 125 #endif << 126 << 127 fdc %r0(%r12) << 128 cmpb,COND(<<) %r20,%r17,.Lcopy << 129 fic (%sr4, %r12) << 130 b,n .Lloop << 131 << 132 boot: << 133 mtctl %r0, %cr15 << 134 << 135 LDREG kexec_free_mem-0b(%arg2), %arg << 136 LDREG kexec_cmdline-0b(%arg2), %arg1 << 137 LDREG kexec_initrd_end-0b(%arg2), %a << 138 LDREG kexec_initrd_start-0b(%arg2), << 139 bv,n %r0(%rp) << 140 156 141 ENDPROC_CFI(relocate_new_kernel); !! 157 relocate_new_kernel_end: 142 158 143 ENTRY(relocate_new_kernel_size) 159 ENTRY(relocate_new_kernel_size) 144 .word relocate_new_kernel_size - reloca !! 160 .long relocate_new_kernel_end - relocate_new_kernel 145 << 146 kexec_param cmdline << 147 kexec_param initrd_start << 148 kexec_param initrd_end << 149 kexec_param free_mem <<
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.