Annotation of qemu/roms/openbios/arch/sparc32/entry.S, revision 1.1

1.1     ! root        1: /**
        !             2:  ** Standalone startup code for Linux PROM emulator.
        !             3:  ** Copyright 1999 Pete A. Zaitcev
        !             4:  ** This code is licensed under GNU General Public License.
        !             5:  **/
        !             6: /*
        !             7:  * $Id: head.S,v 1.12 2002/07/23 05:47:09 zaitcev Exp $
        !             8:  */
        !             9: 
        !            10: #include "psr.h"
        !            11: #include "asm/asi.h"
        !            12: #include "asm/crs.h"
        !            13: #define NO_QEMU_PROTOS
        !            14: #define NO_OPENBIOS_PROTOS
        !            15: #include "arch/common/fw_cfg.h"
        !            16: 
        !            17: #define CFG_ADDR 0x00000510
        !            18: #define CFG_ASI  0x2d
        !            19: 
        !            20: #define PHYS_JJ_INTR0  0x71E00000  /* CPU0 interrupt control registers */
        !            21: 
        !            22: #define PHYS_SS10_INTR0        0xf1400000
        !            23: 
        !            24: #define PHYS_SS2_INTR0         0xf5000000
        !            25: #define SER_ADDR2       0xf1000004
        !            26: 
        !            27: #define PHYS_SS1000_SBI         0x02800000
        !            28: #define SER_ADDR1000            0x00200004
        !            29: 
        !            30: #define WRITE_PAUSE    nop; nop; nop; /* Have to do this after %wim/%psr chg */
        !            31: 
        !            32:         .globl entry, _entry
        !            33: 
        !            34:        .section ".text", "ax"
        !            35:        .align  8
        !            36: 
        !            37:         /* Memory map:
        !            38:         *
        !            39:         * Top +-------------------------+
        !            40:         *     | SMP CPU table           |
        !            41:         *     | s + 0x1f00 ... 0x1f0f   |
        !            42:         *     | s + 0x1f0c valid        |
        !            43:         *     | s + 0x1f08 entry        |
        !            44:         *     | s + 0x1f04 ctxtbl       |
        !            45:         *     | s + 0x1f00 ctx          |
        !            46:         *     +-------------------------+
        !            47:         *     | Bootstrap               |
        !            48:         *     | MMU L3 tables 8 * 0x100 |
        !            49:         *     | s + 0xa00 ... 0x11ff    |
        !            50:         *     +-------------------------+
        !            51:         *     | Bootstrap               |
        !            52:         *     | MMU L2 tables 2 * 0x100 |
        !            53:         *     | s + 0x800 ... 0x9ff     |
        !            54:         *     +-------------------------+
        !            55:         *     | Bootstrap               |
        !            56:         *     | MMU L1 table 0x400      |
        !            57:         *     | s + 0x400 ... 0x7ff     |
        !            58:         *     +-------------------------+
        !            59:         *     | Bootstrap               |
        !            60:         *     | MMU L0/ctx table 0x400  |
        !            61:         *     | s + 0x000 ... 0x3ff     |
        !            62:         *     +-------------------------+
        !            63:         *     |                         |
        !            64:         *     | ROM into RAM            |
        !            65:         *     |                         |
        !            66:         *     +-------------------------+
        !            67:         *     :                         :
        !            68:         * Bottom
        !            69:         */
        !            70: 
        !            71: /*
        !            72:  * Entry point
        !            73:  * We start execution from here.
        !            74:  */
        !            75: _entry:
        !            76: entry:
        !            77:         /* Switch to our main context.
        !            78:          * Main context is statically defined in C.
        !            79:          */
        !            80: 
        !            81:         ! Check signature "QEMU"
        !            82:         set     CFG_ADDR, %g5
        !            83:         mov     FW_CFG_SIGNATURE, %g2
        !            84:         stha    %g2, [%g5] CFG_ASI
        !            85:         add     %g5, 2, %g5
        !            86:         lduba   [%g5] CFG_ASI, %g2
        !            87:         cmp     %g2, 'Q'
        !            88:         bne     bad_conf
        !            89:          nop
        !            90:         lduba   [%g5] CFG_ASI, %g2
        !            91:         cmp     %g2, 'E'
        !            92:         bne     bad_conf
        !            93:          nop
        !            94:         lduba   [%g5] CFG_ASI, %g2
        !            95:         cmp     %g2, 'M'
        !            96:         bne     bad_conf
        !            97:          nop
        !            98:         lduba   [%g5] CFG_ASI, %g2
        !            99:         cmp     %g2, 'U'
        !           100:         bne     bad_conf
        !           101:          nop
        !           102: 
        !           103:         ! Get memory size from configuration device
        !           104:         ! NB: little endian format
        !           105:         mov     FW_CFG_RAM_SIZE, %g2
        !           106:         sub     %g5, 2, %g5
        !           107:         stha    %g2, [%g5] CFG_ASI
        !           108:         add     %g5, 2, %g5
        !           109:         lduba   [%g5] CFG_ASI, %g4
        !           110: 
        !           111:         lduba   [%g5] CFG_ASI, %g3
        !           112:         sll     %g3, 8, %g3
        !           113:         or      %g3, %g4, %g4
        !           114: 
        !           115:         lduba   [%g5] CFG_ASI, %g3
        !           116:         sll     %g3, 16, %g3
        !           117:         or      %g3, %g4, %g4
        !           118: 
        !           119:         lduba   [%g5] CFG_ASI, %g3
        !           120:         sll     %g3, 24, %g3
        !           121:         or      %g3, %g4, %g1
        !           122:         ! %g1 contains end of memory
        !           123: 
        !           124: 
        !           125:         ! Start of private memory in %g6
        !           126:         set     0x2000, %g3
        !           127:         sub     %g1, %g3, %g6
        !           128: 
        !           129:         ! Calculate SMP table location
        !           130:        set     0x1f0c, %g2
        !           131:         add     %g6, %g2, %g2                 ! valid?
        !           132:         lda     [%g2] ASI_M_BYPASS, %g7
        !           133:         sta     %g0, [%g2] ASI_M_BYPASS
        !           134: 
        !           135:         ! Get machine ID from configuration device
        !           136:         mov     FW_CFG_MACHINE_ID, %g2
        !           137:         sub     %g5, 2, %g5
        !           138:         stha    %g2, [%g5] CFG_ASI
        !           139:         add     %g5, 2, %g5
        !           140:         lduba   [%g5] CFG_ASI, %g4
        !           141: 
        !           142:         lduba   [%g5] CFG_ASI, %g3
        !           143:         sll     %g3, 8, %g3
        !           144:         or      %g3, %g4, %g4
        !           145:         mov     %g4, %y
        !           146: 
        !           147:         cmp     %g4, 96
        !           148:         bgeu    ss1000
        !           149:          cmp    %g4, 64
        !           150:         bgeu    ss10
        !           151:          cmp    %g4, 32
        !           152:         blu     ss2
        !           153:          nop
        !           154: 
        !           155:         ! Ok, this is SS-5
        !           156: 
        !           157:         tst     %g7
        !           158:         bz      first_cpu
        !           159:          nop
        !           160: 
        !           161:         ! Clear softints used for SMP CPU startup
        !           162:         set     PHYS_JJ_INTR0 + 0x04, %g1
        !           163:         sll     %g2, 12, %g2
        !           164:         add     %g1, %g2, %g2
        !           165:         set     0xffffffff, %g1
        !           166:         sta     %g1, [%g2] ASI_M_BYPASS         ! clear softints
        !           167:         add     %g2, 4, %g2
        !           168:         sta     %g0, [%g2] ASI_M_BYPASS         ! clear softints
        !           169: 
        !           170: load_ctx:
        !           171:         ! SMP init, jump to user specified address
        !           172:        set     0x1f04, %g5
        !           173:         add     %g6, %g5, %g5                 ! ctxtbl
        !           174:         lda     [%g5] ASI_M_BYPASS, %g2
        !           175:         sta     %g0, [%g5] ASI_M_BYPASS
        !           176:         set     AC_M_CTPR, %g1
        !           177:         sta     %g2, [%g1] ASI_M_MMUREGS        ! set ctx table ptr
        !           178:        set     0x1f00, %g5
        !           179:         add     %g6, %g5, %g5                 ! ctx
        !           180:         lda     [%g5] ASI_M_BYPASS, %g2
        !           181:         sta     %g0, [%g5] ASI_M_BYPASS
        !           182:         set     AC_M_CXR, %g1
        !           183:         sta     %g2, [%g1] ASI_M_MMUREGS        ! set context
        !           184:        set     0x1f08, %g5
        !           185:         add     %g6, %g5, %g5                 ! entry
        !           186:         lda     [%g5] ASI_M_BYPASS, %g2
        !           187:         sta     %g0, [%g5] ASI_M_BYPASS
        !           188:         set     1, %g1
        !           189:         jmp     %g2                             ! jump to kernel
        !           190:          sta    %g1, [%g0] ASI_M_MMUREGS        ! enable mmu
        !           191: 
        !           192: ss10:
        !           193:         ! Ok, this is SS-10 or SS-600MP
        !           194:         tst     %g7
        !           195:         bz      first_cpu
        !           196:          nop
        !           197: 
        !           198:         ! Clear softints used for SMP CPU startup
        !           199:         set     PHYS_SS10_INTR0 + 0x04, %g1
        !           200:         sll     %g2, 12, %g2
        !           201:         add     %g1, %g2, %g2
        !           202:         set     0xffffffff, %g1
        !           203:         sta     %g1, [%g2] ASI_M_CTL            ! clear softints
        !           204:         add     %g2, 4, %g2
        !           205:         b       load_ctx
        !           206:          sta    %g0, [%g2] ASI_M_CTL            ! clear softints
        !           207: 
        !           208: ss2:
        !           209:         ! Ok, this is SS-2
        !           210:         set     ss2_error, %o2
        !           211:         b       ss2_ss1000_halt
        !           212:          nop
        !           213: 
        !           214: ss1000:
        !           215:         ! Ok, this is SS-1000 or SS-2000
        !           216:         set     ss1000_error, %o2
        !           217:         b       ss2_ss1000_halt
        !           218:          nop
        !           219: 
        !           220: first_cpu:
        !           221:         /* Create temporary page tables and map the ROM area to end of
        !           222:        RAM. This will be done properly in iommu.c later. */
        !           223:         ! Calculate start of page tables etc. to %g6
        !           224:         set     0x2000, %g4
        !           225:         sub     %g1, %g4, %g6                   ! start of private memory
        !           226: 
        !           227:         mov     %g6, %g2                        ! ctx table at s+0x0
        !           228:         add    %g2, 0x400, %g3                 ! l1 table at s+0x400
        !           229:         srl    %g3, 0x4, %g3
        !           230:         or     %g3, 0x1, %g3
        !           231:         sta    %g3, [%g2] ASI_M_BYPASS
        !           232:         add    %g2, 0x400, %g2                 ! s+0x400
        !           233:         add    %g2, 0x400, %g3                 ! l2 table for ram (00xxxxxx) at s+0x800
        !           234:         srl    %g3, 0x4, %g3
        !           235:         or     %g3, 0x1, %g3
        !           236:         sta    %g3, [%g2] ASI_M_BYPASS
        !           237:         add    %g2, 0x500, %g3                 ! l2 table for rom (ffxxxxxx) at s+0x900
        !           238:         add    %g2, 0x3fc, %g2                 ! s+0x7fc
        !           239:         srl    %g3, 0x4, %g3
        !           240:         or     %g3, 0x1, %g3
        !           241:         sta    %g3, [%g2] ASI_M_BYPASS
        !           242:         add    %g2, 0x4, %g2                   ! s+0x800
        !           243: #if 0
        !           244:         set     0x40, %g6
        !           245:         set    ((7 << 2) | 2), %g3             ! 7 = U: --- S: RWX (main memory)
        !           246: 1:      sta    %g3, [%g2] ASI_M_BYPASS
        !           247:         add     %g2, 4, %g2
        !           248:         deccc   %g6
        !           249:         bne     1b
        !           250:          nop
        !           251: #else
        !           252:         add     %g2, 0x100, %g2
        !           253: #endif
        !           254:                                                 ! s+0x900
        !           255:         add    %g2, 0xa00 - 0x900, %g3         ! l3 table for rom at s+0xa00
        !           256:         add    %g2, 0x0d0, %g2                 ! s+0x9d0
        !           257:         srl    %g3, 0x4, %g3
        !           258:         or     %g3, 0x1, %g3
        !           259:         sta    %g3, [%g2] ASI_M_BYPASS
        !           260:         add    %g2, 4, %g2                     ! s+0x9d4
        !           261:         add    %g2, 0xb00 - 0x9d4, %g3         ! 2nd l3 table for rom at s+0xb00
        !           262:         srl    %g3, 0x4, %g3
        !           263:         or     %g3, 0x1, %g3
        !           264:         sta    %g3, [%g2] ASI_M_BYPASS
        !           265:         add    %g2, 4, %g2                     ! s+0x9d8
        !           266:         add    %g2, 0xc00 - 0x9d8, %g3         ! 3rd l3 table for rom at s+0xc00
        !           267:         srl    %g3, 0x4, %g3
        !           268:         or     %g3, 0x1, %g3
        !           269:         sta    %g3, [%g2] ASI_M_BYPASS
        !           270:         add    %g2, 4, %g2                     ! s+0x9dc
        !           271:         add    %g2, 0xd00 - 0x9dc, %g3         ! 4th l3 table for rom at s+0xd00
        !           272:         srl    %g3, 0x4, %g3
        !           273:         or     %g3, 0x1, %g3
        !           274:         sta    %g3, [%g2] ASI_M_BYPASS
        !           275:         add    %g2, 4, %g2                     ! s+0x9e0
        !           276:         add    %g2, 0xe00 - 0x9e0, %g3         ! 5th l3 table for rom at s+0xe00
        !           277:         srl    %g3, 0x4, %g3
        !           278:         or     %g3, 0x1, %g3
        !           279:         sta    %g3, [%g2] ASI_M_BYPASS
        !           280:         add    %g2, 4, %g2                     ! s+0x9e4
        !           281:         add    %g2, 0xf00 - 0x9e4, %g3         ! 6th l3 table for rom at s+0xf00
        !           282:         srl    %g3, 0x4, %g3
        !           283:         or     %g3, 0x1, %g3
        !           284:         sta    %g3, [%g2] ASI_M_BYPASS
        !           285:         add    %g2, 4, %g2                     ! s+0x9e8
        !           286:         add    %g2, 0x1000 - 0x9e8, %g3        ! 7th l3 table for rom at s+0x1000
        !           287:         srl    %g3, 0x4, %g3
        !           288:         or     %g3, 0x1, %g3
        !           289:         sta    %g3, [%g2] ASI_M_BYPASS
        !           290:         add    %g2, 4, %g2                     ! s+0x9ec
        !           291:         add    %g2, 0x1100 - 0x9ec, %g3        ! 8th l3 table for rom at s+0x1100
        !           292:         srl    %g3, 0x4, %g3
        !           293:         or     %g3, 0x1, %g3
        !           294:         sta    %g3, [%g2] ASI_M_BYPASS
        !           295:       add      %g2, 0xa00-0x9ec, %g2           ! s+0xa00
        !           296: 
        !           297:         /* Use end of ram for code, rodata, data, and bss
        !           298:        sections. SunOS wants to write to trap table... */
        !           299:         set    _end, %g6
        !           300:         set    _start, %g4
        !           301:         sub     %g6, %g4, %g6
        !           302:         sub     %g1, %g6, %g3
        !           303:         set    0x1000, %g5
        !           304:         sub     %g3, %g5, %g3
        !           305:         sub     %g3, %g5, %g3                   ! start of ROM copy
        !           306:         mov     %g3, %g7                        ! save in %g7
        !           307:         srl     %g6, 12, %g6                    ! # of all pages
        !           308: 1:      srl    %g3, 0x4, %g4
        !           309:         or     %g4, ((7 << 2) | 2), %g4        ! 7 = U: --- S: RWX
        !           310:         sta    %g4, [%g2] ASI_M_BYPASS
        !           311:         add    %g2, 4, %g2
        !           312:         add    %g3, %g5, %g3
        !           313:         deccc  %g6
        !           314:         bne    1b
        !           315:          nop
        !           316: 
        !           317:         mov    %g1, %g6                        ! %g6 = memory size
        !           318: 
        !           319:         /* Copy the code, rodata and data sections from ROM. */
        !           320:         sub     %g7, 4, %g3
        !           321:         set    _start - 4, %g4                 ! First address of TEXT - 4
        !           322:         set    _bss, %g5                       ! Last address of DATA
        !           323:         ba     2f
        !           324:          nop
        !           325: 1:
        !           326:         lda     [%g4] ASI_M_KERNELTXT, %g1
        !           327:         sta    %g1, [%g3] ASI_M_BYPASS
        !           328: 2:
        !           329:         cmp     %g4, %g5
        !           330:         add     %g3, 0x4, %g3
        !           331:         bl      1b
        !           332:          add    %g4, 0x4, %g4
        !           333: 
        !           334:         set     0x2000, %g3
        !           335:         sub     %g6, %g3, %g7                   ! ctx table at s+0x0
        !           336:         set     AC_M_CTPR, %g2
        !           337:         srl     %g7, 4, %g7
        !           338:         sta     %g7, [%g2] ASI_M_MMUREGS       ! set ctx table ptr
        !           339:         set     AC_M_CXR, %g2
        !           340:         sta     %g0, [%g2] ASI_M_MMUREGS       ! context 0
        !           341:         set     highmem, %g2
        !           342:         set    1, %g1
        !           343:         jmp     %g2
        !           344:          sta    %g1, [%g0] ASI_M_MMUREGS       ! enable mmu
        !           345: highmem:
        !           346:         /*
        !           347:          * The code which enables traps is a simplified version of
        !           348:          * kernel head.S.
        !           349:          *
        !           350:          * We know number of windows as 8 so we do not calculate them.
        !           351:          * The deadwood is here for any case.
        !           352:          */
        !           353: 
        !           354:         /* Turn on Supervisor, EnableFloating, and all the PIL bits.
        !           355:          * Also puts us in register window zero with traps off.
        !           356:          */
        !           357:         set    (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
        !           358:         wr     %g2, 0x0, %psr
        !           359:         WRITE_PAUSE
        !           360: 
        !           361:         /* Zero out our BSS section. */
        !           362:         set    _bss - 4, %o0           ! First address of BSS
        !           363:         set    _estack - 4, %o1        ! Last address of BSS
        !           364:         ba     2f
        !           365:          nop
        !           366: 1:
        !           367:         st     %g0, [%o0]
        !           368: 2:
        !           369:         subcc  %o0, %o1, %g0
        !           370:         bl     1b
        !           371:          add   %o0, 0x4, %o0
        !           372: 
        !           373:         set     trap_table, %g1
        !           374:         wr      %g1, 0x0, %tbr
        !           375: 
        !           376:         set     qemu_mem_size, %g1
        !           377:         st      %g6, [%g1]
        !           378: 
        !           379:         set     _end, %o0                       ! Store va->pa conversion factor
        !           380:         set     _start, %o2
        !           381:         sub     %o0, %o2, %o0
        !           382:         sub     %g6, %o0, %o0
        !           383:         set     0x2000, %o1
        !           384:         sub     %o0, %o1, %o0                   ! start of ROM copy
        !           385:         sub     %o2, %o0, %o0                   ! start of ROM copy
        !           386:         set     va_shift, %g1
        !           387:         st      %o0, [%g1]
        !           388: 
        !           389:         set     qemu_machine_type, %g1
        !           390:         mov     %y, %g2
        !           391:         st      %g2, [%g1]
        !           392: 
        !           393:         /* Compute NWINDOWS and stash it away. Now uses %wim trick explained
        !           394:          * in the V8 manual. Ok, this method seems to work, Sparc is cool...
        !           395:          * No, it doesn't work, have to play the save/readCWP/restore trick.
        !           396:          */
        !           397: 
        !           398:         wr      %g0, 0x0, %wim                  ! so we do not get a trap
        !           399:         WRITE_PAUSE
        !           400: 
        !           401:         save
        !           402: 
        !           403:         rd      %psr, %g3
        !           404: 
        !           405:         restore
        !           406: 
        !           407:         and     %g3, 0x1f, %g3
        !           408:         add     %g3, 0x1, %g3
        !           409: 
        !           410:         mov     2, %g1
        !           411:         wr      %g1, 0x0, %wim                  ! make window 1 invalid
        !           412:         WRITE_PAUSE
        !           413: 
        !           414:         cmp     %g3, 0x7
        !           415:         bne     1f
        !           416:          nop
        !           417: 
        !           418:         /* Adjust our window handling routines to
        !           419:          * do things correctly on 7 window Sparcs.
        !           420:          */
        !           421: #define PATCH_INSN(src, dest) \
        !           422:         set     src, %g5; \
        !           423:         set     dest, %g2; \
        !           424:         ld      [%g5], %g4; \
        !           425:         st      %g4, [%g2];
        !           426: 
        !           427:         /* Patch for window spills... */
        !           428:         PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
        !           429:         PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
        !           430: 
        !           431:         /* Patch for window fills... */
        !           432:         PATCH_INSN(fnwin_patch1_7win, fnwin_patch1)
        !           433:         PATCH_INSN(fnwin_patch2_7win, fnwin_patch2)
        !           434: 
        !           435: 1:
        !           436:         /* Finally, turn on traps so that we can call c-code. */
        !           437:         rd     %psr, %g3
        !           438:         wr     %g3, 0x0, %psr
        !           439:         WRITE_PAUSE
        !           440: 
        !           441:         wr     %g3, PSR_ET, %psr
        !           442:         WRITE_PAUSE
        !           443: 
        !           444:         call    __switch_context_nosave
        !           445:          nop
        !           446: 
        !           447:         /* We get here when the main context switches back to
        !           448:          * the boot context.
        !           449:          * Return to previous bootloader.
        !           450:          */
        !           451:         ret
        !           452:          nop
        !           453: 
        !           454: ss2_ss1000_halt:
        !           455:         set     SER_ADDR2, %o0
        !           456:         set     SER_ADDR1000, %o1
        !           457:         mov     0x05, %o3 /* Reg 5, TXCTRL2 */
        !           458:         stba    %o3, [%o0] ASI_M_BYPASS
        !           459:         stba    %o3, [%o1] ASI_M_CTL
        !           460:         mov     0x68, %o3 /* 8 bits, Tx enabled */
        !           461:         stba    %o3, [%o0] ASI_M_BYPASS
        !           462:         stba    %o3, [%o1] ASI_M_CTL
        !           463:         add     %o0, 2, %o0
        !           464:         add     %o1, 2, %o1
        !           465: 
        !           466: 1:      lduba   [%o2] ASI_M_KERNELTXT, %o3
        !           467:         cmp     %o3, 0
        !           468:         be      2f
        !           469:          nop
        !           470:         stba    %o3, [%o0] ASI_M_BYPASS
        !           471:         stba    %o3, [%o1] ASI_M_CTL
        !           472:         b       1b
        !           473:          inc    %o2
        !           474: bad_conf:
        !           475: 2:      b       2b
        !           476:          nop
        !           477: 
        !           478:         .section .rodata
        !           479: ss2_error:
        !           480:         .string "Sun4c machines are not supported by OpenBIOS yet, freezing\r\n"
        !           481: ss1000_error:
        !           482:         .string "Sun4d machines are not supported by OpenBIOS yet, freezing\r\n"

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.