Annotation of qemu/roms/openbios/arch/sparc64/vectors.S, revision 1.1.1.1

1.1       root        1: /*
                      2:  * <vectors.S>
                      3:  *
                      4:  * Sparc V9 Trap Table(s) with SpitFire/Cheetah extensions.
                      5:  *
                      6:  *   Copyright (C) 1996, 2001 David S. Miller ([email protected])
                      7:  *
                      8:  *   This program is free software; you can redistribute it and/or
                      9:  *   modify it under the terms of the GNU General Public License
                     10:  *   version 2 as published by the Free Software Foundation.
                     11:  *
                     12:  *   This program is distributed in the hope that it will be useful,
                     13:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:  *   GNU General Public License for more details.
                     16:  *
                     17:  *   You should have received a copy of the GNU General Public License
                     18:  *   along with this program; if not, write to the Free Software
                     19:  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
                     20:  *   MA  02110-1301, USA.
                     21:  *   This program is free software; you can redistribute it and/or
                     22:  *   modify it under the terms of the GNU General Public License V2
                     23:  *   as published by the Free Software Foundation
                     24:  */
                     25: 
                     26: #define __ASSEMBLY__
                     27: #include "pstate.h"
                     28: #include <asm/asi.h>
                     29: #define ASI_BP ASI_PHYS_BYPASS_EC_E
                     30: #define PROM_ADDR 0x1fff0000000
                     31: #define SER_ADDR 0x1fe020003f8
                     32: #define TICK_INT_DIS 0x8000000000000000
                     33: #define TICK_INTERVAL 10*1000*1000
                     34: 
                     35:         .section ".text.vectors", "ax"
                     36:         .align 16384
                     37: /* Sparc64 trap table */
                     38:         .globl trap_table, __divide_error, softint_irq, softint_irq_tl1
                     39:         .register %g2, #scratch
                     40:         .register %g3, #scratch
                     41:         .register %g6, #scratch
                     42:         .register %g7, #scratch
                     43: trap_table:
                     44: #define SPILL_WINDOW                                    \
                     45:         btst    1, %sp;                                 \
                     46:         be      spill_32bit;                            \
                     47:          nop;                                           \
                     48:         stx     %l0, [%sp + STACK_BIAS + 0x00];         \
                     49:         stx     %l1, [%sp + STACK_BIAS + 0x08];         \
                     50:         stx     %l2, [%sp + STACK_BIAS + 0x10];         \
                     51:         stx     %l3, [%sp + STACK_BIAS + 0x18];         \
                     52:         stx     %l4, [%sp + STACK_BIAS + 0x20];         \
                     53:         stx     %l5, [%sp + STACK_BIAS + 0x28];         \
                     54:         stx     %l6, [%sp + STACK_BIAS + 0x30];         \
                     55:         stx     %l7, [%sp + STACK_BIAS + 0x38];         \
                     56:         stx     %i0, [%sp + STACK_BIAS + 0x40];         \
                     57:         stx     %i1, [%sp + STACK_BIAS + 0x48];         \
                     58:         stx     %i2, [%sp + STACK_BIAS + 0x50];         \
                     59:         stx     %i3, [%sp + STACK_BIAS + 0x58];         \
                     60:         stx     %i4, [%sp + STACK_BIAS + 0x60];         \
                     61:         stx     %i5, [%sp + STACK_BIAS + 0x68];         \
                     62:         stx     %i6, [%sp + STACK_BIAS + 0x70];         \
                     63:         stx     %i7, [%sp + STACK_BIAS + 0x78];         \
                     64:         saved; retry; nop; nop; nop; nop; nop; nop;     \
                     65:         nop; nop; nop; nop; nop;
                     66: 
                     67: #define FILL_WINDOW                                     \
                     68:         btst    1, %sp;                                 \
                     69:         be      fill_32bit;                             \
                     70:          nop;                                           \
                     71:         ldx     [%sp + STACK_BIAS + 0x00], %l0;         \
                     72:         ldx     [%sp + STACK_BIAS + 0x08], %l1;         \
                     73:         ldx     [%sp + STACK_BIAS + 0x10], %l2;         \
                     74:         ldx     [%sp + STACK_BIAS + 0x18], %l3;         \
                     75:         ldx     [%sp + STACK_BIAS + 0x20], %l4;         \
                     76:         ldx     [%sp + STACK_BIAS + 0x28], %l5;         \
                     77:         ldx     [%sp + STACK_BIAS + 0x30], %l6;         \
                     78:         ldx     [%sp + STACK_BIAS + 0x38], %l7;         \
                     79:         ldx     [%sp + STACK_BIAS + 0x40], %i0;         \
                     80:         ldx     [%sp + STACK_BIAS + 0x48], %i1;         \
                     81:         ldx     [%sp + STACK_BIAS + 0x50], %i2;         \
                     82:         ldx     [%sp + STACK_BIAS + 0x58], %i3;         \
                     83:         ldx     [%sp + STACK_BIAS + 0x60], %i4;         \
                     84:         ldx     [%sp + STACK_BIAS + 0x68], %i5;         \
                     85:         ldx     [%sp + STACK_BIAS + 0x70], %i6;         \
                     86:         ldx     [%sp + STACK_BIAS + 0x78], %i7;         \
                     87:         restored; retry; nop; nop; nop; nop; nop; nop;  \
                     88:         nop; nop; nop; nop; nop;
                     89: 
                     90: #define CLEAN_WINDOW                                                    \
                     91:         rdpr    %cleanwin, %l0;         add     %l0, 1, %l0;            \
                     92:         wrpr    %l0, 0x0, %cleanwin;                                    \
                     93:         clr     %o0;    clr     %o1;    clr     %o2;    clr     %o3;    \
                     94:         clr     %o4;    clr     %o5;    clr     %o6;    clr     %o7;    \
                     95:         clr     %l0;    clr     %l1;    clr     %l2;    clr     %l3;    \
                     96:         clr     %l4;    clr     %l5;    clr     %l6;    clr     %l7;    \
                     97:         retry;                                                          \
                     98:         nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
                     99: 
                    100: #define TRAP_IRQ(routine, level)                        \
                    101:                 ba routine;  mov level, %g1; nop; nop; nop; nop; nop; nop;
                    102: #define BTRAP(lvl)                                      \
                    103:                  ba bug; mov lvl, %g1; nop; nop; nop; nop; nop; nop;
                    104: #define BTRAPTL1(lvl) BTRAP(lvl)
                    105: #define BTRAPS(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3) BTRAP(x+4) BTRAP(x+5) BTRAP(x+6) BTRAP(x+7)
                    106: #define BTRAPS4(x) BTRAP(x) BTRAP(x+1) BTRAP(x+2) BTRAP(x+3)
                    107: #define TRAP_HANDLER(routine) ba routine; nop; nop; nop; nop; nop; nop; nop;
                    108: 
                    109: #define STACK_BIAS             2047
                    110:        .globl  sparc64_ttable_tl0, sparc64_ttable_tl1
                    111: sparc64_ttable_tl0:
                    112:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! XXX remove
                    113:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Power-on reset
                    114:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Watchdog reset
                    115:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! External reset
                    116:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! Software reset
                    117:                 ba entry; nop; nop; nop; nop; nop; nop; nop;! RED state
                    118:                 BTRAP(0x06) BTRAP(0x07) BTRAPS(0x08)
                    119:                BTRAPS(0x10) BTRAPS(0x18)
                    120:                BTRAP(0x20) BTRAP(0x21) BTRAP(0x22) BTRAP(0x23)
                    121:                CLEAN_WINDOW ! 24-27
                    122:                BTRAPS(0x28)
                    123:                BTRAPS(0x30) BTRAPS(0x38)
                    124:                BTRAP(0x40) BTRAP(0x41) BTRAP(0x42) BTRAP(0x43)
                    125: tl0_irq4:      TRAP_IRQ(handler_irq, 4)
                    126: tl0_irq5:      TRAP_IRQ(handler_irq, 5)  TRAP_IRQ(handler_irq, 6)
                    127: tl0_irq7:      TRAP_IRQ(handler_irq, 7)  TRAP_IRQ(handler_irq, 8)
                    128: tl0_irq9:      TRAP_IRQ(handler_irq, 9)  TRAP_IRQ(handler_irq, 10)
                    129: tl0_irq11:     TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
                    130: tl0_irq13:     TRAP_IRQ(handler_irq, 13)
                    131: tl0_irq14:     TRAP_IRQ(softint_irq, 14)
                    132: tl0_irq15:     TRAP_IRQ(handler_irq, 15)
                    133:                BTRAPS(0x50) BTRAPS(0x58)
                    134:                BTRAPS4(0x60)
                    135:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
                    136:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
                    137:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
                    138:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
                    139:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
                    140:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
                    141:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
                    142:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
                    143:                BTRAPS4(0x6C)    ! data_access_protection
                    144:                BTRAPS(0x70) BTRAPS(0x78)
                    145: tl0_s0n:        SPILL_WINDOW
                    146: tl0_s1n:        SPILL_WINDOW
                    147: tl0_s2n:        SPILL_WINDOW
                    148: tl0_s3n:        SPILL_WINDOW
                    149: tl0_s4n:        SPILL_WINDOW
                    150: tl0_s5n:        SPILL_WINDOW
                    151: tl0_s6n:        SPILL_WINDOW
                    152: tl0_s7n:        SPILL_WINDOW
                    153: tl0_s0o:        SPILL_WINDOW
                    154: tl0_s1o:        SPILL_WINDOW
                    155: tl0_s2o:        SPILL_WINDOW
                    156: tl0_s3o:        SPILL_WINDOW
                    157: tl0_s4o:        SPILL_WINDOW
                    158: tl0_s5o:        SPILL_WINDOW
                    159: tl0_s6o:        SPILL_WINDOW
                    160: tl0_s7o:        SPILL_WINDOW
                    161: tl0_f0n:        FILL_WINDOW
                    162: tl0_f1n:        FILL_WINDOW
                    163: tl0_f2n:        FILL_WINDOW
                    164: tl0_f3n:        FILL_WINDOW
                    165: tl0_f4n:        FILL_WINDOW
                    166: tl0_f5n:        FILL_WINDOW
                    167: tl0_f6n:        FILL_WINDOW
                    168: tl0_f7n:        FILL_WINDOW
                    169: tl0_f0o:        FILL_WINDOW
                    170: tl0_f1o:        FILL_WINDOW
                    171: tl0_f2o:        FILL_WINDOW
                    172: tl0_f3o:        FILL_WINDOW
                    173: tl0_f4o:        FILL_WINDOW
                    174: tl0_f5o:        FILL_WINDOW
                    175: tl0_f6o:        FILL_WINDOW
                    176: tl0_f7o:        FILL_WINDOW
                    177: tl0_resv100:   BTRAPS(0x100) BTRAPS(0x108)
                    178: tl0_resv110:   BTRAPS(0x110) BTRAPS(0x118)
                    179: tl0_resv120:   BTRAPS(0x120) BTRAPS(0x128)
                    180: tl0_resv130:   BTRAPS(0x130) BTRAPS(0x138)
                    181: tl0_resv140:   BTRAPS(0x140) BTRAPS(0x148)
                    182: tl0_resv150:   BTRAPS(0x150) BTRAPS(0x158)
                    183: tl0_resv160:   BTRAPS(0x160) BTRAPS(0x168)
                    184: tl0_resv170:   BTRAPS(0x170) BTRAPS(0x178)
                    185: tl0_resv180:   BTRAPS(0x180) BTRAPS(0x188)
                    186: tl0_resv190:   BTRAPS(0x190) BTRAPS(0x198)
                    187: tl0_resv1a0:   BTRAPS(0x1a0) BTRAPS(0x1a8)
                    188: tl0_resv1b0:   BTRAPS(0x1b0) BTRAPS(0x1b8)
                    189: tl0_resv1c0:   BTRAPS(0x1c0) BTRAPS(0x1c8)
                    190: tl0_resv1d0:   BTRAPS(0x1d0) BTRAPS(0x1d8)
                    191: tl0_resv1e0:   BTRAPS(0x1e0) BTRAPS(0x1e8)
                    192: tl0_resv1f0:   BTRAPS(0x1f0) BTRAPS(0x1f8)
                    193: 
                    194: #undef BTRAPS
                    195: #define BTRAPS(x) BTRAPTL1(x) BTRAPTL1(x+1) BTRAPTL1(x+2) BTRAPTL1(x+3) BTRAPTL1(x+4) BTRAPTL1(x+5) BTRAPTL1(x+6) BTRAPTL1(x+7)
                    196: 
                    197: #define SKIP_IRQ(routine, level) \
                    198:                 retry;  nop; nop; nop; nop; nop; nop; nop;
                    199: 
                    200: sparc64_ttable_tl1:
                    201:                BTRAPS(0x00) BTRAPS(0x08)
                    202:                BTRAPS(0x10) BTRAPS(0x18)
                    203:                BTRAPTL1(0x20) BTRAPTL1(0x21) BTRAPTL1(0x22) BTRAPTL1(0x23)
                    204:                CLEAN_WINDOW ! 24-27
                    205:                BTRAPS(0x28)
                    206:                BTRAPS(0x30) BTRAPS(0x38)
                    207:                BTRAPTL1(0x40) BTRAPTL1(0x41) BTRAPTL1(0x42) BTRAPTL1(0x43)
                    208: tl1_irq4:      TRAP_IRQ(handler_irq, 4)
                    209: tl1_irq5:      TRAP_IRQ(handler_irq, 5)  TRAP_IRQ(handler_irq, 6)
                    210: tl1_irq7:      TRAP_IRQ(handler_irq, 7)  TRAP_IRQ(handler_irq, 8)
                    211: tl1_irq9:      TRAP_IRQ(handler_irq, 9)  TRAP_IRQ(handler_irq, 10)
                    212: tl1_irq11:     TRAP_IRQ(handler_irq, 11) TRAP_IRQ(handler_irq, 12)
                    213: tl1_irq13:     TRAP_IRQ(handler_irq, 13)
                    214: tl1_irq14:     SKIP_IRQ(softint_irq, 14)
                    215: tl1_irq15:     TRAP_IRQ(handler_irq, 15)
                    216:                BTRAPS(0x50) BTRAPS(0x58)
                    217:                BTRAPS4(0x60)
                    218:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x64 : instruction_access_MMU_miss
                    219:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x65 : instruction_access_MMU_miss
                    220:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x66 : instruction_access_MMU_miss
                    221:                TRAP_HANDLER(reload_IMMU_tlb)    ! 0x67 : instruction_access_MMU_miss
                    222:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x68 : data_access_MMU_miss
                    223:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x69 : data_access_MMU_miss
                    224:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6A : data_access_MMU_miss
                    225:                TRAP_HANDLER(reload_DMMU_tlb)    ! 0x6B : data_access_MMU_miss
                    226:                BTRAPS4(0x6C)    ! data_access_protection
                    227:                BTRAPS(0x70) BTRAPS(0x78)
                    228: tl1_s0n:        SPILL_WINDOW
                    229: tl1_s1n:        SPILL_WINDOW
                    230: tl1_s2n:        SPILL_WINDOW
                    231: tl1_s3n:        SPILL_WINDOW
                    232: tl1_s4n:        SPILL_WINDOW
                    233: tl1_s5n:        SPILL_WINDOW
                    234: tl1_s6n:        SPILL_WINDOW
                    235: tl1_s7n:        SPILL_WINDOW
                    236: tl1_s0o:        SPILL_WINDOW
                    237: tl1_s1o:        SPILL_WINDOW
                    238: tl1_s2o:        SPILL_WINDOW
                    239: tl1_s3o:        SPILL_WINDOW
                    240: tl1_s4o:        SPILL_WINDOW
                    241: tl1_s5o:        SPILL_WINDOW
                    242: tl1_s6o:        SPILL_WINDOW
                    243: tl1_s7o:        SPILL_WINDOW
                    244: tl1_f0n:        FILL_WINDOW
                    245: tl1_f1n:        FILL_WINDOW
                    246: tl1_f2n:        FILL_WINDOW
                    247: tl1_f3n:        FILL_WINDOW
                    248: tl1_f4n:        FILL_WINDOW
                    249: tl1_f5n:        FILL_WINDOW
                    250: tl1_f6n:        FILL_WINDOW
                    251: tl1_f7n:        FILL_WINDOW
                    252: tl1_f0o:        FILL_WINDOW
                    253: tl1_f1o:        FILL_WINDOW
                    254: tl1_f2o:        FILL_WINDOW
                    255: tl1_f3o:        FILL_WINDOW
                    256: tl1_f4o:        FILL_WINDOW
                    257: tl1_f5o:        FILL_WINDOW
                    258: tl1_f6o:        FILL_WINDOW
                    259: tl1_f7o:        FILL_WINDOW
                    260: tl1_resv100:   BTRAPS(0x100) BTRAPS(0x108)
                    261: tl1_resv110:   BTRAPS(0x110) BTRAPS(0x118)
                    262: tl1_resv120:   BTRAPS(0x120) BTRAPS(0x128)
                    263: tl1_resv130:   BTRAPS(0x130) BTRAPS(0x138)
                    264: tl1_resv140:   BTRAPS(0x140) BTRAPS(0x148)
                    265: tl1_resv150:   BTRAPS(0x150) BTRAPS(0x158)
                    266: tl1_resv160:   BTRAPS(0x160) BTRAPS(0x168)
                    267: tl1_resv170:   BTRAPS(0x170) BTRAPS(0x178)
                    268: tl1_resv180:   BTRAPS(0x180) BTRAPS(0x188)
                    269: tl1_resv190:   BTRAPS(0x190) BTRAPS(0x198)
                    270: tl1_resv1a0:   BTRAPS(0x1a0) BTRAPS(0x1a8)
                    271: tl1_resv1b0:   BTRAPS(0x1b0) BTRAPS(0x1b8)
                    272: tl1_resv1c0:   BTRAPS(0x1c0) BTRAPS(0x1c8)
                    273: tl1_resv1d0:   BTRAPS(0x1d0) BTRAPS(0x1d8)
                    274: tl1_resv1e0:   BTRAPS(0x1e0) BTRAPS(0x1e8)
                    275: tl1_resv1f0:   BTRAPS(0x1f0) BTRAPS(0x1f8)
                    276: 
                    277:        .section ".data"
                    278:        .align 8
                    279:        .globl tlb_handler_stack_top, tlb_handler_stack_pointer
                    280: 
                    281:        ! Stack for the tlb MMU trap handlers
                    282: tlb_handler_stack_bottom:
                    283:        .skip 8192
                    284: tlb_handler_stack_top:
                    285:        .skip 8
                    286: 
                    287:        ! MMU trap handler stack pointer
                    288: tlb_handler_stack_pointer:
                    289:        .xword tlb_handler_stack_top
                    290: 
                    291:         .section ".text", "ax"
                    292: 
                    293: spill_32bit:
                    294:         srl     %sp, 0, %sp
                    295:         stw     %l0, [%sp + 0x00]
                    296:         stw     %l1, [%sp + 0x04]
                    297:         stw     %l2, [%sp + 0x08]
                    298:         stw     %l3, [%sp + 0x0c]
                    299:         stw     %l4, [%sp + 0x10]
                    300:         stw     %l5, [%sp + 0x14]
                    301:         stw     %l6, [%sp + 0x18]
                    302:         stw     %l7, [%sp + 0x1c]
                    303:         stw     %i0, [%sp + 0x20]
                    304:         stw     %i1, [%sp + 0x24]
                    305:         stw     %i2, [%sp + 0x28]
                    306:         stw     %i3, [%sp + 0x2c]
                    307:         stw     %i4, [%sp + 0x30]
                    308:         stw     %i5, [%sp + 0x34]
                    309:         stw     %i6, [%sp + 0x38]
                    310:         stw     %i7, [%sp + 0x3c]
                    311:         saved
                    312:         retry
                    313: 
                    314: fill_32bit:
                    315:         srl     %sp, 0, %sp
                    316:         lduw    [%sp + 0x00], %l0
                    317:         lduw    [%sp + 0x04], %l1
                    318:         lduw    [%sp + 0x08], %l2
                    319:         lduw    [%sp + 0x0c], %l3
                    320:         lduw    [%sp + 0x10], %l4
                    321:         lduw    [%sp + 0x14], %l5
                    322:         lduw    [%sp + 0x18], %l6
                    323:         lduw    [%sp + 0x1c], %l7
                    324:         lduw    [%sp + 0x20], %i0
                    325:         lduw    [%sp + 0x24], %i1
                    326:         lduw    [%sp + 0x28], %i2
                    327:         lduw    [%sp + 0x2c], %i3
                    328:         lduw    [%sp + 0x30], %i4
                    329:         lduw    [%sp + 0x34], %i5
                    330:         lduw    [%sp + 0x38], %i6
                    331:         lduw    [%sp + 0x3c], %i7
                    332:         restored
                    333:         retry
                    334: 
                    335: /*
                    336:  * SAVE_CPU_STATE and RESTORE_CPU_STATE are macros used to enable a context switch
                    337:  * to C to occur within the MMU I/D TLB miss handlers.
                    338:  *
                    339:  * Because these handlers are called on a TLB miss, we cannot use flushw to store
                    340:  * processor window state on the stack, as the memory areas used by each window's
                    341:  * stack pointer may not be in the TLB, causing recursive TLB miss traps.
                    342:  *
                    343:  * For this reason, we save window state by manually rotating the window registers
                    344:  * and saving their contents (along with other vital registers) into a special
                    345:  * tlb_handler_stack defined above which is guaranteed to be locked in the TLB, and
                    346:  * so won't cause issues with trap recursion.
                    347:  *
                    348:  * Once this process is complete, we remain in a TL=0, CWP=0 state (with IE=1 to allow
                    349:  * window fill/spill traps if required), switch to our safe tlb_handler_stack and 
                    350:  * invoke the miss handler.
                    351:  */
                    352: 
                    353: #define SAVE_CPU_STATE(type) \
                    354:        /* Set up our exception stack pointer in %g1 */ \
                    355:        setx    tlb_handler_stack_pointer, %g7, %g6; \
                    356:        ldx     [%g6], %g1; \
                    357:        add     %g1, -0x510, %g1; \
                    358:        \
                    359:        /* First save the various state registers */ \
                    360:        rdpr    %cwp, %g7; \
                    361:        stx     %g7, [%g1]; \
                    362:        rdpr    %cansave, %g7; \
                    363:        stx     %g7, [%g1 + 0x8]; \
                    364:        rdpr    %canrestore, %g7; \
                    365:        stx     %g7, [%g1 + 0x10]; \
                    366:        rdpr    %otherwin, %g7; \
                    367:        stx     %g7, [%g1 + 0x18]; \
                    368:        rdpr    %wstate, %g7; \
                    369:        stx     %g7, [%g1 + 0x20]; \
                    370:        rdpr    %cleanwin, %g7; \
                    371:        stx     %g7, [%g1 + 0x28]; \
                    372:        rdpr    %pstate, %g7; \
                    373:        stx     %g7, [%g1 + 0x30]; \
                    374:        \
                    375:        rd      %y, %g7; \
                    376:        stx     %g7, [%g1 + 0x38]; \
                    377:        rd      %fprs, %g7; \
                    378:        stx     %g7, [%g1 + 0x40]; \
                    379:        \
                    380:        rdpr    %tl, %g7; \
                    381:        stx     %g7, [%g1 + 0x48]; \
                    382:        \
                    383:        /* Trap state */ \
                    384:        add     %g1, 0x50, %g5; \
                    385:        mov     4, %g6; \
                    386:        \
                    387: save_trap_state_##type: \
                    388:        deccc   %g6; \
                    389:        wrpr    %g6, %tl; \
                    390:        rdpr    %tpc, %g7; \
                    391:        stx     %g7, [%g5]; \
                    392:        rdpr    %tnpc, %g7; \
                    393:        stx     %g7, [%g5 + 0x8]; \
                    394:        rdpr    %tstate, %g7; \
                    395:        stx     %g7, [%g5 + 0x10]; \
                    396:        rdpr    %tt, %g7; \
                    397:        stx     %g7, [%g5 + 0x18]; \
                    398:        bne     save_trap_state_##type; \
                    399:         add    %g5, 0x20, %g5; \
                    400:        \
                    401:        /* For 4 trap levels with 4 registers, memory required is 
                    402:        4*8*4 = 0x80 bytes */ \
                    403:        \
                    404:        /* Save the o registers */ \
                    405:        stx     %o0, [%g1 + 0xd0]; \
                    406:        stx     %o1, [%g1 + 0xd8]; \
                    407:        stx     %o2, [%g1 + 0xe0]; \
                    408:        stx     %o3, [%g1 + 0xe8]; \
                    409:        stx     %o4, [%g1 + 0xf0]; \
                    410:        stx     %o5, [%g1 + 0xf8]; \
                    411:        stx     %o6, [%g1 + 0x100]; \
                    412:        stx     %o7, [%g1 + 0x108]; \
                    413:        \
                    414:        /* Now iterate through all of the windows saving all l and i registers */ \
                    415:        add     %g1, 0x110, %g5; \
                    416:        \
                    417:        /* Get the number of windows in %g6 */ \
                    418:        rdpr    %ver, %g6; \
                    419:        and     %g6, 0xf, %g6; \
                    420:        inc     %g6; \
                    421:        \
                    422: save_cpu_window_##type: \
                    423:        deccc   %g6; \
                    424:        wrpr    %g6, %cwp; \
                    425:        stx     %l0, [%g5]; \
                    426:        stx     %l1, [%g5 + 0x8]; \
                    427:        stx     %l2, [%g5 + 0x10]; \
                    428:        stx     %l3, [%g5 + 0x18]; \
                    429:        stx     %l4, [%g5 + 0x20]; \
                    430:        stx     %l5, [%g5 + 0x28]; \
                    431:        stx     %l6, [%g5 + 0x30]; \
                    432:        stx     %l7, [%g5 + 0x38]; \
                    433:        stx     %i0, [%g5 + 0x40]; \
                    434:        stx     %i1, [%g5 + 0x48]; \
                    435:        stx     %i2, [%g5 + 0x50]; \
                    436:        stx     %i3, [%g5 + 0x58]; \
                    437:        stx     %i4, [%g5 + 0x60]; \
                    438:        stx     %i5, [%g5 + 0x68]; \
                    439:        stx     %i6, [%g5 + 0x70]; \
                    440:        stx     %i7, [%g5 + 0x78]; \
                    441:        bne     save_cpu_window_##type; \
                    442:         add    %g5, 0x80, %g5; \
                    443:        \
                    444:        /* For 8 windows with 16 registers to save in the window, memory required
                    445:        is 16*8*8 = 0x400 bytes */ \
                    446:        \
                    447:        /* Now we should be in window 0 so update the other window registers */ \
                    448:        rdpr    %ver, %g6; \
                    449:        and     %g6, 0xf, %g6; \
                    450:        dec     %g6; \
                    451:        wrpr    %g6, %cansave; \
                    452:        \
                    453:        wrpr    %g0, %cleanwin; \
                    454:        wrpr    %g0, %canrestore; \
                    455:        wrpr    %g0, %otherwin; \
                    456:        \
                    457:        /* Update our exception stack pointer */ \
                    458:        setx    tlb_handler_stack_pointer, %g7, %g6; \
                    459:        stx     %g1, [%g6];
                    460: 
                    461: 
                    462: #define RESTORE_CPU_STATE(type) \
                    463:        /* Set up our exception stack pointer in %g1 */ \
                    464:        setx    tlb_handler_stack_pointer, %g7, %g6; \
                    465:        ldx     [%g6], %g1; \
                    466:        \
                    467:        /* Get the number of windows in %g6 */ \
                    468:        rdpr    %ver, %g6; \
                    469:        and     %g6, 0xf, %g6; \
                    470:        inc     %g6; \
                    471:        \
                    472:        /* Now iterate through all of the windows restoring all l and i registers */ \
                    473:        add     %g1, 0x110, %g5; \
                    474:        \
                    475: restore_cpu_window_##type: \
                    476:        deccc   %g6; \
                    477:        wrpr    %g6, %cwp; \
                    478:        ldx     [%g5], %l0; \
                    479:        ldx     [%g5 + 0x8], %l1; \
                    480:        ldx     [%g5 + 0x10], %l2; \
                    481:        ldx     [%g5 + 0x18], %l3; \
                    482:        ldx     [%g5 + 0x20], %l4; \
                    483:        ldx     [%g5 + 0x28], %l5; \
                    484:        ldx     [%g5 + 0x30], %l6; \
                    485:        ldx     [%g5 + 0x38], %l7; \
                    486:        ldx     [%g5 + 0x40], %i0; \
                    487:        ldx     [%g5 + 0x48], %i1; \
                    488:        ldx     [%g5 + 0x50], %i2; \
                    489:        ldx     [%g5 + 0x58], %i3; \
                    490:        ldx     [%g5 + 0x60], %i4; \
                    491:        ldx     [%g5 + 0x68], %i5; \
                    492:        ldx     [%g5 + 0x70], %i6; \
                    493:        ldx     [%g5 + 0x78], %i7; \
                    494:        bne     restore_cpu_window_##type; \
                    495:         add    %g5, 0x80, %g5; \
                    496:        \
                    497:        /* Restore the window registers to their original value */ \
                    498:        ldx     [%g1], %g7; \
                    499:        wrpr    %g7, %cwp; \
                    500:        ldx     [%g1 + 0x8], %g7; \
                    501:        wrpr    %g7, %cansave; \
                    502:        ldx     [%g1 + 0x10], %g7; \
                    503:        wrpr    %g7, %canrestore; \
                    504:        ldx     [%g1 + 0x18], %g7; \
                    505:        wrpr    %g7, %otherwin; \
                    506:        ldx     [%g1 + 0x20], %g7; \
                    507:        wrpr    %g7, %wstate; \
                    508:        ldx     [%g1 + 0x28], %g7; \
                    509:        wrpr    %g7, %cleanwin; \
                    510:        ldx     [%g1 + 0x30], %g7; \
                    511:        wrpr    %g7, %pstate; \
                    512:        \
                    513:        /* Restore the o registers */ \
                    514:        ldx     [%g1 + 0xd0], %o0; \
                    515:        ldx     [%g1 + 0xd8], %o1; \
                    516:        ldx     [%g1 + 0xe0], %o2; \
                    517:        ldx     [%g1 + 0xe8], %o3; \
                    518:        ldx     [%g1 + 0xf0], %o4; \
                    519:        ldx     [%g1 + 0xf8], %o5; \
                    520:        ldx     [%g1 + 0x100], %o6; \
                    521:        ldx     [%g1 + 0x108], %o7; \
                    522:        \
                    523:        /* Restore the trap state */ \
                    524:        add     %g1, 0x50, %g5; \
                    525:        mov     4, %g6; \
                    526:        \
                    527: restore_trap_state_##type: \
                    528:        deccc   %g6; \
                    529:        wrpr    %g6, %tl; \
                    530:        ldx     [%g5], %g7; \
                    531:        wrpr    %g7, %tpc; \
                    532:        ldx     [%g5 + 0x8], %g7; \
                    533:        wrpr    %g7, %tnpc; \
                    534:        ldx     [%g5 + 0x10], %g7; \
                    535:        wrpr    %g7, %tstate; \
                    536:        ldx     [%g5 + 0x18], %g7; \
                    537:        wrpr    %g7, %tt; \
                    538:        bne     restore_trap_state_##type; \
                    539:         add    %g5, 0x20, %g5; \
                    540:        \
                    541:        ldx     [%g1 + 0x38], %g7; \
                    542:        wr      %g7, 0, %y; \
                    543:        ldx     [%g1 + 0x40], %g7; \
                    544:        wr      %g7, 0, %fprs; \
                    545:        ldx     [%g1 + 0x48], %g7; \
                    546:        wrpr    %g7, %tl; \
                    547:        \
                    548:        /* Restore exception stack pointer to previous value */ \
                    549:        setx    tlb_handler_stack_pointer, %g7, %g6; \
                    550:        add     %g1, 0x510, %g1; \
                    551:        stx     %g1, [%g6];
                    552: 
                    553: 
                    554:         .globl reload_DMMU_tlb, reload_IMMU_tlb, bug
                    555: 
                    556: reload_DMMU_tlb:
                    557: 
                    558:        SAVE_CPU_STATE(dtlb)
                    559: 
                    560:        /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
                    561:           gcc to save its arguments when building with -O0) */
                    562:        add     %g1, -STACK_BIAS - 192, %sp
                    563: 
                    564:        /* Enable interrupts for window spill/fill traps */
                    565:        rdpr    %pstate, %g7
                    566:        or      %g7, PSTATE_IE, %g7
                    567:        wrpr    %g7, %pstate    
                    568: 
                    569:        call    dtlb_miss_handler
                    570:         nop
                    571: 
                    572:        /* Disable interrupts */
                    573:        rdpr    %pstate, %g7
                    574:        andn    %g7, PSTATE_IE, %g7
                    575:        wrpr    %g7, %pstate
                    576: 
                    577:        RESTORE_CPU_STATE(dtlb)
                    578: 
                    579:         retry
                    580: 
                    581: reload_IMMU_tlb:
                    582: 
                    583:        SAVE_CPU_STATE(itlb)
                    584: 
                    585:        /* Switch to TLB locked stack space (note we add an additional 192 bytes required for
                    586:           gcc to save its arguments when building with -O0) */
                    587:        add     %g1, -STACK_BIAS - 192, %sp
                    588: 
                    589:        /* Enable interrupts for window spill/fill traps */
                    590:        rdpr    %pstate, %g7
                    591:        or      %g7, PSTATE_IE, %g7
                    592:        wrpr    %g7, %pstate    
                    593: 
                    594:        call    itlb_miss_handler
                    595:         nop
                    596: 
                    597:        /* Disable interrupts */
                    598:        rdpr    %pstate, %g7
                    599:        andn    %g7, PSTATE_IE, %g7
                    600:        wrpr    %g7, %pstate
                    601: 
                    602:        RESTORE_CPU_STATE(itlb)
                    603: 
                    604:         retry
                    605: 
                    606: softint_irq_tl1:
                    607: softint_irq:
                    608:         mov     1, %g2
                    609:         /* clear tick interrupt */
                    610:         wr      %g2, 0x0, %clear_softint
                    611:         sll     %g2, %g1, %g2
                    612:         sra     %g2, 0, %g2
                    613:         /* clear softint interrupt */
                    614:         wr      %g2, 0x0, %clear_softint
                    615: 
                    616:         setx    TICK_INT_DIS, %g2, %g1
                    617:         rd      %tick, %g2
                    618:         and     %g1, %g2, %g1
                    619:         brnz,pn %g1, tick_compare_disabled
                    620:          nop
                    621:         set     TICK_INTERVAL, %g1
                    622:         add     %g1, %g2, %g1
                    623:         wr      %g1, 0, %tick_cmpr
                    624: tick_compare_disabled:
                    625:         retry
                    626: 
                    627: handler_irq:
                    628: __divide_error:
                    629: bug:
                    630:         /* Dump the exception and its context */
                    631:         ! Set up CPU state
                    632:         ! Don't change the global register set or we lose %g1 (exception level)
                    633:         rdpr    %pstate, %g2
                    634:         or      %g2, PSTATE_PRIV, %g2
                    635:         wrpr    %g2, %pstate
                    636:         wr      %g0, 0, %fprs
                    637: 
                    638:         ! Jump to ROM ...
                    639:         setx    _start, %g2, %g3
                    640:         setx    highmem, %g2, %g4
                    641:         sub     %g4, %g3, %g4
                    642:         setx    PROM_ADDR, %g2, %g3
                    643:         add     %g4, %g3, %g3
                    644:         jmp     %g3
                    645:         ! ... while disabling I/D MMUs and caches
                    646:          stxa    %g0, [%g0] ASI_LSU_CONTROL
                    647: 
                    648: highmem:
                    649:         ! Extract NWINDOWS from %ver
                    650:         rdpr    %ver, %g2
                    651:         and     %g2, 0xf, %g2
                    652:         wrpr    %g2, 0, %cleanwin
                    653:         wrpr    %g2, 0, %cansave
                    654:         wrpr    %g0, 0, %canrestore
                    655:         wrpr    %g0, 0, %otherwin
                    656:         wrpr    %g0, 0, %wstate
                    657: 
                    658:         b       dump_exception
                    659:          nop
                    660: 
                    661: outstr:
                    662:         /* void outstr (unsigned long port, const unsigned char *str);
                    663:          * Writes a string on an IO port.
                    664:          */
                    665: 1:      ldub    [%o1], %o3
                    666:         cmp     %o3, 0
                    667:         be      2f
                    668:          nop
                    669:         stba    %o3, [%o0] ASI_BP
                    670:         b       1b
                    671:          inc    %o1
                    672: 2:      retl
                    673:          nop
                    674: 
                    675: outdigit:
                    676:         /* void outdigit (unsigned long port, uint8_t digit);
                    677:          * Dumps a single digit on serial port.
                    678:          */
                    679:         add     %o1, '0', %o1
                    680:         retl
                    681:          stba   %o1, [%o0] ASI_BP
                    682: 
                    683: outhex:
                    684:         /* void outhex (unsigned long port, uint64_t value);
                    685:          * Dumps a 64 bits hex number on serial port
                    686:          */
                    687:         mov     %o1, %o2
                    688:         set     60, %o3
                    689:         srlx    %o2, %o3, %o1
                    690: 1:      and     %o1, 0xf, %o1
                    691:         cmp     %o1, 9
                    692:         bgt     2f
                    693:          nop
                    694:         b       3f
                    695:          add    %o1, '0', %o1
                    696: 2:      add     %o1, 'a' - 10, %o1
                    697: 3:      stba    %o1, [%o0] ASI_BP
                    698:         subcc   %o3, 4, %o3
                    699:         bge     1b
                    700:          srlx   %o2, %o3, %o1
                    701:         retl
                    702:          nop
                    703: 
                    704:         /* void dump_exception ();
                    705:          *
                    706:          * Dump a message when catching an exception
                    707:          */
                    708: dump_exception:
                    709:         setx    SER_ADDR, %o3, %o0
                    710:         set     _start, %g3
                    711:         set     (_BUG_message_0), %o1
                    712:         sub     %o1, %g3, %g4
                    713:         setx    PROM_ADDR, %g2, %g3
                    714:         add     %g4, %g3, %g3
                    715:         call    outstr
                    716:          mov    %g3, %o1
                    717: 
                    718:         call    outhex
                    719:          mov    %g1, %o1
                    720: 
                    721:         call    outstr
                    722:          add    %g3, (_BUG_message_1 -  _BUG_message_0), %o1
                    723: 
                    724:         call    outhex
                    725:          rdpr   %tpc, %o1
                    726: 
                    727:         call    outstr
                    728:          add    %g3, (_BUG_message_2 -  _BUG_message_0), %o1
                    729: 
                    730:         call    outhex
                    731:          rdpr   %tnpc, %o1
                    732: 
                    733:         call    outstr
                    734:          add    %g3, (_BUG_message_3 -  _BUG_message_0), %o1
                    735: 
                    736: _forever:
                    737:         /* Loop forever */
                    738:         b       _forever                                  ;
                    739:          nop
                    740: 
                    741:         .section .rodata
                    742: _BUG_message_0:
                    743:         .string "Unhandled Exception 0x"
                    744: _BUG_message_1:
                    745:         .string "\nPC = 0x"
                    746: _BUG_message_2:
                    747:         .string " NPC = 0x"
                    748: _BUG_message_3:
                    749:         .string "\nStopping execution\n"

unix.superglobalmegacorp.com

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