summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/mips/j4start.s
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/fw/mips/j4start.s')
-rw-r--r--private/ntos/fw/mips/j4start.s756
1 files changed, 756 insertions, 0 deletions
diff --git a/private/ntos/fw/mips/j4start.s b/private/ntos/fw/mips/j4start.s
new file mode 100644
index 000000000..e2057fde3
--- /dev/null
+++ b/private/ntos/fw/mips/j4start.s
@@ -0,0 +1,756 @@
+#if defined(JAZZ) && defined(R4000)
+
+// TITLE("NT System Boot Startup")
+//++
+//
+// Copyright (c) 1991 Microsoft Corporation
+//
+// Module Name:
+//
+// j4start.s
+//
+// Abstract:
+//
+// This module gains control after the ROM selftest has executed.
+// Its function is to initialize the hardware for the ARC firmware.
+//
+// Author:
+//
+// David N. Cutler (davec) 22-Apr-1991
+//
+// Environment:
+//
+// Kernel mode only.
+//
+// Revision History:
+//
+//--
+
+#include "ksmips.h"
+
+#ifndef DUO
+#include "jazzprom.h"
+#else
+#include "duoprom.h"
+#endif
+
+#include "dmaregs.h"
+
+#define PROM_BASE (EEPROM_VIRTUAL_BASE)
+#define PROM_ENTRY(x) (PROM_BASE + ((x) * 8))
+
+
+//TEMPTEMP
+#define SECONDARY_CACHE_SIZE (1 << 20)
+
+//
+// This definitions must match the restart block in arc.h
+//
+
+#define RstBlkSavedState 0x28 // Offset to saved state area
+#define RstBlkRestartAdr 0x10
+#define RstBlkBootStatus 0x1C
+
+#define RstBlkFltF0 RstBlkSavedState+0x000
+#define RstBlkFltF1 RstBlkSavedState+0x004
+#define RstBlkFltF2 RstBlkSavedState+0x008
+#define RstBlkFltF3 RstBlkSavedState+0x00C
+#define RstBlkFltF4 RstBlkSavedState+0x010
+#define RstBlkFltF5 RstBlkSavedState+0x014
+#define RstBlkFltF6 RstBlkSavedState+0x018
+#define RstBlkFltF7 RstBlkSavedState+0x01C
+#define RstBlkFltF8 RstBlkSavedState+0x020
+#define RstBlkFltF9 RstBlkSavedState+0x024
+#define RstBlkFltF10 RstBlkSavedState+0x028
+#define RstBlkFltF11 RstBlkSavedState+0x02C
+#define RstBlkFltF12 RstBlkSavedState+0x030
+#define RstBlkFltF13 RstBlkSavedState+0x034
+#define RstBlkFltF14 RstBlkSavedState+0x038
+#define RstBlkFltF15 RstBlkSavedState+0x03C
+#define RstBlkFltF16 RstBlkSavedState+0x040
+#define RstBlkFltF17 RstBlkSavedState+0x044
+#define RstBlkFltF18 RstBlkSavedState+0x048
+#define RstBlkFltF19 RstBlkSavedState+0x04C
+#define RstBlkFltF20 RstBlkSavedState+0x050
+#define RstBlkFltF21 RstBlkSavedState+0x054
+#define RstBlkFltF22 RstBlkSavedState+0x058
+#define RstBlkFltF23 RstBlkSavedState+0x05C
+#define RstBlkFltF24 RstBlkSavedState+0x060
+#define RstBlkFltF25 RstBlkSavedState+0x064
+#define RstBlkFltF26 RstBlkSavedState+0x068
+#define RstBlkFltF27 RstBlkSavedState+0x06C
+#define RstBlkFltF28 RstBlkSavedState+0x070
+#define RstBlkFltF29 RstBlkSavedState+0x074
+#define RstBlkFltF30 RstBlkSavedState+0x078
+#define RstBlkFltF31 RstBlkSavedState+0x07C
+#define RstBlkFsr RstBlkSavedState+0x080
+#define RstBlkIntAt RstBlkSavedState+0x084
+#define RstBlkIntV0 RstBlkSavedState+0x088
+#define RstBlkIntV1 RstBlkSavedState+0x08C
+#define RstBlkIntA0 RstBlkSavedState+0x090
+#define RstBlkIntA1 RstBlkSavedState+0x094
+#define RstBlkIntA2 RstBlkSavedState+0x098
+#define RstBlkIntA3 RstBlkSavedState+0x09C
+#define RstBlkIntT0 RstBlkSavedState+0x0A0
+#define RstBlkIntT1 RstBlkSavedState+0x0A4
+#define RstBlkIntT2 RstBlkSavedState+0x0A8
+#define RstBlkIntT3 RstBlkSavedState+0x0AC
+#define RstBlkIntT4 RstBlkSavedState+0x0B0
+#define RstBlkIntT5 RstBlkSavedState+0x0B4
+#define RstBlkIntT6 RstBlkSavedState+0x0B8
+#define RstBlkIntT7 RstBlkSavedState+0x0BC
+#define RstBlkIntS0 RstBlkSavedState+0x0C0
+#define RstBlkIntS1 RstBlkSavedState+0x0C4
+#define RstBlkIntS2 RstBlkSavedState+0x0C8
+#define RstBlkIntS3 RstBlkSavedState+0x0CC
+#define RstBlkIntS4 RstBlkSavedState+0x0D0
+#define RstBlkIntS5 RstBlkSavedState+0x0D4
+#define RstBlkIntS6 RstBlkSavedState+0x0D8
+#define RstBlkIntS7 RstBlkSavedState+0x0DC
+#define RstBlkIntT8 RstBlkSavedState+0x0E0
+#define RstBlkIntT9 RstBlkSavedState+0x0E4
+#define RstBlkIntK0 RstBlkSavedState+0x0E8
+#define RstBlkIntK1 RstBlkSavedState+0x0EC
+#define RstBlkIntGp RstBlkSavedState+0x0F0
+#define RstBlkIntSp RstBlkSavedState+0x0F4
+#define RstBlkIntS8 RstBlkSavedState+0x0F8
+#define RstBlkIntRa RstBlkSavedState+0x0FC
+#define RstBlkIntLo RstBlkSavedState+0x100
+#define RstBlkIntHi RstBlkSavedState+0x104
+#define RstBlkPsr RstBlkSavedState+0x108
+#define RstBlkFir RstBlkSavedState+0x10C
+
+//
+// Define Boot status bits.
+//
+#define BootStarted (1 << 0)
+#define BootFinished (1 << 1)
+#define RestartStarted (1 << 2)
+#define RestartFinished (1 << 3)
+#define PowerFailStarted (1 << 4)
+#define PowerFailFinished (1 << 5)
+#define ProcessorReady (1 << 6)
+#define ProcessorRunning (1 << 7)
+#define ProcessorStart (1 << 8)
+
+
+.extern TimerTicks 4
+
+
+ SBTTL("Map PCR Routine")
+//++
+//
+// Routine Description:
+//
+// This routine is executed by processor B. It moves the current mapping
+// for the PCR (set to processor A's PCR) to be two pages below it.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(ReMapPCR)
+ .set noreorder
+ .set noat
+
+ li t0,((PCR_VIRTUAL_BASE >> 13) << ENTRYHI_VPN2)
+ mtc0 t0,entryhi
+ nop // 3 cycle hazard
+ nop //
+ nop //
+ tlbp // probe tlb.
+ nop // 2 cycle hazard
+ nop //
+ mfc0 t1,index // get result of probe
+ nop // 1 cycle hazard
+ bltz t1,30f // branch if entry not in the tlb
+ move v0,zero // set return value to false
+ tlbr // read entry from the tb
+ nop // 3 cycle hazard
+ nop //
+ nop //
+ mfc0 t1,entrylo1 // get entry lo 1
+ nop
+ srl t2,t1,ENTRYLO_PFN // extract PFN
+ subu t2,t2,2 // substract two pages
+ sll t2,t2,ENTRYLO_PFN // shift back up
+ andi t1,t1,0x3F // keep page color
+ or t1,t2,t1 // merge with new PFN
+ mtc0 t1,entrylo1 //
+ nop // 1 cycle hazard
+ tlbwi // write updated entry in the tlb.
+ li v0,1 // set return value to true
+30:
+ j ra // return false
+ nop
+
+ .set reorder
+ .set at
+
+ .end ReMapPCR
+
+
+ SBTTL("Initialize PCR Routine")
+//++
+//
+// Routine Description:
+//
+// This routine initializes the PCR needed by the Hal funcions.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ NESTED_ENTRY(InitializePCR, 0x30, zero)
+
+ subu sp,sp,0x30 // allocate stack frame
+ sw ra,0x14(sp) // save return address
+ sw s0,0x18(sp) // save integer registers s0 - s4
+ sw s1,0x1C(sp) //
+ sw s2,0x20(sp) //
+ sw s3,0x24(sp) //
+ sw s4,0x28(sp) //
+#ifdef DUO
+//
+// Change the PCR mapping if processor B
+//
+ li t0,DMA_VIRTUAL_BASE // load DMA base
+ lw t0,DmaWhoAmI(t0) // read Who am I register
+ beq t0,zero,10f // branch if A
+ bal ReMapPCR // Processor B Changes the mapping
+
+10:
+#endif
+
+//
+// Compute the size of the primary data cache, the primary data cache line
+// size, the primary instruction cache, and the primary instruction cache
+// line size.
+//
+ .set noreorder
+ .set noat
+ mfc0 s4,config // get configuration data
+ mtc0 zero,pagemask // initialize the page mask register
+ mtc0 zero,watchlo // initialize the watch address register
+ mtc0 zero,watchhi //
+ mtc0 zero,wired // initialize the wired register
+ mtc0 zero,count // initialize the count register
+ mtc0 zero,compare // initialize the compare register
+ ctc1 zero,fsr // clear floating status
+ .set at
+ .set reorder
+
+ srl t0,s4,CONFIG_IC // compute instruction cache size
+ and t0,t0,0x7 //
+ addu t0,t0,12 //
+ li s0,1 //
+ sll s0,s0,t0 //
+ srl t0,s4,CONFIG_IB // compute instruction cache line size
+ and t0,t0,1 //
+ li s1,16 //
+ sll s1,s1,t0 //
+ srl t0,s4,CONFIG_DC // compute data cache size
+ and t0,t0,0x7 //
+ addu t0,t0,12 //
+ li s2,1 //
+ sll s2,s2,t0 //
+ srl t0,s4,CONFIG_DB // compute data cache line size
+ and t0,t0,1 //
+ li s3,16 //
+ sll s3,s3,t0 //
+
+//
+// Initialize the low memory transfer vector and next free TB index value.
+//
+
+ li t0,TRANSFER_VECTOR // get address of transfer vector
+ la t1,KiGeneralException // get address of trap handler
+ sw t1,0(t0) // set address of trap handler
+ // next free TB entry set in j4reset.s
+10:
+//
+// Zero the PCR page because it is read before it is written.
+//
+
+ li a0,PCR_VIRTUAL_BASE // set address of PCR
+ li a1,PAGE_SIZE // set size of area to zero
+ jal RtlZeroMemory // zero PCR
+
+//
+// Set the primary instruction size, the primary instruction cache line size,
+// the primary data cache size, and the primary data cache line size.
+//
+
+ li t1,KiPcr // get PCR address
+ sw s0,PcFirstLevelIcacheSize(t1) // set size of instruction cache
+ sw s1,PcFirstLevelIcacheFillSize(t1) // set line size of instruction cache
+ sw s2,PcFirstLevelDcacheSize(t1) // set size of data cache
+ sw s3,PcFirstLevelDcacheFillSize(t1) // set line size of data cache
+
+
+//
+// Compute the size of the secondary data cache, the secondary data cache line
+// size, the secondary instruction cache, and the secondary instruction cache
+// line size.
+//
+
+ li s0,0 // compute instruction cache size
+ li s1,0 // compute instruction cache line size
+ li s2,0 // data cache size if no secondary
+ li s3,0 // data cache line size if no secondary
+ li t1,(1 << CONFIG_SC)
+ and t0,s4,t1
+ bne t0,zero,10f // if non-zero no secondary cache
+ li s2,SECONDARY_CACHE_SIZE // compute data cache size
+ srl t0,s4,CONFIG_SB // compute data cache line size
+ and t0,t0,3 //
+ li s3,16 //
+ sll s3,s3,t0 //
+10:
+
+//
+// Set the secondary instruction size, the secondary instruction cache line size,
+// the secondary data cache size, and the secondary data cache line size.
+//
+
+ li t1,KiPcr // get PCR address
+ sw s0,PcSecondLevelIcacheSize(t1) // set size of instruction cache
+ sw s1,PcSecondLevelIcacheFillSize(t1) // set line size of instruction cache
+ sw s2,PcSecondLevelDcacheSize(t1) // set size of data cache
+ sw s3,PcSecondLevelDcacheFillSize(t1) // set line size of data cache
+
+//
+// Set the data cache fill size and alignment values.
+//
+
+ lw t2,PcSecondLevelDcacheSize(t1) // get second level dcache size
+
+ .set noreorder
+ .set noat
+ bnel zero,t2,5f // if ne, second level cache present
+ lw t2,PcSecondLevelDcacheFillSize(t1) // get second level fill size
+ lw t2,PcFirstLevelDcacheFillSize(t1) // get first level fill size
+ .set at
+ .set reorder
+
+5: subu t3,t2,1 // compute dcache alignment value
+ sw t2,PcDcacheFillSize(t1) // set dcache fill size
+ sw t3,PcDcacheAlignment(t1) // set dcache alignment value
+
+ lw ra,0x14(sp) // restore registers
+ lw s0,0x18(sp) //
+ lw s1,0x1C(sp) //
+ lw s2,0x20(sp) //
+ lw s3,0x24(sp) //
+ lw s4,0x28(sp) //
+ addu sp,sp,0x30 // deallocate stack frame
+ j ra // return
+ .end InitializePCR
+
+
+#ifndef DUO
+ SBTTL("Read Floppy Data From Fifo")
+//++
+//
+// Routine Description:
+//
+// This routine is called to read data from the floppy fifo.
+//
+// Arguments:
+//
+// Buffer (a0) - Supplies a pointer to the buffer that receives the data
+// read.
+//
+// Return Value:
+//
+// The number of bytes read is returned as the function value.
+//
+//--
+
+ LEAF_ENTRY(ReadFloppyFifo)
+
+ move v0,zero // clear number of bytes read
+ li t0,FLOPPY_VIRTUAL_BASE // set base address of floppy registers
+ li t1,0xc0 // set constant for dio and rqm bits
+
+//
+// Read data from floppy fifo.
+//
+
+ .set noreorder
+ .set noat
+10: lbu t2,4(t0) // read MSR register
+ nop //
+ and t3,t2,t1 // clear all but dio and rqm bits
+ bne t1,t3,10b // if ne, rqm and dio not both set
+ and t3,t2,0x20 // test nonDMA bit
+ beq zero,t3,20f // if eq, end of transfer
+ addu a0,a0,1 // increment the buffer address
+ addu v0,v0,1 // increment number of bytes read
+ lbu t2,5(t0) // read floppy fifo
+ b 10b //
+ sb t2,-1(a0) // store byte in buffer
+ .set at
+ .set reorder
+
+20: j ra // return
+
+ .end ReadFloppyFifo
+
+ SBTTL("Write Data to Floppy Fifo")
+//++
+//
+// Routine Description:
+//
+// This routine is called to write data to the floppy fifo.
+//
+// Arguments:
+//
+// Buffer (a0) - Supplies a pointer to the buffer that contains the data
+// to be written.
+//
+// Length (a1) - Supplies the number of bytes to be written to the fifo.
+//
+// Return Value:
+//
+// The number of bytes written is returned as the function value.
+//
+//--
+
+ LEAF_ENTRY(WriteFloppyFifo)
+
+ move v0,zero // clear number of bytes writen
+ li t0,FLOPPY_VIRTUAL_BASE // set base address of floppy registers
+ li t1,0x80 // set constant for dio and rqm bits
+//
+// Write data to floppy fifo.
+//
+
+ .set noreorder
+ .set noat
+ addu a1,a0,a1 // address of last byte to transfer.
+ lbu t5,0(a0) // read first byte to write to fifo
+10: lbu t2,4(t0) // read MSR register
+ nop //
+ andi t3,t2,0xc0 // clear all but dio and rqm bits
+ bne t1,t3,10b // if ne, rqm not set or dio set set
+ nop
+ addu a0,a0,1 // increment the buffer address
+ sb t5,5(t0) // write floppy fifo.
+ bne a0,a1,10b // if not last byte, send next
+ lbu t5,0(a0) // read next byte from buffer
+
+//
+// All bytes written to fifo. Wait until floppy controller empties it.
+//
+
+20: lbu t2,4(t0) // read MSR register
+ nop
+ andi t3,t2,0x20 // test nonDMA bit
+ bne t3,zero,20b // if neq, transfer not finished.
+ nop
+ .set at
+ .set reorder
+
+ j ra // return
+
+ .end WriteFloppyFifo
+
+#endif
+
+#ifdef DUO
+
+ SBTTL("Test for IP interrupt")
+//++
+//
+// Routine Desription:
+//
+// This routine reads the cause register and returns True
+// if the IP interrupt bit is set False otherwise
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+////
+//
+//
+//--
+
+ LEAF_ENTRY(IsIpInterruptSet)
+ .set noreorder
+ .set noat
+
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ and t0,t1 // and them
+ beq t0,zero,20f // branch if not set
+ move v0,zero // set return value to False if no IP int
+ li t0,DMA_VIRTUAL_BASE // load DMA base
+ lw t0,DmaIpInterruptAcknowledge(t0)// read IP Ack register to clear it
+10:
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ and t0,t1 // and them
+ bne t0,zero,10b // Keep looping if still set
+ li v0,1 // set return value to True
+20:
+ j ra // return to caller.
+ nop
+ .set reorder
+ .set at
+
+ .end IsIpInterruptSet
+
+ SBTTL("Wait for IP interrupt")
+//++
+//
+// Routine Desription:
+//
+// This routine waits for an IP interrupt by polling the cause register
+// When the IP interrupt occurs, it clears it and returns to the caller.
+//
+// Arguments:
+//
+// a0 Supplies a timeout period in milliseconds to wait for.
+//
+// The Loop takes about 12 internal cycles.
+// For an internal clock of 100MHz this is about 8192 loops
+// per millisecond.
+//
+//
+//
+// Return Value:
+//
+// zero if the Ip interrupt was not received in the specified timeout
+// period. One otherwise.
+//
+//
+//--
+
+ LEAF_ENTRY(WaitForIpInterrupt)
+ .set noreorder
+ .set noat
+
+ bne a0,zero,10f // if timeout specified count loops
+ sll a0,a0,13 // multiply millisecons by 8192 = Loop count
+
+5:
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ // TMPTMP need symbolic definition
+ and t0,t1 // and them
+ beq t0,zero,5b // Keep looping if not set
+ nop
+ b 20f // go to clear interrupt
+ nop
+
+10:
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ addiu a0,a0,-1 // decrement loop counter
+ beq a0,zero,40f // branch out of loop if Timeout
+ move v0,zero // set return value to zero
+ nop
+ and t0,t1 // and them
+ beq t0,zero,10b // Keep looping if not set
+ nop
+
+20:
+ li t0,DMA_VIRTUAL_BASE // load DMA base
+ lw t0,DmaIpInterruptAcknowledge(t0)// read IP Ack register to clear it
+30:
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ and t0,t1 // and them
+ bne t0,zero,30b // Keep looping if still set
+ addiu v0,zero,1 // set return value to 1
+
+40:
+ j ra // return to the caller.
+ nop
+
+ .set reorder
+ .set at
+ .end WaitForIpInterrupt
+
+
+
+ SBTTL("Boot RestartProcessor")
+//++
+//
+// Routine Desription:
+//
+// This routine loads the Saved State Area of the RestartBlock
+// supplied by a0 into the processor and transfers execution to
+// the restart address.
+// This routine assumes that the supplied restart block is valid.
+//
+// Arguments:
+//
+// a0 PRESTART_BLOCK.
+//
+// Return Value:
+//
+// This routine does not return.
+//
+//--
+
+
+ LEAF_ENTRY(FwBootRestartProcessor)
+ .set noreorder
+ .set noat
+//
+// Cache is flushed by the caller.
+//
+// move s0,a0
+// la k0,HalSweepDcache
+// jal k0
+// nop
+// move a0,s0
+
+10:
+ lw t0,RstBlkBootStatus(a0) // read boot status
+ li t1,ProcessorStart // get boot start bit mask
+ and t0,t0,t1 // and them
+ bne t0,zero,30f // if set go to load restart block
+ nop
+
+//
+// Check if another IP interrupt was send to notify us to give up booting.
+//
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ and t0,t1 // and them
+ beq t0,zero,Wait // branch if not set
+ li t0,DMA_VIRTUAL_BASE // load DMA base
+ lw t0,DmaIpInterruptAcknowledge(t0)// read IP Ack register to clear it
+15:
+ mfc0 t0,cause // get cause register
+ li t1,1<<14 // mask to test IP interrupt
+ and t0,t1 // and them
+ bne t0,zero,15b // Keep looping if still set
+ nop // return to the caller.
+ j ra //
+
+Wait:
+ li t0,0x10000 // load delay value
+20: //
+ bne t0,zero,20b // wait
+ addiu t0,t0,-1
+ b 10b
+ nop
+
+30:
+ move k0,a0 // put address of restart block in k0
+ lwc1 f0,RstBlkFltF0(k0) // Load floating registers
+ lwc1 f1,RstBlkFltF1(k0) // don't use double loads since
+ lwc1 f2,RstBlkFltF2(k0) // the alignment is not known.
+ lwc1 f3,RstBlkFltF3(k0) //
+ lwc1 f4,RstBlkFltF4(k0)
+ lwc1 f5,RstBlkFltF5(k0)
+ lwc1 f6,RstBlkFltF6(k0)
+ lwc1 f7,RstBlkFltF7(k0)
+ lwc1 f8,RstBlkFltF8(k0)
+ lwc1 f9,RstBlkFltF9(k0)
+ lwc1 f10,RstBlkFltF10(k0)
+ lwc1 f11,RstBlkFltF11(k0)
+ lwc1 f12,RstBlkFltF12(k0)
+ lwc1 f13,RstBlkFltF13(k0)
+ lwc1 f14,RstBlkFltF14(k0)
+ lwc1 f15,RstBlkFltF15(k0)
+ lwc1 f16,RstBlkFltF16(k0)
+ lwc1 f17,RstBlkFltF17(k0)
+ lwc1 f18,RstBlkFltF18(k0)
+ lwc1 f19,RstBlkFltF19(k0)
+ lwc1 f20,RstBlkFltF20(k0)
+ lwc1 f21,RstBlkFltF21(k0)
+ lwc1 f22,RstBlkFltF22(k0)
+ lwc1 f23,RstBlkFltF23(k0)
+ lwc1 f24,RstBlkFltF24(k0)
+ lwc1 f25,RstBlkFltF25(k0)
+ lwc1 f26,RstBlkFltF26(k0)
+ lwc1 f27,RstBlkFltF27(k0)
+ lwc1 f28,RstBlkFltF28(k0)
+ lwc1 f29,RstBlkFltF29(k0)
+ lwc1 f30,RstBlkFltF30(k0)
+ lwc1 f31,RstBlkFltF31(k0)
+
+ lw k1,RstBlkFsr(k0) // load fsr
+ ctc1 k1,fsr // transfer to coprocessor
+
+ lw AT,RstBlkIntAt(k0) // load integer registers
+ lw v0,RstBlkIntV0(k0)
+ lw v1,RstBlkIntV1(k0)
+ lw a0,RstBlkIntA0(k0)
+ lw a1,RstBlkIntA1(k0)
+ lw a2,RstBlkIntA2(k0)
+ lw a3,RstBlkIntA3(k0)
+ lw t0,RstBlkIntT0(k0)
+ lw t1,RstBlkIntT1(k0)
+ lw t2,RstBlkIntT2(k0)
+ lw t3,RstBlkIntT3(k0)
+ lw t4,RstBlkIntT4(k0)
+ lw t5,RstBlkIntT5(k0)
+ lw t6,RstBlkIntT6(k0)
+ lw t7,RstBlkIntT7(k0)
+ lw s0,RstBlkIntS0(k0)
+ lw s1,RstBlkIntS1(k0)
+ lw s2,RstBlkIntS2(k0)
+ lw s3,RstBlkIntS3(k0)
+ lw s4,RstBlkIntS4(k0)
+ lw s5,RstBlkIntS5(k0)
+ lw s6,RstBlkIntS6(k0)
+ lw s7,RstBlkIntS7(k0)
+ lw t8,RstBlkIntT8(k0)
+ lw t9,RstBlkIntT9(k0)
+ // Skip k0, k1
+ lw gp,RstBlkIntGp(k0)
+ lw sp,RstBlkIntSp(k0)
+ lw s8,RstBlkIntS8(k0)
+ lw ra,RstBlkIntRa(k0)
+ lw k1,RstBlkIntLo(k0) // load IntLo
+ mtlo k1 // move value to register
+ lw k1,RstBlkIntHi(k0) // load IntHi
+ mthi k1 // move value to register
+ lw k1,RstBlkPsr(k0) // load psr
+ mtc0 k1,psr // move to cop0
+ nop // fill for psr write 3 cycles hazard
+ lw k1,RstBlkFir(k0) // load epc
+ mtc0 k1,epc // move to cop0
+
+ lw k1,RstBlkIntK0(k0) // load k0 into k1
+ mtc0 k1,lladdr // save k0 in cop0 register
+
+ lw k1,RstBlkBootStatus(k0) // read boot status
+ ori k1,ProcessorRunning | BootStarted // Or in status bits.
+ sw k1,RstBlkBootStatus(k0) // write updated boot status
+
+ lw k1,RstBlkIntK1(k0) // load k1
+ lw k0,RstBlkFir(k0) // load restart address
+ j k0 // go to restart address
+ mfc0 k0,lladdr // restore k0 in delay slot.
+
+ALTERNATE_ENTRY(FwBootRestartProcessorEnd)
+ nop
+ .set reorder
+ .set at
+
+ .end RestartProcessor
+
+#endif // DUO
+
+#endif