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

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

1.1       nbrk        1: /*     $OpenBSD: locore.S,v 1.3 2006/05/20 22:40:43 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: #define        SYM_MAGIC       0x6274ef2e
                     72:
                     73:        text
                     74:
                     75: GLOBAL(kernelstart)
                     76: GLOBAL(kernel_text)
                     77: ASGLOBAL(start)
                     78:        /*
                     79:         * A few identical jump instructions to make sure the pipeline is
                     80:         * in a good state. Probably overkill, but it's cheap.
                     81:         */
                     82:        br      _ASM_LABEL(main_start)
                     83:        br      _ASM_LABEL(main_start)
                     84:        br      _ASM_LABEL(main_start)
                     85:        br      _ASM_LABEL(main_start)
                     86:
                     87:        /*
                     88:         * Startup code for main processor.
                     89:         */
                     90: ASLOCAL(main_start)
                     91:        /*
                     92:         * Save the arguments passed by the PROM
                     93:         *      r2 boot string
                     94:         *      r3 boot device
                     95:         *      r4 boot unit number
                     96:         *      r5 boot partition number
                     97:         *      r6 magic number if not loaded by the PROM
                     98:         *      r7 end of loaded binary if not loaded by the PROM
                     99:         */
                    100:        or.u    r13, r0,  hi16(_C_LABEL(prom_bootargs))
                    101:        st      r2,  r13, lo16(_C_LABEL(prom_bootargs))
                    102:        or.u    r13, r0,  hi16(_C_LABEL(bootdev))
                    103:        st      r3,  r13, lo16(_C_LABEL(bootdev))
                    104:        or.u    r13, r0,  hi16(_C_LABEL(bootunit))
                    105:        st      r4,  r13, lo16(_C_LABEL(bootunit))
                    106:        or.u    r13, r0,  hi16(_C_LABEL(bootpart))
                    107:        st      r5,  r13, lo16(_C_LABEL(bootpart))
                    108: #if defined(DDB) || NKSYMS > 0
                    109:        or.u    r12, r0,  hi16(SYM_MAGIC)
                    110:        or      r12, r12, lo16(SYM_MAGIC)
                    111:        cmp     r2,  r6,  r12
                    112:        bcnd    ne0, r2,  1f
                    113:        or.u    r13, r0,  hi16(_C_LABEL(esym))
                    114:        st      r7,  r13, lo16(_C_LABEL(esym))
                    115: 1:
                    116: #endif
                    117:
                    118:        /* set cputyp */
                    119:        ldcr    r1,  PID
                    120:        extu    r2,  r1,  8<8>
                    121:        bcnd.n  eq0, r2,  1f
                    122:         or.u   r13, r0,  hi16(_C_LABEL(cputyp))
                    123:        or.u    r8,  r0,  hi16(CPU_88110)
                    124:        br.n    2f
                    125:         or     r8,  r8,  lo16(CPU_88110)
                    126: 1:
                    127:        or.u    r8,  r0,  hi16(CPU_88100)
                    128:        or      r8,  r8,  lo16(CPU_88100)
                    129: 2:
                    130:        st      r8,  r13, lo16(_C_LABEL(cputyp))
                    131:
                    132:        /*
                    133:         * CPU Initialization
                    134:         *
                    135:         * I use r11 and r22 here because they're easy to not
                    136:         * get mixed up -- r10, for example, looks too similar
                    137:         * to r0 when not being careful....
                    138:         *
                    139:         * Ensure that the PSR is as we like:
                    140:         *      supervisor mode
                    141:         *      big-endian byte ordering
                    142:         *      concurrent operation allowed
                    143:         *      carry bit clear (I don't think we really care about this)
                    144:         *      FPU enabled
                    145:         *      misaligned access raises an exception
                    146:         *      interrupts disabled
                    147:         *      shadow registers frozen
                    148:         *
                    149:         * The manual says not to disable interrupts and freeze shadowing
                    150:         * at the same time because interrupts are not actually disabled
                    151:         * until after the next instruction. Well, if an interrupt
                    152:         * occurs now, we're in deep trouble anyway, so I'm going to do
                    153:         * the two together.
                    154:         *
                    155:         * Upon a reset (or poweron, I guess), the PSR indicates:
                    156:         *   supervisor mode
                    157:         *   interrupts, shadowing, FPU, misaligned exception: all disabled
                    158:         *
                    159:         * We'll just construct our own turning on what we want.
                    160:         *
                    161:         *      jfriedl@omron.co.jp
                    162:         */
                    163:
                    164:        cmp     r2, r8, CPU_88110       /* r8 contains cputyp */
                    165:        bb1     eq, r2, 1f      /* if it's a 'mc88110, skip SSBR */
                    166:        stcr    r0, SSBR        /* clear this for later */
                    167: 1:
                    168:        stcr    r0, SR1         /* clear the CPU flags */
                    169:
                    170:        set     r11, r0,  1<PSR_SUPERVISOR_MODE_BIT>
                    171:        set     r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
                    172:        set     r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
                    173:        /*
                    174:         * XXX On 88110 processors, force serial instruction execution for now.
                    175:         * Situation where OoO would break will be hopefully taken care of in
                    176:         * the near future -- miod
                    177:         */
                    178: #if 0
                    179:        clr     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    180: #else
                    181:        set     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    182: #endif
                    183:        set     r11, r11, 1<PSR_SERIALIZE_BIT>
                    184:        stcr    r11, PSR
                    185:        FLUSH_PIPELINE
                    186:
                    187:        /* save PROM vbr */
                    188:        ldcr    r12, VBR
                    189:        or.u    r13, r0,  hi16(_C_LABEL(prom_vbr))
                    190:        st      r12,  r13, lo16(_C_LABEL(prom_vbr))
                    191:        stcr    r0,  VBR
                    192:
                    193: #ifdef MULTIPROCESSOR
                    194:        /*
                    195:         * Have curcpu() point at the dummy cpuinfo structure,
                    196:         * so that cpu_number() does not dereference random memory.
                    197:         * This is necessary for early spl usage, despite the fact that
                    198:         * interrupts are disabled...
                    199:         */
                    200:        or.u    r11, r0,  hi16(_ASM_LABEL(dummy_cpu))
                    201:        or      r11, r11, lo16(_ASM_LABEL(dummy_cpu))
                    202:        stcr    r11, CPU
                    203:
                    204:        /*
                    205:         * SCM PROM idles all secondary MPUs upon startup, so at this point
                    206:         * we do not have to compete with them.
                    207:         */
                    208: #endif /* MULTIPROCESSOR */
                    209:
                    210:        /* Switch to interrupt stack */
                    211:        or.u    r31, r0,  hi16(_ASM_LABEL(intstack_end))
                    212:        or      r31, r31, lo16(_ASM_LABEL(intstack_end))
                    213:
                    214: #ifdef M88110
                    215: #ifdef M88100
                    216:        cmp     r2, r8, CPU_88110 /* r8 contains cputyp */
                    217:        bb1     ne, r2, 1f      /* if it's a 'mc88110, use different vectors */
                    218: #endif
                    219:        or.u    r3, r0, hi16(_C_LABEL(m88110_vector_list))
                    220:        br.n    2f
                    221:         or     r3, r3, lo16(_C_LABEL(m88110_vector_list))
                    222: 1:
                    223: #endif /* M88110 */
                    224: #ifdef M88100
                    225:        or.u    r3, r0, hi16(_C_LABEL(vector_list))
                    226:        or      r3, r3, lo16(_C_LABEL(vector_list))
                    227: #endif /* M88100 */
                    228: 2:
                    229:        bsr.n   _C_LABEL(vector_init)
                    230:         ldcr   r2, VBR
                    231:
                    232:        /*
                    233:         * aviion_bootstrap(), among other things, clears proc0's u area.
                    234:         * We are still using the interrupt stack here, thus we are not
                    235:         * affected...
                    236:         */
                    237:        bsr     _C_LABEL(aviion_bootstrap)
                    238:
                    239:        /*
                    240:         * ...and we can switch to the u area stack now.
                    241:         */
                    242:        ldcr    r10, CPU
                    243:        ld      r31, r10, CI_CURPCB
                    244:
                    245:        /* call main() - no arguments although main() still defines one */
                    246:        bsr.n   _C_LABEL(main)
                    247:         addu   r31, r31, USIZE
                    248:
                    249:        or.u    r2, r0, hi16(_ASM_LABEL(main_panic))
                    250:        bsr.n   _C_LABEL(panic)
                    251:         or     r2, r2, lo16(_ASM_LABEL(main_panic))
                    252:
                    253:        data
                    254:        .align  4
                    255: ASLOCAL(main_panic)
                    256:        string  "main() returned\0"
                    257:        text
                    258:        .align  8
                    259:
                    260: #ifdef MULTIPROCESSOR
                    261:
                    262:        /*
                    263:         * Startup code for secondary processors.
                    264:         * Some of these initializations are very close to main_start; refer
                    265:         * to the comments there for details.
                    266:         */
                    267: GLOBAL(secondary_start)
                    268:        or.u    r31, r0,  hi16(_ASM_LABEL(slavestack_end))
                    269:        or      r31, r31, lo16(_ASM_LABEL(slavestack_end))
                    270:
                    271:        or.u    r13, r0,  hi16(_C_LABEL(cputyp))
                    272:        ld      r8,  r13, lo16(_C_LABEL(cputyp))
                    273:
                    274:        cmp     r2, r8, CPU_88110
                    275:        bb1     eq, r2, 1f
                    276:        stcr    r0, SSBR
                    277: 1:
                    278:        stcr    r0, SR1
                    279:
                    280:        set     r11, r0,  1<PSR_SUPERVISOR_MODE_BIT>
                    281:        set     r11, r11, 1<PSR_INTERRUPT_DISABLE_BIT>
                    282:        set     r11, r11, 1<PSR_GRAPHICS_DISABLE_BIT>
                    283:        /*
                    284:         * XXX On 88110 processors, force serial instruction execution for now.
                    285:         * Situation where OoO would break will be hopefully taken care of in
                    286:         * the near future -- miod
                    287:         */
                    288: #if 0
                    289:        clr     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    290: #else
                    291:        set     r11, r11, 1<PSR_SERIAL_MODE_BIT>
                    292: #endif
                    293:        set     r11, r11, 1<PSR_SERIALIZE_BIT>
                    294:        stcr    r11, PSR
                    295:        FLUSH_PIPELINE
                    296:        stcr    r0,  VBR        /* set Vector Base Register to 0, ALWAYS! */
                    297:        FLUSH_PIPELINE
                    298:
                    299:        /*
                    300:         * Have curcpu() point at the dummy cpuinfo structure,
                    301:         * so that cpu_number() does not dereference random memory.
                    302:         * This is necessary for early spl usage, despite the fact that
                    303:         * interrupts are disabled...
                    304:         */
                    305:        or.u    r11, r0,  hi16(_ASM_LABEL(dummy_cpu))
                    306:        or      r11, r11, lo16(_ASM_LABEL(dummy_cpu))
                    307:        stcr    r11, CPU
                    308:
                    309:        /*
                    310:         * Since there may be more than one secondary MPU, compete with them
                    311:         * to initialize safely.
                    312:         */
                    313:        or.u    r11, r0,  hi16(_C_LABEL(cpu_mutex))
                    314:        or      r11, r11, lo16(_C_LABEL(cpu_mutex))
                    315: 1:
                    316:        or      r22, r0,  1
                    317:        xmem    r22, r11, r0            /* If r22 gets 0, we have the lock... */
                    318:        bcnd    eq0, r22, 4f            /* ...but if not, we must wait */
                    319: 2:
                    320:        /* just watch the lock until it looks clear */
                    321:        ld      r22, r11, r0
                    322:        bcnd    eq0, r22, 1b
                    323:        /* since we can be here with caches off, add a few nops to
                    324:           keep the bus from getting overloaded */
                    325:        or      r2,  r0,  lo16(1000)
                    326: 3:
                    327:        subu    r2,  r2,  1
                    328:        bcnd    ne0, r2,  3b
                    329:        br      1b
                    330: 4:
                    331:
                    332:        /*
                    333:         * While holding the cpu_mutex, the secondary cpu can use the slavestack
                    334:         * to call secondary_pre_main() to determine its cpu number.
                    335:         * After that, however, it should allocate its own stack and switch
                    336:         * to it.
                    337:         */
                    338:
                    339:        bsr     _C_LABEL(secondary_pre_main)    /* set cpu number */
                    340:
                    341:        ldcr    r2, CPU
                    342:        ld      r3, r2, CI_IDLE_PCB
                    343:        bsr.n   _C_LABEL(secondary_main)
                    344:         addu   r31, r3, USIZE                  /* switch to idle stack */
                    345:
                    346:        /*
                    347:         * At this point, the CPU has been correctly initialized and has
                    348:         * identified itself on the console.
                    349:         * All it needs now is to jump to the idle loop and wait for work to
                    350:         * be offered.
                    351:         */
                    352:        br      _ASM_LABEL(cpu_switch_idle)
                    353:
                    354: #endif /* MULTIPROCESSOR */
                    355:
                    356: /*
                    357:  * void delay(int us)
                    358:  *
                    359:  * The processor loops (busy waits) for the given number of microseconds:
                    360:  * Thus, delay(1000000) will delay for one second.
                    361:  * (originally from Mach 2.5)
                    362:  */
                    363: GLOBAL(delay)
                    364:        or.u    r3, r0, hi16(_cpuspeed)
                    365:        ld      r3, r3, lo16(_cpuspeed)
                    366:        mul     r4, r2, r3
                    367:        subu    r4, r4, 4       /* overhead of these instructions */
                    368:
                    369:        /* now loop for the given number of cycles */
                    370: 1:
                    371:        bcnd.n  gt0, r4, 1b
                    372:         subu   r4, r4, 2       /* two cycles per iteration */
                    373:
                    374:        jmp     r1
                    375:
                    376: /*****************************************************************************/
                    377:
                    378:        data
                    379:        .align  PAGE_SIZE
                    380: GLOBAL(kernel_sdt)             /* SDT (segment descriptor table */
                    381:        space   0x2000          /* 8K - 4K phys, 4K virt*/
                    382:
                    383:        .align  PAGE_SIZE
                    384: ASGLOBAL(intstack)
                    385:        space   USIZE
                    386: ASGLOBAL(intstack_end)
                    387:
                    388: #ifdef MULTIPROCESSOR
                    389:        space   PAGE_SIZE       /* 4K, small, interim stack */
                    390: ASLOCAL(slavestack_end)
                    391: #endif
                    392:
                    393: /*
                    394:  * Main processor's idle pcb and stack.
                    395:  * Should be page aligned.
                    396:  */
                    397:        .align  PAGE_SIZE
                    398: GLOBAL(idle_u)
                    399:        space   USIZE
                    400:
                    401: /*
                    402:  * Process 0's u.
                    403:  * Should be page aligned.
                    404:  */
                    405:        .align  PAGE_SIZE
                    406: ASLOCAL(u0)
                    407:        space   USIZE
                    408: GLOBAL(proc0paddr)
                    409:        word    _ASM_LABEL(u0)  /*  KVA of proc0 uarea */
                    410:
                    411: #ifdef MULTIPROCESSOR
                    412: /* Dummy cpuinfo structure, for cpu_number() to work early. */
                    413: ASLOCAL(dummy_cpu)
                    414:        word    1       /* ci_alive */
                    415:        word    0       /* ci_curproc */
                    416:        word    0       /* ci_curpcb */
                    417:        word    0       /* ci_cpuid */
                    418: #endif /* MULTIPROCESSOR */
                    419:
                    420: #if defined(DDB) || NKSYMS > 0
                    421: GLOBAL(esym)
                    422:        word    0
                    423: #endif /* DDB || NKSYMS > 0 */

CVSweb