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

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: 
1.1.1.2 ! root      129:         ! Check if this is the boot CPU and skip SMP table check if yes
        !           130:         ! XXX: not all CPUs should have MXCC
        !           131:         set     0x1c00f00, %g2
        !           132:         ldda    [%g2] ASI_CONTROL, %g2
        !           133:         srl     %g3, 24, %g7
        !           134:         sub     %g7, 8, %g7
        !           135:         tst     %g7
        !           136:         bz      skip_table
        !           137:          nop
        !           138: 
1.1       root      139:         ! Calculate SMP table location
                    140:        set     0x1f0c, %g2
                    141:         add     %g6, %g2, %g2                 ! valid?
                    142:         lda     [%g2] ASI_M_BYPASS, %g7
                    143:         sta     %g0, [%g2] ASI_M_BYPASS
                    144: 
1.1.1.2 ! root      145: skip_table:
1.1       root      146:         ! Get machine ID from configuration device
                    147:         mov     FW_CFG_MACHINE_ID, %g2
                    148:         sub     %g5, 2, %g5
                    149:         stha    %g2, [%g5] CFG_ASI
                    150:         add     %g5, 2, %g5
                    151:         lduba   [%g5] CFG_ASI, %g4
                    152: 
                    153:         lduba   [%g5] CFG_ASI, %g3
                    154:         sll     %g3, 8, %g3
                    155:         or      %g3, %g4, %g4
                    156:         mov     %g4, %y
                    157: 
                    158:         cmp     %g4, 96
                    159:         bgeu    ss1000
                    160:          cmp    %g4, 64
                    161:         bgeu    ss10
                    162:          cmp    %g4, 32
                    163:         blu     ss2
                    164:          nop
                    165: 
                    166:         ! Ok, this is SS-5
                    167: 
                    168:         tst     %g7
                    169:         bz      first_cpu
                    170:          nop
                    171: 
                    172:         ! Clear softints used for SMP CPU startup
                    173:         set     PHYS_JJ_INTR0 + 0x04, %g1
                    174:         sll     %g2, 12, %g2
                    175:         add     %g1, %g2, %g2
                    176:         set     0xffffffff, %g1
                    177:         sta     %g1, [%g2] ASI_M_BYPASS         ! clear softints
                    178:         add     %g2, 4, %g2
                    179:         sta     %g0, [%g2] ASI_M_BYPASS         ! clear softints
                    180: 
                    181: load_ctx:
                    182:         ! SMP init, jump to user specified address
                    183:        set     0x1f04, %g5
                    184:         add     %g6, %g5, %g5                 ! ctxtbl
                    185:         lda     [%g5] ASI_M_BYPASS, %g2
                    186:         sta     %g0, [%g5] ASI_M_BYPASS
                    187:         set     AC_M_CTPR, %g1
                    188:         sta     %g2, [%g1] ASI_M_MMUREGS        ! set ctx table ptr
                    189:        set     0x1f00, %g5
                    190:         add     %g6, %g5, %g5                 ! ctx
                    191:         lda     [%g5] ASI_M_BYPASS, %g2
                    192:         sta     %g0, [%g5] ASI_M_BYPASS
                    193:         set     AC_M_CXR, %g1
                    194:         sta     %g2, [%g1] ASI_M_MMUREGS        ! set context
                    195:        set     0x1f08, %g5
                    196:         add     %g6, %g5, %g5                 ! entry
                    197:         lda     [%g5] ASI_M_BYPASS, %g2
                    198:         sta     %g0, [%g5] ASI_M_BYPASS
                    199:         set     1, %g1
                    200:         jmp     %g2                             ! jump to kernel
                    201:          sta    %g1, [%g0] ASI_M_MMUREGS        ! enable mmu
                    202: 
                    203: ss10:
                    204:         ! Ok, this is SS-10 or SS-600MP
                    205:         tst     %g7
                    206:         bz      first_cpu
                    207:          nop
                    208: 
                    209:         ! Clear softints used for SMP CPU startup
                    210:         set     PHYS_SS10_INTR0 + 0x04, %g1
                    211:         sll     %g2, 12, %g2
                    212:         add     %g1, %g2, %g2
                    213:         set     0xffffffff, %g1
                    214:         sta     %g1, [%g2] ASI_M_CTL            ! clear softints
                    215:         add     %g2, 4, %g2
                    216:         b       load_ctx
                    217:          sta    %g0, [%g2] ASI_M_CTL            ! clear softints
                    218: 
                    219: ss2:
                    220:         ! Ok, this is SS-2
                    221:         set     ss2_error, %o2
                    222:         b       ss2_ss1000_halt
                    223:          nop
                    224: 
                    225: ss1000:
                    226:         ! Ok, this is SS-1000 or SS-2000
                    227:         set     ss1000_error, %o2
                    228:         b       ss2_ss1000_halt
                    229:          nop
                    230: 
                    231: first_cpu:
                    232:         /* Create temporary page tables and map the ROM area to end of
                    233:        RAM. This will be done properly in iommu.c later. */
                    234:         ! Calculate start of page tables etc. to %g6
                    235:         set     0x2000, %g4
                    236:         sub     %g1, %g4, %g6                   ! start of private memory
                    237: 
                    238:         mov     %g6, %g2                        ! ctx table at s+0x0
                    239:         add    %g2, 0x400, %g3                 ! l1 table at s+0x400
                    240:         srl    %g3, 0x4, %g3
                    241:         or     %g3, 0x1, %g3
                    242:         sta    %g3, [%g2] ASI_M_BYPASS
                    243:         add    %g2, 0x400, %g2                 ! s+0x400
                    244:         add    %g2, 0x400, %g3                 ! l2 table for ram (00xxxxxx) at s+0x800
                    245:         srl    %g3, 0x4, %g3
                    246:         or     %g3, 0x1, %g3
                    247:         sta    %g3, [%g2] ASI_M_BYPASS
                    248:         add    %g2, 0x500, %g3                 ! l2 table for rom (ffxxxxxx) at s+0x900
                    249:         add    %g2, 0x3fc, %g2                 ! s+0x7fc
                    250:         srl    %g3, 0x4, %g3
                    251:         or     %g3, 0x1, %g3
                    252:         sta    %g3, [%g2] ASI_M_BYPASS
                    253:         add    %g2, 0x4, %g2                   ! s+0x800
                    254: #if 0
                    255:         set     0x40, %g6
                    256:         set    ((7 << 2) | 2), %g3             ! 7 = U: --- S: RWX (main memory)
                    257: 1:      sta    %g3, [%g2] ASI_M_BYPASS
                    258:         add     %g2, 4, %g2
                    259:         deccc   %g6
                    260:         bne     1b
                    261:          nop
                    262: #else
                    263:         add     %g2, 0x100, %g2
                    264: #endif
                    265:                                                 ! s+0x900
                    266:         add    %g2, 0xa00 - 0x900, %g3         ! l3 table for rom at s+0xa00
                    267:         add    %g2, 0x0d0, %g2                 ! s+0x9d0
                    268:         srl    %g3, 0x4, %g3
                    269:         or     %g3, 0x1, %g3
                    270:         sta    %g3, [%g2] ASI_M_BYPASS
                    271:         add    %g2, 4, %g2                     ! s+0x9d4
                    272:         add    %g2, 0xb00 - 0x9d4, %g3         ! 2nd l3 table for rom at s+0xb00
                    273:         srl    %g3, 0x4, %g3
                    274:         or     %g3, 0x1, %g3
                    275:         sta    %g3, [%g2] ASI_M_BYPASS
                    276:         add    %g2, 4, %g2                     ! s+0x9d8
                    277:         add    %g2, 0xc00 - 0x9d8, %g3         ! 3rd l3 table for rom at s+0xc00
                    278:         srl    %g3, 0x4, %g3
                    279:         or     %g3, 0x1, %g3
                    280:         sta    %g3, [%g2] ASI_M_BYPASS
                    281:         add    %g2, 4, %g2                     ! s+0x9dc
                    282:         add    %g2, 0xd00 - 0x9dc, %g3         ! 4th l3 table for rom at s+0xd00
                    283:         srl    %g3, 0x4, %g3
                    284:         or     %g3, 0x1, %g3
                    285:         sta    %g3, [%g2] ASI_M_BYPASS
                    286:         add    %g2, 4, %g2                     ! s+0x9e0
                    287:         add    %g2, 0xe00 - 0x9e0, %g3         ! 5th l3 table for rom at s+0xe00
                    288:         srl    %g3, 0x4, %g3
                    289:         or     %g3, 0x1, %g3
                    290:         sta    %g3, [%g2] ASI_M_BYPASS
                    291:         add    %g2, 4, %g2                     ! s+0x9e4
                    292:         add    %g2, 0xf00 - 0x9e4, %g3         ! 6th l3 table for rom at s+0xf00
                    293:         srl    %g3, 0x4, %g3
                    294:         or     %g3, 0x1, %g3
                    295:         sta    %g3, [%g2] ASI_M_BYPASS
                    296:         add    %g2, 4, %g2                     ! s+0x9e8
                    297:         add    %g2, 0x1000 - 0x9e8, %g3        ! 7th l3 table for rom at s+0x1000
                    298:         srl    %g3, 0x4, %g3
                    299:         or     %g3, 0x1, %g3
                    300:         sta    %g3, [%g2] ASI_M_BYPASS
                    301:         add    %g2, 4, %g2                     ! s+0x9ec
                    302:         add    %g2, 0x1100 - 0x9ec, %g3        ! 8th l3 table for rom at s+0x1100
                    303:         srl    %g3, 0x4, %g3
                    304:         or     %g3, 0x1, %g3
                    305:         sta    %g3, [%g2] ASI_M_BYPASS
                    306:       add      %g2, 0xa00-0x9ec, %g2           ! s+0xa00
                    307: 
                    308:         /* Use end of ram for code, rodata, data, and bss
                    309:        sections. SunOS wants to write to trap table... */
                    310:         set    _end, %g6
                    311:         set    _start, %g4
                    312:         sub     %g6, %g4, %g6
                    313:         sub     %g1, %g6, %g3
                    314:         set    0x1000, %g5
                    315:         sub     %g3, %g5, %g3
                    316:         sub     %g3, %g5, %g3                   ! start of ROM copy
                    317:         mov     %g3, %g7                        ! save in %g7
                    318:         srl     %g6, 12, %g6                    ! # of all pages
                    319: 1:      srl    %g3, 0x4, %g4
                    320:         or     %g4, ((7 << 2) | 2), %g4        ! 7 = U: --- S: RWX
                    321:         sta    %g4, [%g2] ASI_M_BYPASS
                    322:         add    %g2, 4, %g2
                    323:         add    %g3, %g5, %g3
                    324:         deccc  %g6
                    325:         bne    1b
                    326:          nop
                    327: 
                    328:         mov    %g1, %g6                        ! %g6 = memory size
                    329: 
                    330:         /* Copy the code, rodata and data sections from ROM. */
                    331:         sub     %g7, 4, %g3
                    332:         set    _start - 4, %g4                 ! First address of TEXT - 4
                    333:         set    _bss, %g5                       ! Last address of DATA
                    334:         ba     2f
                    335:          nop
                    336: 1:
                    337:         lda     [%g4] ASI_M_KERNELTXT, %g1
                    338:         sta    %g1, [%g3] ASI_M_BYPASS
                    339: 2:
                    340:         cmp     %g4, %g5
                    341:         add     %g3, 0x4, %g3
                    342:         bl      1b
                    343:          add    %g4, 0x4, %g4
                    344: 
                    345:         set     0x2000, %g3
                    346:         sub     %g6, %g3, %g7                   ! ctx table at s+0x0
                    347:         set     AC_M_CTPR, %g2
                    348:         srl     %g7, 4, %g7
                    349:         sta     %g7, [%g2] ASI_M_MMUREGS       ! set ctx table ptr
                    350:         set     AC_M_CXR, %g2
                    351:         sta     %g0, [%g2] ASI_M_MMUREGS       ! context 0
                    352:         set     highmem, %g2
                    353:         set    1, %g1
                    354:         jmp     %g2
                    355:          sta    %g1, [%g0] ASI_M_MMUREGS       ! enable mmu
                    356: highmem:
                    357:         /*
                    358:          * The code which enables traps is a simplified version of
                    359:          * kernel head.S.
                    360:          *
                    361:          * We know number of windows as 8 so we do not calculate them.
                    362:          * The deadwood is here for any case.
                    363:          */
                    364: 
                    365:         /* Turn on Supervisor, EnableFloating, and all the PIL bits.
                    366:          * Also puts us in register window zero with traps off.
                    367:          */
                    368:         set    (PSR_PS | PSR_S | PSR_PIL | PSR_EF), %g2
                    369:         wr     %g2, 0x0, %psr
                    370:         WRITE_PAUSE
                    371: 
                    372:         /* Zero out our BSS section. */
                    373:         set    _bss - 4, %o0           ! First address of BSS
                    374:         set    _estack - 4, %o1        ! Last address of BSS
                    375:         ba     2f
                    376:          nop
                    377: 1:
                    378:         st     %g0, [%o0]
                    379: 2:
                    380:         subcc  %o0, %o1, %g0
                    381:         bl     1b
                    382:          add   %o0, 0x4, %o0
                    383: 
                    384:         set     trap_table, %g1
                    385:         wr      %g1, 0x0, %tbr
                    386: 
                    387:         set     qemu_mem_size, %g1
                    388:         st      %g6, [%g1]
                    389: 
                    390:         set     _end, %o0                       ! Store va->pa conversion factor
                    391:         set     _start, %o2
                    392:         sub     %o0, %o2, %o0
                    393:         sub     %g6, %o0, %o0
                    394:         set     0x2000, %o1
                    395:         sub     %o0, %o1, %o0                   ! start of ROM copy
                    396:         sub     %o2, %o0, %o0                   ! start of ROM copy
                    397:         set     va_shift, %g1
                    398:         st      %o0, [%g1]
                    399: 
                    400:         set     qemu_machine_type, %g1
                    401:         mov     %y, %g2
                    402:         st      %g2, [%g1]
                    403: 
                    404:         /* Compute NWINDOWS and stash it away. Now uses %wim trick explained
                    405:          * in the V8 manual. Ok, this method seems to work, Sparc is cool...
                    406:          * No, it doesn't work, have to play the save/readCWP/restore trick.
                    407:          */
                    408: 
                    409:         wr      %g0, 0x0, %wim                  ! so we do not get a trap
                    410:         WRITE_PAUSE
                    411: 
                    412:         save
                    413: 
                    414:         rd      %psr, %g3
                    415: 
                    416:         restore
                    417: 
                    418:         and     %g3, 0x1f, %g3
                    419:         add     %g3, 0x1, %g3
                    420: 
                    421:         mov     2, %g1
                    422:         wr      %g1, 0x0, %wim                  ! make window 1 invalid
                    423:         WRITE_PAUSE
                    424: 
                    425:         cmp     %g3, 0x7
                    426:         bne     1f
                    427:          nop
                    428: 
                    429:         /* Adjust our window handling routines to
                    430:          * do things correctly on 7 window Sparcs.
                    431:          */
                    432: #define PATCH_INSN(src, dest) \
                    433:         set     src, %g5; \
                    434:         set     dest, %g2; \
                    435:         ld      [%g5], %g4; \
                    436:         st      %g4, [%g2];
                    437: 
                    438:         /* Patch for window spills... */
                    439:         PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
                    440:         PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
                    441: 
                    442:         /* Patch for window fills... */
                    443:         PATCH_INSN(fnwin_patch1_7win, fnwin_patch1)
                    444:         PATCH_INSN(fnwin_patch2_7win, fnwin_patch2)
                    445: 
                    446: 1:
                    447:         /* Finally, turn on traps so that we can call c-code. */
                    448:         rd     %psr, %g3
                    449:         wr     %g3, 0x0, %psr
                    450:         WRITE_PAUSE
                    451: 
                    452:         wr     %g3, PSR_ET, %psr
                    453:         WRITE_PAUSE
                    454: 
                    455:         call    __switch_context_nosave
                    456:          nop
                    457: 
                    458:         /* We get here when the main context switches back to
                    459:          * the boot context.
                    460:          * Return to previous bootloader.
                    461:          */
                    462:         ret
                    463:          nop
                    464: 
                    465: ss2_ss1000_halt:
                    466:         set     SER_ADDR2, %o0
                    467:         set     SER_ADDR1000, %o1
                    468:         mov     0x05, %o3 /* Reg 5, TXCTRL2 */
                    469:         stba    %o3, [%o0] ASI_M_BYPASS
                    470:         stba    %o3, [%o1] ASI_M_CTL
                    471:         mov     0x68, %o3 /* 8 bits, Tx enabled */
                    472:         stba    %o3, [%o0] ASI_M_BYPASS
                    473:         stba    %o3, [%o1] ASI_M_CTL
                    474:         add     %o0, 2, %o0
                    475:         add     %o1, 2, %o1
                    476: 
                    477: 1:      lduba   [%o2] ASI_M_KERNELTXT, %o3
                    478:         cmp     %o3, 0
                    479:         be      2f
                    480:          nop
                    481:         stba    %o3, [%o0] ASI_M_BYPASS
                    482:         stba    %o3, [%o1] ASI_M_CTL
                    483:         b       1b
                    484:          inc    %o2
                    485: bad_conf:
                    486: 2:      b       2b
                    487:          nop
                    488: 
                    489:         .section .rodata
                    490: ss2_error:
                    491:         .string "Sun4c machines are not supported by OpenBIOS yet, freezing\r\n"
                    492: ss1000_error:
                    493:         .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.