#include "opt_compat_netbsd.h"
#include "opt_compat_sunos.h"
#include "opt_ddb.h"
#include "opt_fpsp.h"
#include "opt_fpu_emulate.h"
#include "opt_m68k_arch.h"
#include "ksyms.h"
#include "assym.h"
#include <machine/asm.h>
#include <machine/trap.h>
.text
GLOBAL(kernel_text)
.data
.space PAGE_SIZE
ASGLOBAL(tmpstk)
.text
#define _RELOC(var, ar) \
lea var-KERNBASE,ar; \
addl %a5,ar
#define RELOC(var, ar) _RELOC(_C_LABEL(var), ar)
#define ASRELOC(var, ar) _RELOC(_ASM_LABEL(var), ar)
BSS(lowram,4)
BSS(esym,4)
.text
ASENTRY_NOPROFILE(start)
movw #PSL_HIGHIPL, %sr | no interrupts
movl #CACHE_OFF, %d0
movc %d0, %cacr | clear and disable on-chip cache(s)
movl #0x20100000, %a5
movl #0x20000000, %a0
RELOC(edata, %a1)
1:
movl %a5@+, %a0@+
cmpl %a5, %a1
bne 1b
movl #0x20000000, %a5
ASRELOC(tmpstk, %a0)
movl %a0, %sp | give ourselves a temporary stack
RELOC(edata, %a0)
RELOC(end, %a1)
2:
clrb %a0@+
cmpl %a0, %a1
bne 2b
RELOC(esym, %a0)
#if 0
movl %a4, %a0@ | store end of symbol table
#else
clrl %a0@ | no symbol table, yet
#endif
RELOC(lowram, %a0)
movl %a5, %a0@ | store start of physical memory
#if 0
RELOC(boothowto, %a0) | save reboot flags
movl %d7, %a0@
RELOC(bootdev, %a0) | and boot device
movl %d6, %a0@
#endif
movl #0x200,%d0 | data freeze bit
movc %d0,%cacr | only exists on 68030
movc %cacr,%d0 | read it back
tstl %d0 | zero?
jeq Lnot68030 | yes, we have 68020/68040
RELOC(mmutype, %a0) | no, we have 68030
movl #MMU_68030,%a0@ | set to reflect 68030 PMMU
RELOC(cputype, %a0)
movl #CPU_68030,%a0@ | and 68030 CPU
jra Lstart1
Lnot68030:
bset #31,%d0 | data cache enable bit
movc %d0,%cacr | only exists on 68040
movc %cacr,%d0 | read it back
tstl %d0 | zero?
beq Lis68020 | yes, we have 68020
moveq #0,%d0 | now turn it back off
movec %d0,%cacr | before we access any data
RELOC(mmutype, %a0)
movl #MMU_68040,%a0@ | with a 68040 MMU
RELOC(cputype, %a0)
movl #CPU_68040,%a0@ | and a 68040 CPU
RELOC(fputype, %a0)
movl #FPU_68040,%a0@ | ...and FPU
jra Lstart1
Lis68020:
Lstart1:
movl 0x5c00ac00, %d0
andb #0x60, %d0
jne Lnot8M
movl #0x20800000, %d1 | memory end, 8M
jra Lmemok
Lnot8M:
cmpb #0x20, %d0
jne Lunkmem
movl #0x22000000, %d1 | memory end, 32M
jra Lmemok
Lunkmem:
movl #0x20400000, %d1 | memory end, assume at least 4M
Lmemok:
moveq #PGSHIFT,%d2
lsrl %d2,%d1 | convert to page (click) number
movl %a5,%d0 | lowram value from ROM via boot
lsrl %d2,%d0 | convert to page number
subl %d0,%d1 | compute amount of RAM present
RELOC(physmem, %a0)
movl %d1,%a0@ | and physmem
.globl _Sysseg_pa, _pmap_bootstrap, _avail_start
#if NKSYMS || defined(DDB) || defined(MODULAR)
RELOC(esym,%a0) | end of static kernel test/data/syms
movl %a0@,%a4
tstl %a4
jne Lstart2
#endif
movl #_C_LABEL(end),%a4 | end of static kernel text/data
Lstart2:
addl %a5,%a4 | convert to PA
subl #KERNBASE, %a4
pea %a5@ | firstpa
pea %a4@ | nextpa
RELOC(pmap_bootstrap1,%a0)
jbsr %a0@ | pmap_bootstrap1(firstpa, nextpa)
addql #8,%sp
movl %d0, %d7
RELOC(Sysseg_pa, %a0) | system segment table addr
movl %a0@,%d1 | read value (a PA)
subl #KERNBASE, %d1
RELOC(mmutype, %a0)
cmpl #MMU_68040,%a0@ | 68040?
jne Lmotommu1 | no, skip
.long 0x4e7b1807 | movc d1,srp
jra Lstploaddone
Lmotommu1:
#ifdef M68030
RELOC(protorp, %a0)
movl %d1,%a0@(4) | segtable address
pmove %a0@,%srp | load the supervisor root pointer
#endif
Lstploaddone:
RELOC(mmutype, %a0)
cmpl #MMU_68040,%a0@ | 68040?
jne Lmotommu2 | no, skip
movel #0x2000c000, %d0 | double map RAM
.long 0x4e7b0004 | movc d0,itt0
.long 0x4e7b0006 | movc d0,dtt0
moveq #0, %d0 | ensure TT regs are disabled
.long 0x4e7b0005 | movc d0,itt1
.long 0x4e7b0007 | movc d0,dtt1
.word 0xf4d8 | cinva bc
.word 0xf518 | pflusha
movl #MMU40_TCR_BITS, %d0
.long 0x4e7b0003 | movc d0,tc
movl #0x80008000, %d0
movc %d0, %cacr | turn on both caches
jmp Lenab1:l | avoid pc-relative
Lmotommu2:
pflusha
RELOC(prototc, %a2)
movl #MMU51_TCR_BITS,%a2@ | value to load TC with
pmove %a2@,%tc | load it
jmp Lenab1
Lenab1:
.word 0xf4d8 | cinva bc
.word 0xf518 | pflusha
nop
nop
nop
nop
nop
moveq #0,%d0 | ensure TT regs are disabled
.long 0x4e7b0004 | movc d0,itt0
.long 0x4e7b0005 | movc d0,itt1
.long 0x4e7b0006 | movc d0,dtt0
.long 0x4e7b0007 | movc d0,dtt1
lea _ASM_LABEL(tmpstk),%sp | re-load temporary stack
jbsr _C_LABEL(vec_init) | initialize vector table
jbsr _C_LABEL(pmap_bootstrap2)
movl %a0,%sp | now running on lwp0's stack
movl #0,%a6 | terminate the stack back trace
jbsr _C_LABEL(_TBIA) | invalidate TLB
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
jeq Lnocache0 | yes, cache already on
movl #CACHE_ON,%d0
movc %d0,%cacr | clear cache(s)
Lnocache0:
movl %d7,%sp@- | push nextpa saved above
jbsr _C_LABEL(machine_init) | additional pre-main initialization
addql #4,%sp
jra _C_LABEL(main) | main() (never returns)
ENTRY_NOPROFILE(lev6intr)
INTERRUPT_SAVEREG
movl _C_LABEL(clockbase), %a0
movl %a0@, %d0
movl %d0, %a0@
btst #2, %d0
jeq 1f
addql #1,_C_LABEL(m68k_intr_evcnt)+CLOCK_INTRCNT
lea %sp@(0), %a1 | a1 = &clockframe
movl %a1, %sp@-
jbsr _C_LABEL(hardclock) | hardclock(&frame)
addql #4, %sp
jra 2f
1:
movl %d0, %sp@-
jbsr _C_LABEL(otherclock)
addql #4, %sp
2:
INTERRUPT_RESTOREREG
jra _ASM_LABEL(rei) | all done
ENTRY_NOPROFILE(lev7intr)
addql #1,_C_LABEL(m68k_intr_evcnt)+NMI_INTRCNT
clrl %sp@-
moveml #0xFFFF,%sp@- | save registers
movl %usp,%a0 | and save
movl %a0,%sp@(FR_SP) | the user stack pointer
jbsr _C_LABEL(nmihand) | call handler
movl %sp@(FR_SP),%a0 | restore
movl %a0,%usp | user SP
moveml %sp@+,#0x7FFF | and remaining registers
addql #8,%sp | pop SP and stack adjust
jra _ASM_LABEL(rei) | all done
ENTRY_NOPROFILE(machine_reboot)
movl #0x5c00c060, %d0 | want phys addressing
.long 0x4e7b0006 | movc d0,dtt0
movl #1, 0x5c00b800 | reset
stop #0x2700 | paranoia
.data
GLOBAL(mmutype)
.long MMU_68040 | default to 68040
GLOBAL(cputype)
.long CPU_68040 | default to 68040
GLOBAL(prototc)
.long 0 | prototype translation control
#ifdef DEBUG
.globl fulltflush, fullcflush
fulltflush:
.long 0
fullcflush:
.long 0
#endif