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

Annotation of sys/arch/macppc/macppc/ofwreal.S, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ofwreal.S,v 1.3 2003/10/16 05:03:22 deraadt Exp $     */
                      2: /*     $NetBSD: ofwreal.S,v 1.1 1996/09/30 16:34:51 ws Exp $   */
                      3:
                      4: /*
                      5:  * Copyright (C) 1996 Wolfgang Solfrank.
                      6:  * Copyright (C) 1996 TooLs GmbH.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *     This product includes software developed by TooLs GmbH.
                     20:  * 4. The name of TooLs GmbH may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     27:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     28:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     29:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     30:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     31:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     32:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
                     36:  * This file provides a real-mode client interface on machines, that
                     37:  * (incorrectly) only implement virtual mode client interface.
                     38:  *
                     39:  * It assumes though, that any actual memory in the machine is
                     40:  * mapped 1:1 even by the virtual mode OpenFirmware.
                     41:  * Furthermore it assumes that addresses returned by OpenFirmware are not
                     42:  * accessed by the client.
                     43:  *
                     44:  */
                     45: #include <machine/asm.h>
                     46: #include <machine/psl.h>
                     47: #include <machine/trap.h>
                     48: #include <machine/param.h>
                     49:
                     50: #define        CACHELINE       32              /* Note that this value is really hardwired */
                     51:
                     52:        .data
                     53: ofentry:       .long   0               /* actual entry to firmware in virtual mode */
                     54:
                     55: #define        SRSIZE          (16*4+4)
                     56: #define        SPRGSIZE        (4*4)
                     57: #define        SDR1SIZE        4
                     58: #define MSRSIZE                4
                     59: #define        SVSIZE          (SRSIZE+SPRGSIZE+SDR1SIZE+MSRSIZE)
                     60: #define BATSIZE                (16*4)
                     61:
                     62:        .global _C_LABEL(fwcall)
                     63: _C_LABEL(fwcall): .long 0
                     64:
                     65: .lcomm fwsave,SVSIZE,8
                     66: .lcomm fwbatsave,BATSIZE,8
                     67: .lcomm clsave,SVSIZE,8
                     68: .lcomm clbatsave,BATSIZE,8
                     69: .lcomm ofsrsave,16*4,4 /* 16 words of 4 bytes to store OF segment registers */
                     70: .lcomm srsave,16*4,4   /* 16 words of 4 bytes to swap OF segment registers*/
                     71:        .globl _C_LABEL(ofmsr)
                     72: _C_LABEL(ofmsr):       .long   0       /* area to store msr for openfirmware*/
                     73:
                     74:        .text
                     75: _ENTRY(_C_LABEL(ofw_init))
                     76:        mflr    %r31                    /* save return address */
                     77:
                     78:        mr      %r13,%r6                /* save args (only pointer used) */
                     79:        lis     %r8,ofentry@ha
                     80:        stw     %r5,ofentry@l(%r8)      /* save virtual mode firmware entry */
                     81:
                     82:        lis     %r4,fwcall@ha           /* call ofw directly until vm setup */
                     83:        stw     %r5,fwcall@l(%r4)
                     84:
                     85:        mfmsr   %r5
                     86:        lis     %r4,_C_LABEL(ofmsr)@ha  /* save msr from openfirmware */
                     87:        stw     %r5,_C_LABEL(ofmsr)@l(%r4)
                     88: #if 0
                     89:        lis     %r0,(0x80001ffe)@ha
                     90:        addi    %r0,%r0,(0x80001ffe)@l
                     91:        mtdbatu 0,%r0
                     92:        lis     %r0,(0x80000022)@ha
                     93:        addi    %r0,%r0,(0x80000022)@l
                     94:        mtdbatl 0,%r0
                     95: #endif
                     96:
                     97:        lis     %r3,fwsave@ha   /* save the mmu values of the firmware */
                     98:        addi    %r3,%r3,fwsave@l
                     99:        lis     %r4,fwbatsave@ha
                    100:        addi    %r4,%r4,fwbatsave@l
                    101:        bl      savemmu
                    102:
                    103:        /* save openfirmware address mappings */
                    104:        bl      _C_LABEL(save_ofw_mapping)
                    105:
                    106: #if 0
                    107:        /* dont really need the bats from firmware saved, 0 to disable */
                    108:        lis     %r3,fwbatsave@ha
                    109:        addi    %r3,%r3,fwbatsave@l
                    110:        li      %r4,64
                    111:        li      %r5,0
                    112: 1:     subi    %r4,%r4,%r4
                    113:        stwx    %r5,%r4,%r3
                    114:        cmpi    4,0,0
                    115:        bne     1b
                    116: #endif
                    117:
                    118:        mr      %r6,%r13                /* restore args pointer */
                    119:        mtlr    %r31                    /* restore return address */
                    120:        blr
                    121:
                    122: /*
                    123:  * Save everyting related to the mmu to the saveare pointed to by r3.
                    124:  */
                    125:        .type   savemmu,@function
                    126: savemmu:
                    127:
                    128:        mr      %r6,%r4 /* r4 holds pointer to BAT save area */
                    129:
                    130:        li      %r4,0                   /* save SRs */
                    131: 1:
                    132:        addis   %r4,%r4,-0x10000000@ha
                    133:        or.     %r4,%r4,%r4
                    134:        mfsrin  %r5,%r4
                    135:        stwu    %r5,4(%r3)
                    136:        bne     1b
                    137:
                    138:        mfibatl %r4,0                   /* save BATs */
                    139:        stw     %r4,0(%r6)
                    140:        mfibatu %r4,0
                    141:        stw     %r4,4(%r6)
                    142:        mfibatl %r4,1
                    143:        stw     %r4,8(%r6)
                    144:        mfibatu %r4,1
                    145:        stw     %r4,0xc(%r6)
                    146:        mfibatl %r4,2
                    147:        stw     %r4,0x10(%r6)
                    148:        mfibatu %r4,2
                    149:        stw     %r4,0x14(%r6)
                    150:        mfibatl %r4,3
                    151:        stw     %r4,0x18(%r6)
                    152:        mfibatu %r4,3
                    153:        stw     %r4,0x1c(%r6)
                    154:        mfdbatl %r4,0
                    155:        stw     %r4,0x20(%r6)
                    156:        mfdbatu %r4,0
                    157:        stw     %r4,0x24(%r6)
                    158:        mfdbatl %r4,1
                    159:        stw     %r4,0x28(%r6)
                    160:        mfdbatu %r4,1
                    161:        stw     %r4,0x2c(%r6)
                    162:        mfdbatl %r4,2
                    163:        stw     %r4,0x30(%r6)
                    164:        mfdbatu %r4,2
                    165:        stw     %r4,0x34(%r6)
                    166:        mfdbatl %r4,3
                    167:        stw     %r4,0x38(%r6)
                    168:        mfdbatu %r4,3
                    169:        stw     %r4,0x3c(%r6)
                    170:
                    171:        mfsprg  %r4,0                   /* save SPRGs */
                    172:        stw     %r4,4(%r3)
                    173:        mfsprg  %r4,1
                    174:        stw     %r4,8(%r3)
                    175:        mfsprg  %r4,2
                    176:        stw     %r4,12(%r3)
                    177:        mfsprg  %r4,3
                    178:        stw     %r4,16(%r3)
                    179:
                    180:        mfsdr1  %r4                     /* save SDR1 */
                    181:        stw     %r4,20(%r3)
                    182:
                    183:        addi    %r4,%r3,24
                    184:
                    185:        mfmsr   %r4
                    186:        stw     %r4,24(%r3)
                    187:
                    188:        sync
                    189:        isync
                    190:
                    191:        blr
                    192:
                    193: /*
                    194:  * Restore everyting related to the mmu from the savearea pointed to by r3.
                    195:  * and bats pointed to by r4.
                    196:  */
                    197:        .type   restoremmu,@function
                    198: restoremmu:
                    199:
                    200:        li      %r0,0
                    201:        mtmsr   %r0
                    202:        mr      %r6,%r4                 /* pointer to sr to restore */
                    203:        li      %r4,0                   /* restore SRs */
                    204: 1:
                    205:        lwzu    %r5,4(%r3)
                    206:        addis   %r4,%r4,-0x10000000@ha
                    207:        or.     %r4,%r4,%r4
                    208:        mtsrin  %r5,%r4
                    209:        bne     1b
                    210:
                    211:        mfmsr   %r4
                    212:        lis     %r5,(PSL_IR|PSL_DR)@h           /* turn off MMU */
                    213:        ori     %r5,%r5,(PSL_IR|PSL_DR)@l       /* turn off MMU */
                    214:        andc    %r4,%r4,%r5                             /* turn off MMU */
                    215:        mtmsr   %r4
                    216:        isync
                    217:
                    218:        li      %r4,0                   /* first, invalidate BATs */
                    219:        mtibatu 0,%r4
                    220:        mtibatu 1,%r4
                    221:        mtibatu 2,%r4
                    222:        mtibatu 3,%r4
                    223:        mtdbatu 0,%r4
                    224:        mtdbatu 1,%r4
                    225:        mtdbatu 2,%r4
                    226:        mtdbatu 3,%r4
                    227:
                    228:        lwz     %r4,0(%r6)
                    229:        mtibatl 0,%r4                   /* restore BATs */
                    230:        lwz     %r4,4(%r6)
                    231:        mtibatu 0,%r4
                    232:        lwz     %r4,8(%r6)
                    233:        mtibatl 1,%r4
                    234:        lwz     %r4,12(%r6)
                    235:        mtibatu 1,%r4
                    236:        lwz     %r4,16(%r6)
                    237:        mtibatl 2,%r4
                    238:        lwz     %r4,20(%r6)
                    239:        mtibatu 2,%r4
                    240:        lwz     %r4,24(%r6)
                    241:        mtibatl 3,%r4
                    242:        lwz     %r4,28(%r6)
                    243:        mtibatu 3,%r4
                    244:        lwz     %r4,32(%r6)
                    245:        mtdbatl 0,%r4
                    246:        lwz     %r4,36(%r6)
                    247:        mtdbatu 0,%r4
                    248:        lwz     %r4,40(%r6)
                    249:        mtdbatl 1,%r4
                    250:        lwz     %r4,44(%r6)
                    251:        mtdbatu 1,%r4
                    252:        lwz     %r4,48(%r6)
                    253:        mtdbatl 2,%r4
                    254:        lwz     %r4,52(%r6)
                    255:        mtdbatu 2,%r4
                    256:        lwz     %r4,56(%r6)
                    257:        mtdbatl 3,%r4
                    258:        lwz     %r4,60(%r6)
                    259:        mtdbatu 3,%r4
                    260:
                    261:        lwz     %r4,4(%r3)
                    262:        mtsprg  0,4                     /* restore SPRGs */
                    263:        lwz     %r4,8(%r3)
                    264:        mtsprg  1,4
                    265:        lwz     %r4,12(%r3)
                    266:        mtsprg  2,4
                    267:        lwz     %r4,16(%r3)
                    268:        mtsprg  3,4
                    269:
                    270:        sync                            /* remove everything from tlb */
                    271:        lis     %r4,0x40000@ha
                    272:        li      %r5,0x1000
                    273: 1:
                    274:        subf.   %r4,%r5,%r4
                    275:        tlbie   %r4
                    276:        bne     1b
                    277:
                    278:        sync
                    279:        tlbsync
                    280:        sync
                    281:
                    282:        lwz     %r4,20(%r3)
                    283:        sync
                    284:        mtsdr1  %r4                     /* restore SDR1 */
                    285:
                    286:
                    287:        /* tlbia */
                    288:        sync
                    289:        li      %r5,0x40
                    290:        mtctr   %r5
                    291:        li      %r4,0
                    292:     1:
                    293:        tlbie   %r4
                    294:        addi    %r4,%r4,0x1000
                    295:        bdnz    1b
                    296:        sync
                    297:        tlbsync
                    298:        sync
                    299:
                    300:        lwz     %r4,24(%r3)
                    301:        mtmsr   %r4
                    302:        isync
                    303:
                    304:        blr
                    305:
                    306:
                    307: _ENTRY(_C_LABEL(fwentry))
                    308:        stwu    %r1,-16(%r1)
                    309:        mflr    %r4
                    310:        stw     %r4,20(%r1)
                    311:        stw     %r3,12(%r1)                     /* save arg */
                    312:
                    313:        lis     %r3,clsave@ha           /* save mmu values of client */
                    314:        addi    %r3,%r3,clsave@l
                    315:        lis     %r4,clbatsave@ha        /* save mmu values of client */
                    316:        addi    %r4,%r4,clbatsave@l
                    317:        bl      savemmu
                    318:
                    319:        lis     %r3,fwsave@ha           /* restore mmu values of firmware */
                    320:        addi    %r3,%r3,fwsave@l
                    321:        lis     %r4,fwbatsave@ha
                    322:        addi    %r4,%r4,fwbatsave@l
                    323:        bl      restoremmu
                    324:
                    325:        lis     %r3,ofentry@ha
                    326:        lwz     %r3,ofentry@l(%r3)      /* get actual firmware entry */
                    327:        mtlr    %r3
                    328:
                    329:        mfmsr   %r4
                    330:        ori     %r4,%r4,PSL_IR|PSL_DR   /* turn on MMU */
                    331:        mtmsr   %r4
                    332:        isync
                    333:
                    334:        lwz     %r3,12(%r1)             /* restore arg */
                    335:        blrl                            /* do actual firmware call */
                    336:
                    337:        stw     %r3,12(%r1)             /* save return value */
                    338:
                    339:        lis     %r3,fwsave@ha           /* save mmu values of firmare */
                    340:        addi    %r3,%r3,fwsave@l        /* (might not be necessary, but... */
                    341:        lis     %r4,fwbatsave@ha
                    342:        addi    %r4,%r4,fwbatsave@l
                    343:        bl      savemmu
                    344:
                    345:        lis     %r3,clsave@ha           /* restore mmu values of client */
                    346:        addi    %r3,%r3,clsave@l
                    347:        lis     %r4,clbatsave@ha        /* save mmu values of client */
                    348:        addi    %r4,%r4,clbatsave@l
                    349:        bl      restoremmu
                    350:
                    351:        lwz     %r4,20(%r1)
                    352:        lwz     %r3,12(%r1)             /* restore return value */
                    353:
                    354:        mtlr    %r4
                    355:        addi    %r1,%r1,16
                    356:        blr
                    357:
                    358: /*
                    359:  * OpenFirmware entry point
                    360:  */
                    361: _ENTRY(_C_LABEL(openfirmware))
                    362:        stwu    %r1,-16(%r1)
                    363:        mflr    %r0                     /* save return address */
                    364:        stw     %r0,20(%r1)
                    365:
                    366:        lis     %r4,fwcall@ha
                    367:        lwz     %r4,fwcall@l(%r4)
                    368:
                    369:        mtlr    %r4
                    370:        blrl
                    371:
                    372:        lwz     %r0,20(%r1)
                    373:        mtlr    %r0
                    374:        lwz     %r1,0(%r1)
                    375:        blr
                    376:
                    377: /*
                    378:  * Switch to/from OpenFirmware real mode stack
                    379:  *
                    380:  * Note: has to be called as the very first thing in OpenFirmware interface routines.
                    381:  * E.g.:
                    382:  * int
                    383:  * OF_xxx(arg1, arg2)
                    384:  * type arg1, arg2;
                    385:  * {
                    386:  *     static struct {
                    387:  *             char *name;
                    388:  *             int nargs;
                    389:  *             int nreturns;
                    390:  *             char *method;
                    391:  *             int arg1;
                    392:  *             int arg2;
                    393:  *             int ret;
                    394:  *     } args = {
                    395:  *             "xxx",
                    396:  *             2,
                    397:  *             1,
                    398:  *     };
                    399:  *
                    400:  *     ofw_stack();
                    401:  *     args.arg1 = arg1;
                    402:  *     args.arg2 = arg2;
                    403:  *     if (openfirmware(&args) < 0)
                    404:  *             return -1;
                    405:  *     return args.ret;
                    406:  * }
                    407:  */
                    408: .lcomm firmstk,NBPG,16
                    409: .comm  _C_LABEL(OF_buf),NBPG,PGOFSET
                    410:
                    411: _ENTRY(_C_LABEL(ofw_stack))
                    412:        mfmsr   %r8                     /* turn off interrupts */
                    413:        andi.   %r0,%r8,~(PSL_EE|PSL_RI)@l
                    414:        mtmsr   %r0
                    415:        stw     %r8,4(%r1)              /* abuse return address slot */
                    416:
                    417:        lwz     %r5,0(%r1)              /* get length of stack frame */
                    418:        subf    %r5,%r1,%r5
                    419:
                    420:        lis     %r7,firmstk+NBPG-8@ha
                    421:        addi    %r7,%r7,firmstk+NBPG-8@l
                    422:        li      %r6,0xf
                    423:        andc    %r7,%r7,%r6
                    424:        lis     %r6,ofw_back@ha
                    425:        addi    %r6,%r6,ofw_back@l
                    426:        subf    %r4,%r5,%r7             /* make room for stack frame on new stack */
                    427:        stwu    %r1,-16(%r7)
                    428:        stw     %r6,4(%r7)              /* setup return pointer */
                    429:
                    430:        stw     %r7,-16(%r4)
                    431:
                    432:        addi    %r3,%r1,%r8
                    433:        addi    %r1,%r4,-16
                    434:        subi    %r5,%r5,%r8
                    435:        subi    %r4,%r4,%r8
                    436:
                    437:        b       _C_LABEL(ofbcopy)       /* and copy it */
                    438:
                    439:        .type ofw_back,@function
                    440: ofw_back:
                    441:        lwz     %r1,0(%r1)              /* get callers original stack pointer */
                    442:
                    443:        lwz     %r0,4(%r1)              /* get saved msr from abused slot */
                    444:        mtmsr   %r0
                    445:
                    446:        lwz     %r1,0(%r1)              /* return */
                    447:        lwz     %r0,4(%r1)
                    448:        mtlr    %r0
                    449:        blr
                    450:

CVSweb