mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
2.8 KiB
160 lines
2.8 KiB
/* 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
|
|
|