Annotation of qemu/roms/openbios/arch/sparc32/entry.S, revision 1.1.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.