You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
780 lines
15 KiB
780 lines
15 KiB
/* $Id: start.S,v 1.1.1.1 2006/09/14 01:59:08 root Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2001 Opsycon AB (www.opsycon.se)
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Opsycon AB, Sweden.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#ifndef _KERNEL
|
|
#define _KERNEL
|
|
#endif
|
|
|
|
#include <asm.h>
|
|
#include <regnum.h>
|
|
#include <cpu.h>
|
|
#include <pte.h>
|
|
|
|
#include "pmon/dev/ns16550.h"
|
|
#include "target/prid.h"
|
|
#include "target/sbd.h"
|
|
#include "target/fcr.h"
|
|
#include "target/via686b.h"
|
|
#include "target/i8254.h"
|
|
#include "target/isapnpreg.h"
|
|
#define DEBUG_LOCORE
|
|
|
|
|
|
|
|
#ifdef DEBUG_LOCORE
|
|
#define TTYDBG(x) \
|
|
.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop
|
|
#else
|
|
#define TTYDBG(x)
|
|
#endif
|
|
|
|
#define PRINTSTR(x) \
|
|
.rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop
|
|
|
|
|
|
#define tmpsize s1
|
|
#define msize s2
|
|
#define bonito s4
|
|
#define dbg s5
|
|
#define sdCfg s6
|
|
|
|
#define CP0_CONFIG $16
|
|
#define CP0_TAGLO $28
|
|
#define CP0_TAGHI $29
|
|
|
|
|
|
/*
|
|
* Register usage:
|
|
*
|
|
* s0 link versus load offset, used to relocate absolute adresses.
|
|
* s1 free
|
|
* s2 memory size.
|
|
* s3 free.
|
|
* s4 Bonito base address.
|
|
* s5 dbg.
|
|
* s6 sdCfg.
|
|
* s7 rasave.
|
|
* s8 L3 Cache size.
|
|
*/
|
|
|
|
|
|
.set noreorder
|
|
.globl _start
|
|
.globl start
|
|
.globl __main
|
|
_start:
|
|
start:
|
|
.globl stack
|
|
stack = start - 0x4000 /* Place PMON stack below PMON start in RAM */
|
|
|
|
/* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */
|
|
mtc0 zero, COP_0_STATUS_REG
|
|
mtc0 zero, COP_0_CAUSE_REG
|
|
li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */
|
|
mtc0 t0, COP_0_STATUS_REG
|
|
la sp, stack
|
|
la gp, _gp
|
|
|
|
// bal uncached /* Switch to uncached address space */
|
|
nop
|
|
|
|
bal locate /* Get current execute address */
|
|
nop
|
|
|
|
uncached:
|
|
or ra, UNCACHED_MEMORY_ADDR
|
|
j ra
|
|
nop
|
|
|
|
/*
|
|
* Reboot vector usable from outside pmon.
|
|
*/
|
|
.align 8
|
|
ext_map_and_reboot:
|
|
bal CPU_TLBClear
|
|
nop
|
|
|
|
li a0, 0xc0000000
|
|
li a1, 0x40000000
|
|
bal CPU_TLBInit
|
|
nop
|
|
la v0, tgt_reboot
|
|
la v1, start
|
|
subu v0, v1
|
|
lui v1, 0xffc0
|
|
addu v0, v1
|
|
jr v0
|
|
nop
|
|
|
|
/*
|
|
* Exception vectors here for rom, before we are up and running. Catch
|
|
* whatever comes up before we have a fully fledged exception handler.
|
|
*/
|
|
.align 9 /* bfc00200 */
|
|
la a0, v200_msg
|
|
bal stringserial
|
|
nop
|
|
b exc_common
|
|
|
|
.align 7 /* bfc00280 */
|
|
la a0, v280_msg
|
|
bal stringserial
|
|
nop
|
|
b exc_common
|
|
|
|
/* Cache error */
|
|
.align 8 /* bfc00300 */
|
|
PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ")
|
|
mfc0 a0, COP_0_CACHE_ERR
|
|
bal hexserial
|
|
nop
|
|
b exc_common
|
|
|
|
/* General exception */
|
|
.align 7 /* bfc00380 */
|
|
la a0, v380_msg
|
|
bal stringserial
|
|
nop
|
|
b exc_common
|
|
|
|
.align 8 /* bfc00400 */
|
|
la a0, v400_msg
|
|
bal stringserial
|
|
nop
|
|
|
|
|
|
|
|
exc_common:
|
|
PRINTSTR("\r\nCAUSE=")
|
|
mfc0 a0, COP_0_CAUSE_REG
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\nSTATUS=")
|
|
mfc0 a0, COP_0_STATUS_REG
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\nERRORPC=")
|
|
mfc0 a0, COP_0_ERROR_PC
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\nEPC=")
|
|
mfc0 a0, COP_0_EXC_PC
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\nDERR0=")
|
|
cfc0 a0, COP_0_DERR_0
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\nDERR1=")
|
|
cfc0 a0, COP_0_DERR_1
|
|
bal hexserial
|
|
nop
|
|
|
|
// b ext_map_and_reboot
|
|
nop
|
|
|
|
.align 8
|
|
nop
|
|
.align 8
|
|
.word read
|
|
.word write
|
|
.word open
|
|
.word close
|
|
.word nullfunction
|
|
.word printf
|
|
.word vsprintf
|
|
.word nullfunction
|
|
.word nullfunction
|
|
.word getenv
|
|
.word nullfunction
|
|
.word nullfunction
|
|
.word nullfunction
|
|
.word nullfunction
|
|
|
|
|
|
/*
|
|
* We get here from executing a bal to get the PC value of the current execute
|
|
* location into ra. Check to see if we run from ROM or if this is ramloaded.
|
|
*/
|
|
locate:
|
|
la s0,uncached
|
|
subu s0,ra,s0
|
|
and s0,0xffffff00
|
|
|
|
li t0,SR_BOOT_EXC_VEC
|
|
mtc0 t0,COP_0_STATUS_REG
|
|
mtc0 zero,COP_0_CAUSE_REG
|
|
.set noreorder
|
|
|
|
bal initserial
|
|
nop
|
|
|
|
PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n")
|
|
PRINTSTR("ERRORPC=")
|
|
mfc0 a0, COP_0_ERROR_PC
|
|
bal hexserial
|
|
nop
|
|
|
|
PRINTSTR(" CONFIG=")
|
|
mfc0 a0, COP_0_CONFIG
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\n")
|
|
|
|
PRINTSTR(" PRID=")
|
|
mfc0 a0, COP_0_PRID
|
|
bal hexserial
|
|
nop
|
|
PRINTSTR("\r\n")
|
|
|
|
bnez s0,1f
|
|
nop
|
|
li a0,64
|
|
jal initmips
|
|
nop
|
|
1:
|
|
|
|
/*
|
|
* Now determine DRAM configuration and size by
|
|
* reading the I2C EEROM on the DIMMS
|
|
*/
|
|
|
|
################################
|
|
# Initailize SDRAM Interface #
|
|
################################
|
|
li a2, 0xbf000000
|
|
#li a1, 0x0c4007b8
|
|
li a1, 0x0c4002d4
|
|
sw a1, 0x0(a2)
|
|
# li a1, 0x209800a7
|
|
li a1, 0x209800c6
|
|
#li a1, 0x209000c6
|
|
#li a1, 0x208800c6
|
|
sw a1, 0x4(a2)
|
|
|
|
li msize,0x02000000
|
|
PRINTSTR("Init SDRAM Done!\r\n");
|
|
|
|
|
|
#define CF_7_SE (1 << 3) /* Secondary cache enable */
|
|
#define CF_7_SC (1 << 31) /* Secondary cache not present */
|
|
#define CF_7_TE (1 << 12) /* Tertiary cache enable */
|
|
#define CF_7_TC (1 << 17) /* Tertiary cache not present */
|
|
#define CF_7_TS (3 << 20) /* Tertiary cache size */
|
|
#define CF_7_TS_AL 20 /* Shift to align */
|
|
#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop
|
|
do_caches:
|
|
TTYDBG("Init caches...\r\n")
|
|
|
|
li s7, 0 /* no L2 cache */
|
|
li s8, 0 /* no L3 cache */
|
|
|
|
TTYDBG("godson1 caches found\r\n")
|
|
bal cache_init
|
|
nop
|
|
|
|
TTYDBG("Init caches done, cfg = ")
|
|
mfc0 a0, COP_0_CONFIG
|
|
bal hexserial
|
|
nop
|
|
TTYDBG("\r\n\r\n")
|
|
|
|
mfc0 a0,COP_0_CONFIG
|
|
and a0,a0,~((1<<12) | 3)
|
|
or a0,a0,2
|
|
mtc0 a0,COP_0_CONFIG
|
|
|
|
|
|
#include "newtest.32/mydebug.S"
|
|
bootnow:
|
|
#define FCALL_PRINTSTR(x) \
|
|
.rdata;98: .asciz x; .text; la a0, 98b; la v0, stringserial; addu v0,s0;jalr v0; nop
|
|
|
|
#undef BAL
|
|
#define BAL(x) \
|
|
la v0,x; \
|
|
addu v0,s0; \
|
|
jalr v0; \
|
|
nop;
|
|
|
|
|
|
|
|
|
|
|
|
/*copy copy program to sdram to make copy fast*/
|
|
|
|
la t0,121f
|
|
addu t0,s0
|
|
la t1,122f
|
|
addu t1,s0
|
|
|
|
li t2,0xa0000000
|
|
1:
|
|
lw v0,(t0)
|
|
sw v0,(t2)
|
|
addu t0,4
|
|
addu t2,4
|
|
ble t0,t1,1b
|
|
nop
|
|
|
|
li t0,0xa0000000
|
|
jr t0
|
|
nop
|
|
|
|
.align 3
|
|
121:
|
|
FCALL_PRINTSTR("Copy PMON to execute location...\r\n")
|
|
la a0, start
|
|
addu a1,a0,s0
|
|
la a2, _edata
|
|
or a0, 0xa0000000
|
|
or a2, 0xa0000000
|
|
subu t1, a2, a0
|
|
srl t1, t1, 2
|
|
|
|
move t0, a0
|
|
move t1, a1
|
|
move t2, a2
|
|
|
|
/* copy text section */
|
|
|
|
1: and t3,t0,0x0000ffff
|
|
bnez t3,2f
|
|
nop
|
|
move a0,t0
|
|
BAL(hexserial)
|
|
nop
|
|
li a0,'\r'
|
|
BAL(tgt_putchar)
|
|
nop
|
|
2: lw t3, 0(t1)
|
|
nop
|
|
sw t3, 0(t0)
|
|
addu t0, 4
|
|
addu t1, 4
|
|
bne t2, t0, 1b
|
|
nop
|
|
|
|
FCALL_PRINTSTR("\ncopy text section done.\r\n")
|
|
|
|
/* Clear BSS */
|
|
la a0, _edata
|
|
la a2, _end
|
|
2: sw zero, 0(a0)
|
|
bne a2, a0, 2b
|
|
addu a0, 4
|
|
|
|
|
|
FCALL_PRINTSTR("Copy PMON to execute location done.\r\n")
|
|
FCALL_PRINTSTR("sp=");
|
|
move a0, sp
|
|
BAL(hexserial)
|
|
nop
|
|
|
|
li a0, 0
|
|
sw a0, CpuTertiaryCacheSize /* Set L3 cache size */
|
|
|
|
|
|
move a0,msize
|
|
srl a0,20
|
|
|
|
|
|
la v0, initmips
|
|
jalr v0
|
|
nop
|
|
|
|
.align 3
|
|
122:
|
|
stuck:
|
|
b stuck
|
|
nop
|
|
|
|
/*
|
|
* Clear the TLB. Normally called from start.S.
|
|
*/
|
|
#if __mips64
|
|
#define MTC0 dmtc0
|
|
#else
|
|
#define MTC0 mtc0
|
|
#endif
|
|
LEAF(CPU_TLBClear)
|
|
li a3, 0 # First TLB index.
|
|
|
|
li a2, PG_SIZE_4K
|
|
MTC0 a2, COP_0_TLB_PG_MASK # Whatever...
|
|
|
|
1:
|
|
MTC0 zero, COP_0_TLB_HI # Clear entry high.
|
|
MTC0 zero, COP_0_TLB_LO0 # Clear entry low0.
|
|
MTC0 zero, COP_0_TLB_LO1 # Clear entry low1.
|
|
|
|
mtc0 a3, COP_0_TLB_INDEX # Set the index.
|
|
addiu a3, 1
|
|
li a2, 64
|
|
nop
|
|
nop
|
|
tlbwi # Write the TLB
|
|
|
|
bne a3, a2, 1b
|
|
nop
|
|
|
|
jr ra
|
|
nop
|
|
END(CPU_TLBClear)
|
|
|
|
/*
|
|
* Set up the TLB. Normally called from start.S.
|
|
*/
|
|
LEAF(CPU_TLBInit)
|
|
li a3, 0 # First TLB index.
|
|
|
|
li a2, PG_SIZE_16M
|
|
MTC0 a2, COP_0_TLB_PG_MASK # All pages are 16Mb.
|
|
|
|
1:
|
|
and a2, a0, PG_SVPN
|
|
MTC0 a2, COP_0_TLB_HI # Set up entry high.
|
|
|
|
move a2, a0
|
|
srl a2, a0, PG_SHIFT
|
|
and a2, a2, PG_FRAME
|
|
ori a2, PG_IOPAGE
|
|
MTC0 a2, COP_0_TLB_LO0 # Set up entry low0.
|
|
addu a2, (0x01000000 >> PG_SHIFT)
|
|
MTC0 a2, COP_0_TLB_LO1 # Set up entry low1.
|
|
|
|
mtc0 a3, COP_0_TLB_INDEX # Set the index.
|
|
addiu a3, 1
|
|
li a2, 0x02000000
|
|
subu a1, a2
|
|
nop
|
|
tlbwi # Write the TLB
|
|
|
|
bgtz a1, 1b
|
|
addu a0, a2 # Step address 32Mb.
|
|
|
|
jr ra
|
|
nop
|
|
END(CPU_TLBInit)
|
|
|
|
LEAF(stringserial)
|
|
move a2, ra
|
|
addu a1, a0, s0
|
|
lbu a0, 0(a1)
|
|
1:
|
|
beqz a0, 2f
|
|
nop
|
|
bal tgt_putchar
|
|
addiu a1, 1
|
|
b 1b
|
|
lbu a0, 0(a1)
|
|
|
|
2:
|
|
j a2
|
|
nop
|
|
END(stringserial)
|
|
|
|
LEAF(outstring)
|
|
move a2, ra
|
|
move a1, a0
|
|
lbu a0, 0(a1)
|
|
1:
|
|
beqz a0, 2f
|
|
nop
|
|
bal tgt_putchar
|
|
addiu a1, 1
|
|
b 1b
|
|
lbu a0, 0(a1)
|
|
|
|
2:
|
|
j a2
|
|
nop
|
|
END(outstring)
|
|
|
|
LEAF(hexserial)
|
|
move a2, ra
|
|
move a1, a0
|
|
li a3, 7
|
|
1:
|
|
rol a0, a1, 4
|
|
move a1, a0
|
|
and a0, 0xf
|
|
la v0, hexchar
|
|
addu v0, s0
|
|
addu v0, a0
|
|
bal tgt_putchar
|
|
lbu a0, 0(v0)
|
|
|
|
bnez a3, 1b
|
|
addu a3, -1
|
|
|
|
j a2
|
|
nop
|
|
END(hexserial)
|
|
|
|
LEAF(tgt_putchar)
|
|
la v0, COM1_BASE_ADDR
|
|
1:
|
|
lbu v1, NSREG(NS16550_LSR)(v0)
|
|
and v1, LSR_TXRDY
|
|
beqz v1, 1b
|
|
nop
|
|
|
|
sb a0, NSREG(NS16550_DATA)(v0)
|
|
j ra
|
|
nop
|
|
END(tgt_putchar)
|
|
|
|
LEAF(tgt_testchar)
|
|
la v0, COM1_BASE_ADDR
|
|
1:
|
|
lbu v1, NSREG(NS16550_LSR)(v0)
|
|
and v0,v1, LSR_RXRDY
|
|
jr ra
|
|
nop
|
|
END(tgt_testchar)
|
|
|
|
LEAF(tgt_getchar)
|
|
la v0, COM1_BASE_ADDR
|
|
1:
|
|
lbu v1, NSREG(NS16550_LSR)(v0)
|
|
and v1, LSR_RXRDY
|
|
beqz v1, 1b
|
|
nop
|
|
lb v0, NSREG(NS16550_DATA)(v0)
|
|
jr ra
|
|
nop
|
|
END(tgt_getchar)
|
|
|
|
|
|
/* baud rate definitions, matching include/termios.h */
|
|
#define B0 0
|
|
#define B50 50
|
|
#define B75 75
|
|
#define B110 110
|
|
#define B134 134
|
|
#define B150 150
|
|
#define B200 200
|
|
#define B300 300
|
|
#define B600 600
|
|
#define B1200 1200
|
|
#define B1800 1800
|
|
#define B2400 2400
|
|
#define B4800 4800
|
|
#define B9600 9600
|
|
#define B19200 19200
|
|
#define B38400 38400
|
|
#define B57600 57600
|
|
#define B115200 115200
|
|
|
|
LEAF(initserial)
|
|
la v0, COM1_BASE_ADDR
|
|
1:
|
|
li v1, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_4
|
|
sb v1, NSREG(NS16550_FIFO)(v0)
|
|
li v1, CFCR_DLAB
|
|
sb v1, NSREG(NS16550_CFCR)(v0)
|
|
li v1, NS16550HZ/(16*CONS_BAUD)
|
|
sb v1, NSREG(NS16550_DATA)(v0)
|
|
srl v1, 8
|
|
sb v1, NSREG(NS16550_IER)(v0)
|
|
li v1, CFCR_8BITS
|
|
sb v1, NSREG(NS16550_CFCR)(v0)
|
|
li v1, MCR_DTR|MCR_RTS
|
|
sb v1, NSREG(NS16550_MCR)(v0)
|
|
li v1, 0x0
|
|
sb v1, NSREG(NS16550_IER)(v0)
|
|
j ra
|
|
nop
|
|
END(initserial)
|
|
|
|
__main:
|
|
j ra
|
|
nop
|
|
|
|
|
|
.rdata
|
|
transmit_pat_msg:
|
|
.asciz "\r\nInvalid transmit pattern. Must be DDDD or DDxDDx\r\n"
|
|
v200_msg:
|
|
.asciz "\r\nPANIC! Unexpected TLB refill exception!\r\n"
|
|
v280_msg:
|
|
.asciz "\r\nPANIC! Unexpected XTLB refill exception!\r\n"
|
|
v380_msg:
|
|
.asciz "\r\nPANIC! Unexpected General exception!\r\n"
|
|
v400_msg:
|
|
.asciz "\r\nPANIC! Unexpected Interrupt exception!\r\n"
|
|
hexchar:
|
|
.ascii "0123456789abcdef"
|
|
|
|
.text
|
|
.align 2
|
|
/*
|
|
* I2C Functions used in early startup code to get SPD info from
|
|
* SDRAM modules. This code must be entirely PIC and RAM independent.
|
|
*/
|
|
|
|
/* Delay macro */
|
|
#define DELAY(count) \
|
|
li v0, count; \
|
|
99: \
|
|
bnz vo, 99b;\
|
|
addiu v0, -1
|
|
|
|
|
|
|
|
#define Index_Store_Tag_D 0x09
|
|
#define Index_Invalidate_I 0x00
|
|
#define Index_Writeback_Inv_D 0x01
|
|
|
|
LEAF(nullfunction)
|
|
jr ra
|
|
nop
|
|
END(nullfunction)
|
|
|
|
.ent cache_init
|
|
.global cache_init
|
|
.set noreorder
|
|
cache_init:
|
|
move t1,ra
|
|
####part 2####
|
|
cache_detect_4way:
|
|
mfc0 t4, CP0_CONFIG
|
|
andi t5, t4, 0x0e00
|
|
srl t5, t5, 9 #ic
|
|
andi t6, t4, 0x01c0
|
|
srl t6, t6, 6 #dc
|
|
addiu t8, $0, 1
|
|
addiu t9, $0, 2
|
|
#set dcache way
|
|
beq t6, $0, cache_d1way
|
|
addiu t7, $0, 1 #1 way
|
|
beq t6, t8, cache_d2way
|
|
addiu t7, $0, 2 #2 way
|
|
beq $0, $0, cache_d4way
|
|
addiu t7, $0, 4 #4 way
|
|
cache_d1way:
|
|
beq $0, $0, 1f
|
|
addiu t6, t6, 12 #1 way
|
|
cache_d2way:
|
|
beq $0, $0, 1f
|
|
addiu t6, t6, 11 #2 way
|
|
cache_d4way:
|
|
addiu t6, t6, 10 #4 way (10), 2 way(11), 1 way(12)
|
|
1: #set icache way
|
|
beq t5, $0, cache_i1way
|
|
addiu t3, $0, 1 #1 way
|
|
beq t5, t8, cache_i2way
|
|
addiu t3, $0, 2 #2 way
|
|
beq $0, $0, cache_i4way
|
|
addiu t3, $0, 4 #4 way
|
|
cache_i1way:
|
|
beq $0, $0, 1f
|
|
addiu t5, t5, 12
|
|
cache_i2way:
|
|
beq $0, $0, 1f
|
|
addiu t5, t5, 11
|
|
cache_i4way:
|
|
addiu t5, t5, 10 #4 way (10), 2 way(11), 1 way(12)
|
|
|
|
1: addiu t4, $0, 1
|
|
sllv t6, t4, t6
|
|
sllv t5, t4, t5
|
|
#if 0
|
|
la t0, memvar
|
|
sw t7, 0x0(t0) #ways
|
|
sw t5, 0x4(t0) #icache size
|
|
sw t6, 0x8(t0) #dcache size
|
|
#endif
|
|
####part 3####
|
|
.set mips3
|
|
lui a0, 0x8000
|
|
addu a1, $0, t5
|
|
addu a2, $0, t6
|
|
cache_init_d2way:
|
|
#a0=0x80000000, a1=icache_size, a2=dcache_size
|
|
#a3, v0 and v1 used as local registers
|
|
mtc0 $0, CP0_TAGHI
|
|
addu v0, $0, a0
|
|
addu v1, a0, a2
|
|
1: slt a3, v0, v1
|
|
beq a3, $0, 1f
|
|
nop
|
|
mtc0 $0, CP0_TAGLO
|
|
beq t7, 1, 4f
|
|
cache Index_Store_Tag_D, 0x0(v0) # 1 way
|
|
beq t7, 2 ,4f
|
|
cache Index_Store_Tag_D, 0x1(v0) # 2 way
|
|
cache Index_Store_Tag_D, 0x2(v0) # 4 way
|
|
cache Index_Store_Tag_D, 0x3(v0)
|
|
4: beq $0, $0, 1b
|
|
addiu v0, v0, 0x20
|
|
1:
|
|
cache_flush_i2way:
|
|
addu v0, $0, a0
|
|
addu v1, a0, a1
|
|
1: slt a3, v0, v1
|
|
beq a3, $0, 1f
|
|
nop
|
|
beq t3, 1, 4f
|
|
cache Index_Invalidate_I, 0x0(v0) # 1 way
|
|
beq t3, 2, 4f
|
|
cache Index_Invalidate_I, 0x1(v0) # 2 way
|
|
cache Index_Invalidate_I, 0x2(v0)
|
|
cache Index_Invalidate_I, 0x3(v0) # 4 way
|
|
4: beq $0, $0, 1b
|
|
addiu v0, v0, 0x20
|
|
1:
|
|
cache_flush_d2way:
|
|
addu v0, $0, a0
|
|
addu v1, a0, a2
|
|
1: slt a3, v0, v1
|
|
beq a3, $0, 1f
|
|
nop
|
|
beq t7, 1, 4f
|
|
cache Index_Writeback_Inv_D, 0x0(v0) #1 way
|
|
beq t7, 2, 4f
|
|
cache Index_Writeback_Inv_D, 0x1(v0) # 2 way
|
|
cache Index_Writeback_Inv_D, 0x2(v0)
|
|
cache Index_Writeback_Inv_D, 0x3(v0) # 4 way
|
|
4: beq $0, $0, 1b
|
|
addiu v0, v0, 0x20
|
|
.set mips0
|
|
1:
|
|
cache_init_finish:
|
|
jr t1
|
|
nop
|
|
.set reoreder
|
|
.end cache_init
|
|
|
|
|
|
|