[BACK]Return to locore.S CVS log [TXT][DIR] Up to [local] / sys / arch / mvme88k / mvme88k

Annotation of sys/arch/mvme88k/mvme88k/locore.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: locore.S,v 1.49 2006/05/08 14:03:35 miod Exp $        */
                      2: /*
                      3:  * Copyright (c) 2005, Miodrag Vallat.
                      4:  * Copyright (c) 1998 Steve Murphree, Jr.
                      5:  * Copyright (c) 1996 Nivas Madhur
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Nivas Madhur.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     31:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  *
                     33:  */
                     34: /*
                     35:  * Mach Operating System
                     36:  * Copyright (c) 1993-1991 Carnegie Mellon University
                     37:  * Copyright (c) 1991 OMRON Corporation
                     38:  * All Rights Reserved.
                     39:  *
                     40:  * Permission to use, copy, modify and distribute this software and its
                     41:  * documentation is hereby granted, provided that both the copyright
                     42:  * notice and this permission notice appear in all copies of the
                     43:  * software, derivative works or modified versions, and any portions
                     44:  * thereof, and that both notices appear in supporting documentation.
                     45:  *
                     46:  * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     47:  * CONDITION.  CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
                     48:  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     49:  *
                     50:  * Carnegie Mellon requests users of this software to return to
                     51:  *
                     52:  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
                     53:  *  School of Computer Science
                     54:  *  Carnegie Mellon University
                     55:  *  Pittsburgh PA 15213-3890
                     56:  *
                     57:  * any improvements or extensions that they make and grant Carnegie the
                     58:  * rights to redistribute these changes.
                     59:  */
                     60:
                     61: #include "assym.h"
                     62: #include "ksyms.h"
                     63:
                     64: #include <machine/asm.h>
                     65: #include <machine/m88100.h>
                     66: #include <machine/param.h>
                     67: #include <machine/psl.h>
                     68: #include <machine/trap.h>
                     69: #include <machine/vmparam.h>
                     70:
                     71: /*
                     72:  * The memory looks like:
                     73:  *   0x00000 - 0x01000 trap vectors
                     74:  *   0x01000 - 0x10000 first 64k used by BUG
                     75:  *   0x10000 == start  Boot loader jumps here. (for now, this can
                     76:  *                     handle only NMAGIC - screwy linker)
                     77:  */
                     78:        text
                     79:
                     80: GLOBAL(kernelstart)
                     81: GLOBAL(kernel_text)
                     82: ASGLOBAL(start)
                     83:        /*
                     84:         * A few identical jump instructions to make sure the pipeline is
                     85:         * in a good state. Probably overkill, but it's cheap.
                     86:         */
                     87:        br      _ASM_LABEL(main_start)
                     88:        br      _ASM_LABEL(main_start)
                     89:        br      _ASM_LABEL(main_start)
                     90:        br      _ASM_LABEL(main_start)
                     91:
                     92:        /*
                     93:         * Startup code for main processor.
                     94:         */
                     95: ASLOCAL(main_start)
                     96:        /*
                     97:         * Save the arguments passed by the boot loader
                     98:         *      r2 boot flags
                     99:         *      r3 boot controller physical address
                    100:         *      r4 esym (if applicable)
                    101:         *      r5 start of miniroot (unused)
                    102:         *      r6 end of miniroot (unused)
                    103:         *      r7 ((Clun << 8) | Dlun): encoded bootdev
                    104:         *      r8 board type (0x187, 0x188, 0x197)
                    105:         */
                    106: /*
                    107:  * (*entry)(flag, bugargs.ctrl_addr, cp, kernel.smini,kernel.emini,
                    108:  *  bootdev, brdtyp);
                    109:  */
                    110:        or.u    r13, r0,  hi16(_C_LABEL(boothowto))
                    111:        st      r2,  r13, lo16(_C_LABEL(boothowto))
                    112:        or.u    r13, r0,  hi16(_C_LABEL(bootaddr))
                    113:        st      r3,  r13, lo16(_C_LABEL(bootaddr))
                    114:        or.u    r13, r0,  hi16(_C_LABEL(first_addr))
                    115:        st      r4,  r13, lo16(_C_LABEL(first_addr))
                    116: #if defined(DDB) || NKSYMS > 0
                    117:        or.u    r13, r0,  hi16(_C_LABEL(esym))
                    118:        st      r4,  r13, lo16(_C_LABEL(esym))
                    119: #endif
                    120:        or.u    r13, r0,  hi16(_C_LABEL(bootdev))
                    121:        st      r7,  r13, lo16(_C_LABEL(bootdev))
                    122:        or.u    r13, r0,  hi16(_C_LABEL(brdtyp))
                    123:        st      r8,  r13, lo16(_C_LABEL(brdtyp))
                    124:
                    125:        /* set cputyp */
                    126:        ldcr    r1,  PID
                    127:        extu    r2,  r1, 8<8>
                    128:        bcnd.n  eq0, r2, 1f
                    129:         or.u   r13, r0,  hi16(_C_LABEL(cputyp))
                    130:        or.u    r8,  r0,  hi16(CPU_88110)
                    131:        br.n    2f
                    132:         or     r8,  r8,  lo16(CPU_88110)
                    133: 1:
                    134:        or.u    r8,  r0,  hi16(CPU_88100)
                    135:        or      r8,  r8,  lo16(CPU_88100)
                    136: 2:
                    137:        st      r8,  r13, lo16(_C_LABEL(cputyp))
                    138:
                    139:        /*
                    140:         * CPU Initialization
                    141:         *
                    142:         * I use r11 and r22 here because they're easy to not
                    143:         * get mixed up -- r10, for example, looks too similar
                    144:         * to r0 when not being careful....
                    145:         *
                    146:         * Ensure that the PSR is as we like:
                    147:         *      supervisor mode
                    148:         *      big-endian byte ordering
                    149:         *      concurrent operation allowed
                    150:         *      carry bit clear (I don't think we really care about this)
                    151:         *      FPU enabled
                    152:         *      misaligned access raises an exception
                    153:         *      interrupts disabled
                    154:         *      shadow registers frozen
                    155:         *
                    156:         * The manual says not to disable interrupts and freeze shadowing
                    157:         * at the same time because interrupts are not actually disabled
                    158:         * until after the next instruction. Well, if an interrupt
                    159:         * occurs now, we're in deep trouble anyway, so I'm going to do
                    160:         * the two together.
                    161:         *
                    162:         * Upon a reset (or poweron, I guess), the PSR indicates:
                    163:         *   supervisor mode
                    164:         *   interrupts, shadowing, FPU, misaligned exception: all disabled
                    165:         *
                    166:         * We'll just construct our own turning on what we want.
                    167:         *
                    168:         *      jfriedl@omron.co.jp
                    169:         */
                    170:
                    171:        cmp     r2, r8, CPU_88110       /* r8 contains cputyp */
                    172:        bb1     eq, r2, 1f      /* if it's a 'mc88110, skip SSBR */
                    173:        stcr    r0, SSBR        /* clear this for later */
                    174: 1:
                    175:        stcr    r0, SR1         /* clear the CPU flags */
                    176:
                    177:        set     r11, r0,  1<PSR_SUPERVISOR_MODE_BIT>
                    178:        set     r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
                    179:        set     r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
                    180:        /*
                    181:         * XXX On 88110 processors, force serial instruction execution for now.
                    182:         * Situation where OoO would break will be hopefully taken care of in
                    183:         * the near future -- miod
                    184:         */
                    185: #if 0
                    186:        clr     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    187: #else
                    188:        set     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    189: #endif
                    190:        set     r11, r11, 1<PSR_SERIALIZE_BIT>
                    191:        stcr    r11, PSR
                    192:        FLUSH_PIPELINE
                    193:        stcr    r0,  VBR        /* set Vector Base Register to 0, ALWAYS! */
                    194:        FLUSH_PIPELINE
                    195:
                    196: #ifdef MULTIPROCESSOR
                    197:        /*
                    198:         * Have curcpu() point at the dummy cpuinfo structure,
                    199:         * so that cpu_number() does not dereference random memory.
                    200:         * This is necessary for early spl usage, despite the fact that
                    201:         * interrupts are disabled...
                    202:         */
                    203:        or.u    r11, r0,  hi16(_ASM_LABEL(dummy_cpu))
                    204:        or      r11, r11, lo16(_ASM_LABEL(dummy_cpu))
                    205:        stcr    r11, CPU
                    206:
                    207:        /*
                    208:         * MVME BUG idles all secondary MPUs upon startup, so at this point
                    209:         * we do not have to compete with them.
                    210:         */
                    211: #endif /* MULTIPROCESSOR */
                    212:
                    213:        /* Switch to interrupt stack */
                    214:        or.u    r31, r0,  hi16(_ASM_LABEL(intstack_end))
                    215:        or      r31, r31, lo16(_ASM_LABEL(intstack_end))
                    216:
                    217: #ifdef M88110
                    218: #ifdef M88100
                    219:        cmp     r2, r8, CPU_88110 /* r8 contains cputyp */
                    220:        bb1     ne, r2, 1f      /* if it's a 'mc88110, use different vectors */
                    221: #endif
                    222:        or.u    r3, r0, hi16(_C_LABEL(m88110_vector_list))
                    223:        br.n    2f
                    224:         or     r3, r3, lo16(_C_LABEL(m88110_vector_list))
                    225: 1:
                    226: #endif /* M88110 */
                    227: #ifdef M88100
                    228:        or.u    r3, r0, hi16(_C_LABEL(vector_list))
                    229:        or      r3, r3, lo16(_C_LABEL(vector_list))
                    230: #endif /* M88100 */
                    231: 2:
                    232:        bsr.n   _C_LABEL(mvme88k_vector_init)
                    233:         ldcr   r2, VBR
                    234:
                    235:        /*
                    236:         * mvme_bootstrap(), among other things, clears proc0's u area.
                    237:         * We are still using the interrupt stack here, thus we are not
                    238:         * affected...
                    239:         */
                    240:        bsr     _C_LABEL(mvme_bootstrap)
                    241:
                    242:        /*
                    243:         * ...and we can switch to the u area stack now.
                    244:         */
                    245:        ldcr    r10, CPU
                    246:        ld      r31, r10, CI_CURPCB
                    247:
                    248:        /* call main() - no arguments although main() still defines one */
                    249:        bsr.n   _C_LABEL(main)
                    250:         addu   r31, r31, USIZE
                    251:
                    252:        or.u    r2, r0, hi16(_ASM_LABEL(main_panic))
                    253:        bsr.n   _C_LABEL(panic)
                    254:         or     r2, r2, lo16(_ASM_LABEL(main_panic))
                    255:
                    256:        data
                    257:        .align  4
                    258: ASLOCAL(main_panic)
                    259:        string  "main() returned\0"
                    260:        text
                    261:        .align  8
                    262:
                    263: #ifdef MULTIPROCESSOR
                    264:
                    265:        /*
                    266:         * Startup code for secondary processors.
                    267:         * Some of these initializations are very close to main_start; refer
                    268:         * to the comments there for details.
                    269:         */
                    270: GLOBAL(secondary_start)
                    271:        or.u    r31, r0,  hi16(_ASM_LABEL(slavestack_end))
                    272:        or      r31, r31, lo16(_ASM_LABEL(slavestack_end))
                    273:
                    274:        or.u    r13, r0,  hi16(_C_LABEL(cputyp))
                    275:        ld      r8,  r13, lo16(_C_LABEL(cputyp))
                    276:
                    277:        cmp     r2, r8, CPU_88110
                    278:        bb1     eq, r2, 1f
                    279:        stcr    r0, SSBR
                    280: 1:
                    281:        stcr    r0, SR1
                    282:
                    283:        set     r11, r0,  1<PSR_SUPERVISOR_MODE_BIT>
                    284:        set     r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
                    285:        set     r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
                    286:        /*
                    287:         * XXX On 88110 processors, force serial instruction execution for now.
                    288:         * Situation where OoO would break will be hopefully taken care of in
                    289:         * the near future -- miod
                    290:         */
                    291: #if 0
                    292:        clr     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    293: #else
                    294:        set     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    295: #endif
                    296:        set     r11, r11, 1<PSR_SERIALIZE_BIT>
                    297:        stcr    r11, PSR
                    298:        FLUSH_PIPELINE
                    299:        stcr    r0,  VBR        /* set Vector Base Register to 0, ALWAYS! */
                    300:        FLUSH_PIPELINE
                    301:
                    302:        /*
                    303:         * Have curcpu() point at the dummy cpuinfo structure,
                    304:         * so that cpu_number() does not dereference random memory.
                    305:         * This is necessary for early spl usage, despite the fact that
                    306:         * interrupts are disabled...
                    307:         */
                    308:        or.u    r11, r0,  hi16(_ASM_LABEL(dummy_cpu))
                    309:        or      r11, r11, lo16(_ASM_LABEL(dummy_cpu))
                    310:        stcr    r11, CPU
                    311:
                    312:        /*
                    313:         * Since there may be more than one secondary MPU, compete with them
                    314:         * to initialize safely.
                    315:         */
                    316:        or.u    r11, r0,  hi16(_C_LABEL(cpu_mutex))
                    317:        or      r11, r11, lo16(_C_LABEL(cpu_mutex))
                    318: 1:
                    319:        or      r22, r0,  1
                    320:        xmem    r22, r11, r0            /* If r22 gets 0, we have the lock... */
                    321:        bcnd    eq0, r22, 4f            /* ...but if not, we must wait */
                    322: 2:
                    323:        /* just watch the lock until it looks clear */
                    324:        ld      r22, r11, r0
                    325:        bcnd    eq0, r22, 1b
                    326:        /* since we can be here with caches off, add a few nops to
                    327:           keep the bus from getting overloaded */
                    328:        or      r2,  r0,  lo16(1000)
                    329: 3:
                    330:        subu    r2,  r2,  1
                    331:        bcnd    ne0, r2,  3b
                    332:        br      1b
                    333: 4:
                    334:
                    335:        /*
                    336:         * While holding the cpu_mutex, the secondary cpu can use the slavestack
                    337:         * to call secondary_pre_main() to determine its cpu number.
                    338:         * After that, however, it should allocate its own stack and switch
                    339:         * to it.
                    340:         */
                    341:
                    342:        bsr     _C_LABEL(secondary_pre_main)    /* set cpu number */
                    343:
                    344:        ldcr    r2, CPU
                    345:        ld      r3, r2, CI_IDLE_PCB
                    346:        bsr.n   _C_LABEL(secondary_main)
                    347:         addu   r31, r3, USIZE                  /* switch to idle stack */
                    348:
                    349:        /*
                    350:         * At this point, the CPU has been correctly initialized and has
                    351:         * identified itself on the console.
                    352:         * All it needs now is to jump to the idle loop and wait for work to
                    353:         * be offered.
                    354:         */
                    355:        br      _ASM_LABEL(cpu_switch_idle)
                    356:
                    357: #endif /* MULTIPROCESSOR */
                    358:
                    359: /*
                    360:  * Reset code.
                    361:  * Should be rewritten in C eventually.
                    362:  */
                    363: GLOBAL(doboot)
                    364: #ifdef MVME188
                    365:        /* check if it's a mvme188 */
                    366:        or.u    r4, r0, hi16(_C_LABEL(brdtyp))
                    367:        ld      r3, r4, lo16(_C_LABEL(brdtyp))
                    368:        cmp     r4, r3, BRD_188
                    369:        bb1     ne, r4, 1f
                    370:        bsr     _C_LABEL(m188_reset)
                    371:        br      8f
                    372: 1:
                    373: #endif /* MVME188 */
                    374:        /*
                    375:         * Try hitting the SRST bit in VMEchip2 to reset the system.
                    376:         */
                    377:        or.u    r3, r0, 0xfff4
                    378:        ld      r4, r3, 0x0060          /* read offset (LCSR + 0x60) */
                    379:        bb0.n   30, r4, 1f              /* if not SYSCON, don't SYSRST */
                    380:         set    r4, r4, 1<23>           /* set SYSRST bit - bit 23 */
                    381:        st      r4, r3, 0x0060          /* and store it back  */
                    382: 1:
                    383:        ld      r4, r3, 0x0104          /* try local reset, then */
                    384:        set     r4, r4, 1<7>
                    385:        st      r4, r3, 0x0104
                    386:
                    387:        /*
                    388:         * We will be here if the reset above failed. In this case,
                    389:         * we will try to return to bug.
                    390:         *
                    391:         * Switch to interrupt stack and call _doboot to take care
                    392:         * going to BUG. Need to do this since _doboot turns off the
                    393:         * the MMU and we need to be on a 1-to-1 mapped stack so that
                    394:         * further calls don't get data access exceptions.
                    395:         */
                    396:
                    397: 8:
                    398:        or.u    r31, r0,  hi16(_ASM_LABEL(intstack_end))
                    399:        bsr.n   _C_LABEL(_doboot)
                    400:         or     r31, r31, lo16(_ASM_LABEL(intstack_end))
                    401:        /*NOTREACHED*/
                    402:
                    403: /*
                    404:  * MVME188 specific support routines
                    405:  */
                    406:
                    407: #ifdef MVME188
                    408: /*
                    409:  * void m188_delay(int us)
                    410:  *
                    411:  * The processor loops (busy waits) for the given number of microseconds:
                    412:  * Thus, delay(1000000) will delay for one second.
                    413:  * (originally from Mach 2.5)
                    414:  */
                    415: GLOBAL(m188_delay)
                    416:        or.u    r3, r0, hi16(_cpuspeed)
                    417:        ld      r3, r3, lo16(_cpuspeed)
                    418:        mul     r4, r2, r3
                    419:        subu    r4, r4, 4       /* overhead of these instructions */
                    420:
                    421:        /* now loop for the given number of cycles */
                    422: 1:
                    423:        bcnd.n  gt0, r4, 1b
                    424:         subu   r4, r4, 2       /* two cycles per iteration */
                    425:
                    426:        jmp     r1
                    427: #endif
                    428:
                    429: /*****************************************************************************/
                    430:
                    431:        data
                    432:        .align  PAGE_SIZE
                    433: GLOBAL(kernel_sdt)             /* SDT (segment descriptor table */
                    434:        space   0x2000          /* 8K - 4K phys, 4K virt*/
                    435:
                    436:        .align  PAGE_SIZE
                    437: ASGLOBAL(intstack)
                    438:        space   USIZE
                    439: ASGLOBAL(intstack_end)
                    440:
                    441: #ifdef MULTIPROCESSOR
                    442:        space   PAGE_SIZE       /* 4K, small, interim stack */
                    443: ASLOCAL(slavestack_end)
                    444: #endif
                    445:
                    446: /*
                    447:  * Main processor's idle pcb and stack.
                    448:  * Should be page aligned.
                    449:  */
                    450:        .align  PAGE_SIZE
                    451: GLOBAL(idle_u)
                    452:        space   USIZE
                    453:
                    454: /*
                    455:  * Process 0's u.
                    456:  * Should be page aligned.
                    457:  */
                    458:        .align  PAGE_SIZE
                    459: ASLOCAL(u0)
                    460:        space   USIZE
                    461: GLOBAL(proc0paddr)
                    462:        word    _ASM_LABEL(u0)  /*  KVA of proc0 uarea */
                    463:
                    464: #ifdef MULTIPROCESSOR
                    465: /* Dummy cpuinfo structure, for cpu_number() to work early. */
                    466: ASLOCAL(dummy_cpu)
                    467:        word    1       /* ci_alive */
                    468:        word    0       /* ci_curproc */
                    469:        word    0       /* ci_curpcb */
                    470:        word    0       /* ci_cpuid */
                    471: #endif /* MULTIPROCESSOR */
                    472:
                    473: #if defined(DDB) || NKSYMS > 0
                    474: GLOBAL(esym)
                    475:        word    0
                    476: #endif /* DDB || NKSYMS > 0 */

CVSweb