root/sys/arch/cesfic/cesfic/locore.s
/*      $NetBSD: locore.s,v 1.73 2026/04/28 03:29:09 thorpej Exp $      */

/*
 * Copyright (c) 1980, 1990, 1993
 *      The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * the Systems Programming Group of the University of Utah Computer
 * Science Department.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * from: Utah $Hdr: locore.s 1.66 92/12/22$
 *
 *      @(#)locore.s    8.6 (Berkeley) 5/27/94
 */

/*
 * Copyright (c) 1994, 1995 Gordon W. Ross
 * Copyright (c) 1988 University of Utah.
 *
 * This code is derived from software contributed to Berkeley by
 * the Systems Programming Group of the University of Utah Computer
 * Science Department.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * from: Utah $Hdr: locore.s 1.66 92/12/22$
 *
 *      @(#)locore.s    8.6 (Berkeley) 5/27/94
 */

#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>

/*
 * This is for kvm_mkdb, and should be the address of the beginning
 * of the kernel text segment (not necessarily the same as kernbase).
 */
        .text
GLOBAL(kernel_text)

/*
 * Temporary stack for a variety of purposes.
 * Try and make this the first thing is the data segment so it
 * is page aligned.  Note that if we overflow here, we run into
 * our text segment.
 */
        .data
        .space  PAGE_SIZE
ASGLOBAL(tmpstk)

        .text
/*
 * Macro to relocate a symbol, used before MMU is enabled.
 */
#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)

/*
 * Initialization
 *
 * A4 contains the address of the end of the symtab
 * A5 contains physical load point from boot
 * VBR contains zero from ROM.  Exceptions will continue to vector
 * through ROM until MMU is turned on at which time they will vector
 * through our table (vectors.s).
 */

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)

        /* XXX fixed load address */
        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

        /*
         * All data registers are now free.  All address registers
         * except a5 are free.  a5 is used by the RELOC() macro,
         * and cannot be used until after the MMU is enabled.
         */

/* determine our CPU/MMU combo - check for all regardless of kernel config */
        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:
        /* impossible */

Lstart1:

/* initialize memory size (for pmap_bootstrap1) */
        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
/* configure kernel and lwp0 VA space so we can get going */
        .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

        /*
         * Updated nextpa returned in %d0.  We need to squirrel
         * that away in a callee-saved register to use later,
         * after the MMU is enabled.
         */
        movl    %d0, %d7

        /* NOTE: %d7 is now off-limits!! */

/*
 * Prepare to enable MMU.
 */
        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 /* M68030 */
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:
        /* XXX do TT here */
        pflusha
        RELOC(prototc, %a2)
        movl    #MMU51_TCR_BITS,%a2@    | value to load TC with
        pmove   %a2@,%tc                | load it
        jmp     Lenab1

/*
 * Should be running mapped from this point on
 */
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

        /* phase 2 of pmap setup, returns lwp0 SP in %a0 */
        jbsr    _C_LABEL(pmap_bootstrap2)
        movl    %a0,%sp                 | now running on lwp0's stack
        movl    #0,%a6                  | terminate the stack back trace

/* flush TLB and turn on caches */
        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:

/* Final setup for call to main(). */
        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)

/*
 * Interrupt handlers.
 */

ENTRY_NOPROFILE(lev6intr)       /* Level 6: clock */
        INTERRUPT_SAVEREG
        /* XXX */
        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)       /* level 7: parity errors, reset key */
        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