root/sys/arch/hp300/stand/common/srt0.S
/*      $NetBSD: srt0.S,v 1.17 2011/02/08 20:20:14 rmind Exp $  */

/*
 * Copyright (c) 1988 University of Utah.
 * Copyright (c) 1982, 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: srt0.c 1.18 92/12/21$
 *
 *      @(#)srt0.c      8.1 (Berkeley) 6/10/93
 */

/*
 * Startup code for standalone system
 */

/* For machineid and mmuid constants */
#include <machine/hp300spu.h>

/* For _C_LABEL() and friends. */
#include <machine/asm.h>

        STACK =    0xfffff000           /* below the ROM page */
        BOOTTYPE = 0xfffffdc0
        LOWRAM =   0xfffffdce
        SYSFLAG =  0xfffffed2           /* system flags */
        MSUS =     0xfffffedc           /* MSUS (?) structure */
        VECTORS =  0xfffffee0           /* beginning of jump vectors */
        NMIRESET = 0xffffff9c           /* reset vector */
        BUSERR =   0xfffffffc
        MAXADDR =  0xfffff000
        NBPG =     4096
        MMUCMD =   0x005f400c           /* MMU command/status register */

        .data
GLOBAL(bootdev)
        .long   0

GLOBAL(howto)
        .long   0

GLOBAL(lowram)
        .long   0

GLOBAL(machineid)
        .long   0

GLOBAL(mmuid)
        .long   0

        .text
ASENTRY_NOPROFILE(begin)
        movl    #STACK,%sp
        moveq   #47,%d0                 /* # of vectors - 1 */
        movl    #VECTORS+2,%a0          /* addr part of first vector */
1:
        movl    #_ASM_LABEL(__trap),%a0@ /* make it direct to __trap */
        addql   #6,%a0                  /* move to next vector addr */
        dbf     %d0,1b                  /* go til done */
#ifdef ITECONSOLE
        movl    #NMIRESET,%a0           /* NMI keyboard reset addr */
        movl    #nmi,%a0@               /* catch in reset routine */
#else
        /*
         * Built without ITE console support; leave the ROM's NMI
         * vector in place, so the system will still reset if a
         * keyboard NMI is issued.
         */
#endif

/*
 * Determine our SPU type and look for internal HP-IB
 */
        lea     _C_LABEL(machineid),%a0
        movl    #0x808,%d0
        movc    %d0,%cacr               /* clear and disable on-chip cache(s) */
        movl    #0x200,%d0              /* data freeze bit */
        movc    %d0,%cacr               /*   only exists on 68030 */
        movc    %cacr,%d0               /* read it back */
        tstl    %d0                     /* zero? */
        jeq     not68030                /* yes, we have 68020/68040 */

        /*
         * 68030 models
         */

        movl    #0x808,%d0
        movc    %d0,%cacr               /* clear data freeze bit again */

        movl    #0x80,MMUCMD            /* set magic cookie */
        movl    MMUCMD,%d0              /* read it back */
        btst    #7,%d0                  /* cookie still on? */
        jeq     not370                  /* no, 360, 362 or 375 */
        movl    #HP_370,%a0@            /* consider a 370 for now */
        movl    #0,MMUCMD               /* clear magic cookie */
        movl    MMUCMD,%d0              /* read it back */
        btst    #7,%d0                  /* still on? */
        jeq     ihpibcheck              /* no, a 370 */
        movl    #HP_340,%a0@            /* yes, must be a 340 */
        jra     ihpibcheck

not370:
        movl    #HP_360,%a0@            /* type is at least a 360 */
        movl    #0,MMUCMD               /* clear magic cookie2 */
        movl    MMUCMD,%d0              /* read it back */
        btst    #16,%d0                 /* still on? */
        jeq     isa36x                  /* no, a 360 or a 362 */
        lea     _C_LABEL(mmuid),%a0
        lsrl    #MMUID_SHIFT,%d0        /* save MMU ID */
        andl    #MMUID_MASK,%d0
        movl    %d0,%a0@
        lea     _C_LABEL(machineid),%a0
        cmpb    #MMUID_345,%d0          /* are we a 345? */
        jeq     isa345
        cmpb    #MMUID_375,%d0          /* how about a 375? */
        jeq     isa375
        movl    #HP_400,%a0@            /* must be a 400 */
        jra     ihpibcheck
isa36x:
        movl    #0x01000000,%sp@-       /* check DIOII_BASE (scode 132) */
        jbsr    _C_LABEL(badaddr)
        addql   #4,%sp
        tstl    %d0
        jne     ihpibcheck              /* no device, assume 360 */
        movl    #0x01000000,%a0
        movb    %a0@(0x01),%d0          /* check device ID at DIO_IDOFF */
        cmpb    #0x39,%d0               /* framebuffer? */
        jne     ihpibcheck              /* no, assume 360 */
        movb    %a0@(0x15),%d0          /* check sec ID at DIO_SECIDOFF */
        cmpb    #0x11,%d0               /* VRX sti on 362? */
        jne     ihpibcheck              /* no, assume 360 */
        lea     _C_LABEL(machineid),%a0
        movl    #HP_362,%a0@
        jra     ihpibcheck
isa345:
        movl    #HP_345,%a0@
        jra     ihpibcheck
isa375:
        movl    #HP_375,%a0@
        jra     ihpibcheck

        /*
         * End of 68030 section
         */

not68030:
        bset    #31,%d0                 /* data cache enable bit */
        movc    %d0,%cacr               /*   only exists on 68040 */
        movc    %cacr,%d0               /* read it back */
        tstl    %d0                     /* zero? */
        beq     is68020                 /* yes, we have 68020 */

        /*
         * 68040 models
         */

        moveq   #0,%d0                  /* now turn it back off */
        movec   %d0,%cacr               /*   before we access any data */

        .long   0x4e7b0004              /* movc %d0,%itt0 */
        .long   0x4e7b0005              /* movc %d0,%itt1 */
        .long   0x4e7b0006              /* movc %d0,%dtt0 */
        .long   0x4e7b0007              /* movc %d0,%dtt1 */
        .word   0xf4d8                  /* cinva bc */

        lea     _C_LABEL(mmuid),%a0
        movl    MMUCMD,%d0              /* get MMU ID */
        lsrl    #MMUID_SHIFT,%d0
        andl    #MMUID_MASK,%d0
        movl    %d0,%a0@                /* save it */
        lea     _C_LABEL(machineid),%a0
        cmpb    #MMUID_425_T,%d0        /* are we a 425t? */
        jeq     isa425
        cmpb    #MMUID_425_S,%d0        /* how about 425s? */
        jeq     isa425
        cmpb    #MMUID_425_E,%d0        /* or maybe a 425e? */
        jeq     isa425
        cmpb    #MMUID_433_T,%d0        /* or a 433t? */
        jeq     isa433
        cmpb    #MMUID_433_S,%d0        /* or a 433s? */
        jeq     isa433
        cmpb    #MMUID_385,%d0          /* or a 385? */
        jeq     isa385
        cmpb    #MMUID_382,%d0          /* or a 382? */
        jeq     isa382
        movl    #HP_380,%a0@            /* guess we are a 380 */
        jra     ihpibcheck
isa425:
        movl    #HP_425,%a0@
        jra     ihpibcheck
isa433:
        movl    #HP_433,%a0@
        jra     ihpibcheck
isa385:
        movl    #HP_385,%a0@
        jra     ihpibcheck
isa382:
        movl    #HP_382,%a0@
        jra     ihpibcheck

        /*
         * End 68040 section
         */

        /*
         * 68020 models
         */

is68020:
        movl    #HP_330,%a0@            /* consider a 330 for now */
        movl    #1,MMUCMD               /* a 68020, write HP MMU location */
        movl    MMUCMD,%d0              /* read it back */
        btst    #0,%d0                  /* zero? */
        jeq     ihpibcheck              /* yes, a 330 */
        movl    #HP_320,%a0@            /* no, consider a 320 for now */
        movl    #0x80,MMUCMD            /* set magic cookie */
        movl    MMUCMD,%d0              /* read it back */
        btst    #7,%d0                  /* cookie still on? */
        jeq     ihpibcheck              /* no, just a 320 */
        movl    #HP_350,%a0@            /* yes, a 350 */

        /*
         * End 68020 section
         */

ihpibcheck:
        movl    #0,MMUCMD               /* make sure MMU is off */
        btst    #5,SYSFLAG              /* do we have an internal HP-IB? */
        jeq     boottype                /* yes, continue */
        clrl    _C_LABEL(internalhpib)  /* no, clear the internal address */
/*
 * If this is a reboot, extract howto/bootdev stored by kernel
 */
boottype:
        cmpw    #12,BOOTTYPE            /* is this a reboot (REQ_REBOOT)? */
        jne     notreboot               /* no, skip */
        lea     MAXADDR,%a0             /* find last page */
        movl    %a0@+,%d7               /* and extract howto, bootdev */
        movl    %a0@+,%d6               /*   from where doboot() left them */
        jra     boot1
/*
 * At this point we do not know which logical device the MSUS select
 * code refers to so we cannot construct bootdev.  So we just punt
 * and let configure() construct it.
 */
notreboot:
        moveq   #0,%d6                  /* make sure bootdev is invalid */
        cmpw    #18,BOOTTYPE            /* does the user want to interact? */
        jeq     askme                   /* yes, go to it */
        moveq   #0,%d7                  /* default to RB_AUTOBOOT */
        jra     boot1
askme:
        moveq   #3,%d7                  /* default to RB_SINGLE|RB_ASKNAME */
boot1:
        movl    %d6,_C_LABEL(bootdev)   /* save bootdev and howto */
        movl    %d7,_C_LABEL(howto)     /*   globally so all can access */
        movl    LOWRAM,%d0              /* read lowram value from bootrom */
        /*
         * Must preserve the scratch area for the BOOT ROM.
         * Round up to the next 8k boundary.
         */
        addl    #((2*NBPG)-1),%d0
        andl    #-(2*NBPG),%d0
        movl    %d0,_C_LABEL(lowram)    /* stash that value */
start:
        movl    #_C_LABEL(edata),%a2    /* start of BSS */
        movl    #_C_LABEL(end),%a3      /* end */
1:
        clrb    %a2@+                   /* clear BSS */
        cmpl    %a2,%a3                 /* done? */
        bne     1b                      /* no, keep going */
        jsr     _C_LABEL(configure)     /* configure critical devices */
        jsr     _C_LABEL(main)          /* lets go */
GLOBAL(_rtt)
        movl    #3,_C_LABEL(howto)      /* restarts get RB_SINGLE|RB_ASKNAME */
        jmp     start

/*
 * probe a location and see if it causes a bus error
 */
ENTRY_NOPROFILE(badaddr)
        movl    BUSERR,_C_LABEL(_bsave) /* save ROM bus error handler address */
        movl    %sp,_C_LABEL(_ssave)    /* and current stack pointer */
        movl    #catchbad,BUSERR        /* plug in our handler */
        movl    %sp@(4),%a0             /* address to probe */
        movw    %a0@,%d1                /* do it */
        movl    _C_LABEL(_bsave),BUSERR /* if we got here, it did not fault */
        clrl    %d0                     /* return that this was not a bad */
                                        /*   addr */
        rts

catchbad:
        movl    _C_LABEL(_bsave),BUSERR /* got a bus error, so restore */
                                        /*   old handler */
        movl    _C_LABEL(_ssave),%sp    /* manually restore stack */
        moveq   #1,%d0                  /* indicate that we got a fault */
        rts                             /* return to caller of badaddr() */

        .data
GLOBAL(_bsave)
        .long   0

GLOBAL(_ssave)
        .long   0

ASENTRY_NOPROFILE(__trap)
        moveml  #0xFFFF,%sp@-           /* save registers */
        movl    %sp,%sp@-               /* push pointer to frame */
        jsr     _C_LABEL(trap)          /* call C routine to deal with it */
        tstl    %d0
        jeq     Lstop
        addql   #4,%sp
        moveml  %sp@+,#0x7FFF
        addql   #8,%sp
        rte
Lstop:
        stop    #0x2700                 /* stop cold */

#ifdef ITECONSOLE
ASENTRY_NOPROFILE(nmi)
        movw    #18,BOOTTYPE            /* mark as system switch */
        jsr     _C_LABEL(kbdnmi)        /* clear the interrupt, and */
                                        /*   reset the system */
        stop    #0                      /* SCREEEECH! */
#endif

ENTRY_NOPROFILE(call_req_reboot)
        jmp     0x1A4                   /* call ROM reboot function */
        rts                             /* XXX: just in case? */

ENTRY_NOPROFILE(romout)
        movl    %sp@(4),%d0             /* line number */
        movl    %sp@(8),%a0             /* string */
        jsr     0x150                   /* do it */
        rts

/*
 * _transfer(entry, howto, opendev, conscode, lowram, esym)
 *
 *      Transfer control to the kernel.  We also set up registers
 *      as older kernels expect.
 */
ENTRY_NOPROFILE(_transfer)
        movl    %sp@(8),%d7             /* howto */
        movl    %sp@(12),%d6            /* opendev (compat) */
        movl    %sp@(16),%d5            /* conscode (compat) */
        movl    %sp@(20),%a5            /* lowram */
        movl    %sp@(24),%a4            /* esym (compat) */

        movl    %sp@(4),%a0             /* load entry point */
        jbsr    %a0@                    /* GO! */