Annotation of qemu/roms/openbios/arch/sparc64/vectors.S, revision 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.