Compare commits
2 Commits
uflash
...
mz-startup
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b0705e54ab | ||
|
|
459e3f09ea |
@@ -1,8 +1,9 @@
|
||||
#
|
||||
# Startup code for Microchip PIC32 microcontrollers.
|
||||
# Using HID bootloader.
|
||||
# Based on the MIPS application note:
|
||||
# "Boot-CPS: Example Boot Code for MIPS® Cores".
|
||||
#
|
||||
# Copyright (C) 2010 Serge Vakulenko, <serge@vak.ru>
|
||||
# Copyright (C) 2010-2014 Serge Vakulenko, <serge@vak.ru>
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software
|
||||
# and its documentation for any purpose and without fee is hereby
|
||||
@@ -26,6 +27,43 @@
|
||||
|
||||
#define UBASE 0x7f008000 /* User space base address */
|
||||
|
||||
/*
|
||||
* MIPS Coprocessor 0 register numbers
|
||||
*/
|
||||
#define C0_INDEX $0
|
||||
#define C0_ENTRYLO0 $2
|
||||
#define C0_ENTRYLO1 $3
|
||||
#define C0_PAGEMASK $5
|
||||
#define C0_WIRED $6
|
||||
#define C0_COUNT $9
|
||||
#define C0_ENTRYHI $10
|
||||
#define C0_COMPARE $11
|
||||
#define C0_STATUS $12
|
||||
#define C0_SRSCTL $12,2
|
||||
#define C0_CAUSE $13
|
||||
#define C0_EPC $14
|
||||
#define C0_CONFIG $16
|
||||
#define C0_CONFIG1 $16,1
|
||||
#define C0_CONFIG7 $16,7
|
||||
#define C0_WATCHLO $18
|
||||
#define C0_WATCHHI $19
|
||||
#define C0_DEBUG $23
|
||||
#define C0_DEPC $24
|
||||
#define C0_ITAGLO $28
|
||||
#define C0_DTAGLO $28,2
|
||||
#define C0_ERRPC $30
|
||||
|
||||
/*
|
||||
* MIPS Config1 register
|
||||
*/
|
||||
#define CFG1_MMUSSHIFT 25 // mmu size - 1
|
||||
#define CFG1_ISSHIFT 22 // icache lines 64<<n
|
||||
#define CFG1_ILSHIFT 19 // icache line size 2<<n
|
||||
#define CFG1_IASHIFT 16 // icache ways - 1
|
||||
#define CFG1_DSSHIFT 13 // dcache lines 64<<n
|
||||
#define CFG1_DLSHIFT 10 // dcache line size 2<<n
|
||||
#define CFG1_DASHIFT 7 // dcache ways - 1
|
||||
|
||||
.set noreorder
|
||||
.set mips32r2
|
||||
.set nomips16
|
||||
@@ -45,52 +83,279 @@
|
||||
_reset_vector_: .globl _reset_vector_
|
||||
|
||||
.set noat
|
||||
move $1, $zero # Clear all regs
|
||||
move $2, $zero
|
||||
move $3, $zero
|
||||
move $4, $zero
|
||||
move $5, $zero
|
||||
move $6, $zero
|
||||
move $7, $zero
|
||||
move $8, $zero
|
||||
move $9, $zero
|
||||
move $10, $zero
|
||||
move $11, $zero
|
||||
move $12, $zero
|
||||
move $13, $zero
|
||||
move $14, $zero
|
||||
move $15, $zero
|
||||
move $16, $zero
|
||||
move $17, $zero
|
||||
move $18, $zero
|
||||
move $19, $zero
|
||||
move $20, $zero
|
||||
move $21, $zero
|
||||
move $22, $zero
|
||||
move $23, $zero
|
||||
move $24, $zero
|
||||
move $25, $zero
|
||||
move $26, $zero
|
||||
move $27, $zero
|
||||
move $28, $zero
|
||||
move $29, $zero
|
||||
move $30, $zero
|
||||
move $31, $zero
|
||||
mtlo $zero
|
||||
mthi $zero
|
||||
.set at
|
||||
mtc0 $0, C0_COUNT # Clear cp0 Count (Used to measure boot time.)
|
||||
#if 0
|
||||
//
|
||||
// Check for NMI exception.
|
||||
//
|
||||
check_nmi: # Check whether we are here due to a reset or NMI.
|
||||
mfc0 $s1, C0_STATUS # Read Status
|
||||
ext $s1, $s1, 19, 1 # extract NMI
|
||||
beqz $s1, init_gpr # Branch if this is NOT an NMI exception.
|
||||
nop
|
||||
|
||||
# Call nmi_exception().
|
||||
la $sp, _stack-16 # Set up stack base.
|
||||
la $gp, _gp # GP register value defined by linker script.
|
||||
la $s1, nmi_exception # Call user-defined NMI handler.
|
||||
jalr $s1
|
||||
nop
|
||||
#endif
|
||||
//
|
||||
// Set all GPRs of all register sets to predefined state.
|
||||
//
|
||||
init_gpr:
|
||||
li $1, 0xdeadbeef # 0xdeadbeef stands out, kseg2 mapped, odd.
|
||||
|
||||
# Determine how many shadow sets are implemented (in addition to the base register set.)
|
||||
# the first time thru the loop it will initialize using $1 set above.
|
||||
# At the bottom og the loop, 1 is subtract from $30
|
||||
# and loop back to next_shadow_set to start the next loop and the next lowest set number.
|
||||
mfc0 $29, C0_SRSCTL # read SRSCtl
|
||||
ext $30, $29, 26, 4 # extract HSS
|
||||
|
||||
next_shadow_set: # set PSS to shadow set to be initialized
|
||||
ins $29, $30, 6, 4 # insert PSS
|
||||
mtc0 $29, C0_SRSCTL # write SRSCtl
|
||||
|
||||
wrpgpr $1, $1
|
||||
wrpgpr $2, $1
|
||||
wrpgpr $3, $1
|
||||
wrpgpr $4, $1
|
||||
wrpgpr $5, $1
|
||||
wrpgpr $6, $1
|
||||
wrpgpr $7, $1
|
||||
wrpgpr $8, $1
|
||||
wrpgpr $9, $1
|
||||
wrpgpr $10, $1
|
||||
wrpgpr $11, $1
|
||||
wrpgpr $12, $1
|
||||
wrpgpr $13, $1
|
||||
wrpgpr $14, $1
|
||||
wrpgpr $15, $1
|
||||
wrpgpr $16, $1
|
||||
wrpgpr $17, $1
|
||||
wrpgpr $18, $1
|
||||
wrpgpr $19, $1
|
||||
wrpgpr $20, $1
|
||||
wrpgpr $21, $1
|
||||
wrpgpr $22, $1
|
||||
wrpgpr $23, $1
|
||||
wrpgpr $24, $1
|
||||
wrpgpr $25, $1
|
||||
wrpgpr $26, $1
|
||||
wrpgpr $27, $1
|
||||
wrpgpr $28, $1
|
||||
beqz $30, init_cp0
|
||||
wrpgpr $29, $1
|
||||
|
||||
wrpgpr $30, $1
|
||||
wrpgpr $31, $1
|
||||
b next_shadow_set
|
||||
add $30, -1 # Decrement to the next lower number
|
||||
|
||||
//
|
||||
// Init CP0 Status, Count, Compare, Watch*, and Cause.
|
||||
//
|
||||
init_cp0:
|
||||
# Initialize Status
|
||||
li $v1, 0x00400404 # (M_StatusIM | M_StatusERL | M_StatusBEV)
|
||||
mtc0 $v1, C0_STATUS # write Status
|
||||
|
||||
# Initialize Watch registers if implemented.
|
||||
mfc0 $v0, C0_CONFIG1 # read Config1
|
||||
ext $v1, $v0, 3, 1 # extract bit 3 WR (Watch registers implemented)
|
||||
beq $v1, $zero, done_wr
|
||||
li $v1, 0x7 # (M_WatchHiI | M_WatchHiR | M_WatchHiW)
|
||||
|
||||
# Clear Watch Status bits and disable watch exceptions
|
||||
mtc0 $v1, C0_WATCHHI # write WatchHi0
|
||||
mfc0 $v0, C0_WATCHHI # read WatchHi0
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO # clear WatchLo0
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 1 # write WatchHi1
|
||||
mfc0 $v0, C0_WATCHHI, 1 # read WatchHi1
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 1 # clear WatchLo1
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 2 # write WatchHi2
|
||||
mfc0 $v0, C0_WATCHHI, 2 # read WatchHi2
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 2 # clear WatchLo2
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 3 # write WatchHi3
|
||||
mfc0 $v0, C0_WATCHHI, 3 # read WatchHi3
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 3 # clear WatchLo3
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 4 # write WatchHi4
|
||||
mfc0 $v0, C0_WATCHHI, 4 # read WatchHi4
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 4 # clear WatchLo4
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 5 # write WatchHi5
|
||||
mfc0 $v0, C0_WATCHHI, 5 # read WatchHi5
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 5 # clear WatchLo5
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 6 # write WatchHi6
|
||||
mfc0 $v0, C0_WATCHHI, 6 # read WatchHi6
|
||||
bgez $v0, done_wr # Check for bit 31 (sign bit) for more Watch registers
|
||||
mtc0 $zero, C0_WATCHLO, 6 # clear WatchLo6
|
||||
|
||||
mtc0 $v1, C0_WATCHHI, 7 # write WatchHi7
|
||||
mtc0 $zero, C0_WATCHLO, 7 # clear WatchLo7
|
||||
|
||||
done_wr:
|
||||
# Clear WP bit to avoid watch exception upon user code entry, IV, and software interrupts.
|
||||
mtc0 $zero, C0_CAUSE # clear Cause: init AFTER init of WatchHi/Lo registers.
|
||||
|
||||
# Clear timer interrupt. (Count was cleared at the reset vector to allow timing boot.)
|
||||
b init_tlb # Jump over exception vectors
|
||||
mtc0 $zero, C0_COMPARE # clear Compare
|
||||
|
||||
//
|
||||
// Clear TLB: generate unique EntryHi contents per entry pair.
|
||||
//
|
||||
init_tlb:
|
||||
# Determine if we have a TLB
|
||||
mfc0 $v1, C0_CONFIG # read Config
|
||||
ext $v1, $v1, 7, 3 # extract MT field
|
||||
li $a3, 0x1 # load a 1 to check against
|
||||
bne $v1, $a3, init_icache
|
||||
|
||||
# Config1MMUSize == Number of TLB entries - 1
|
||||
mfc0 $v0, C0_CONFIG1 # Config1
|
||||
ext $v1, $v0, CFG1_MMUSSHIFT, 6 # extract MMU Size
|
||||
mtc0 $zero, C0_ENTRYLO0 # clear EntryLo0
|
||||
mtc0 $zero, C0_ENTRYLO1 # clear EntryLo1
|
||||
mtc0 $zero, C0_PAGEMASK # clear PageMask
|
||||
mtc0 $zero, C0_WIRED # clear Wired
|
||||
li $a0, 0x80000000
|
||||
|
||||
next_tlb_entry:
|
||||
mtc0 $v1, C0_INDEX # write Index
|
||||
mtc0 $a0, C0_ENTRYHI # write EntryHi
|
||||
ehb
|
||||
tlbwi
|
||||
add $a0, 2<<13 # Add 8K to the address to avoid TLB conflict with previous entry
|
||||
|
||||
bne $v1, $zero, next_tlb_entry
|
||||
add $v1, -1
|
||||
|
||||
//
|
||||
// Clear L1 instruction cache.
|
||||
//
|
||||
init_icache:
|
||||
# Determine how big the I-cache is
|
||||
mfc0 $v0, C0_CONFIG1 # read Config1
|
||||
ext $v1, $v0, CFG1_ILSHIFT, 3 # extract I-cache line size
|
||||
beq $v1, $zero, done_icache # Skip ahead if no I-cache
|
||||
nop
|
||||
|
||||
mfc0 $s1, C0_CONFIG7 # Read Config7
|
||||
ext $s1, $s1, 18, 1 # extract HCI
|
||||
bnez $s1, done_icache # Skip when Hardware Cache Initialization bit set
|
||||
|
||||
li $a2, 2
|
||||
sllv $v1, $a2, $v1 # Now have true I-cache line size in bytes
|
||||
|
||||
ext $a0, $v0, CFG1_ISSHIFT, 3 # extract IS
|
||||
li $a2, 64
|
||||
sllv $a0, $a2, $a0 # I-cache sets per way
|
||||
|
||||
ext $a1, $v0, CFG1_IASHIFT, 3 # extract I-cache Assoc - 1
|
||||
add $a1, 1
|
||||
mul $a0, $a0, $a1 # Total number of sets
|
||||
lui $a2, 0x8000 # Get a KSeg0 address for cacheops
|
||||
|
||||
mtc0 $zero, C0_ITAGLO # Clear ITagLo register
|
||||
move $a3, $a0
|
||||
|
||||
next_icache_tag:
|
||||
# Index Store Tag Cache Op
|
||||
# Will invalidate the tag entry, clear the lock bit, and clear the LRF bit
|
||||
cache 0x8, 0($a2) # ICIndexStTag
|
||||
add $a3, -1 # Decrement set counter
|
||||
bne $a3, $zero, next_icache_tag
|
||||
add $a2, $v1 # Get next line address
|
||||
done_icache:
|
||||
|
||||
//
|
||||
// Enable cacheability of kseg0 segment.
|
||||
// Need to switch to kseg1, modify kseg0 CCA, then switch back.
|
||||
//
|
||||
la $a2, enable_k0_cache
|
||||
li $a1, 0xf
|
||||
ins $a2, $a1, 29, 1 # changed to KSEG1 address by setting bit 29
|
||||
jr $a2
|
||||
nop
|
||||
|
||||
enable_k0_cache:
|
||||
# Set CCA for kseg0 to cacheable.
|
||||
# NOTE! This code must be executed in KSEG1 (not KSEG0 uncached)
|
||||
mfc0 $v0, C0_CONFIG # read C0_Config
|
||||
li $v1, 3 # CCA for single-core processors
|
||||
ins $v0, $v1, 0, 3 # instert K0
|
||||
mtc0 $v0, C0_CONFIG # write C0_Config
|
||||
|
||||
la $a2, init_dcache
|
||||
jr $a2 # switch back to KSEG0
|
||||
ehb
|
||||
|
||||
//
|
||||
// Initialize the L1 data cache
|
||||
//
|
||||
init_dcache:
|
||||
mfc0 $v0, C0_CONFIG1 # read C0_Config1
|
||||
ext $v1, $v0, CFG1_DLSHIFT, 3 # extract D-cache line size
|
||||
beq $v1, $zero, done_dcache # Skip ahead if no D-cache
|
||||
nop
|
||||
|
||||
mfc0 $s1, C0_CONFIG7 # Read Config7
|
||||
ext $s1, $s1, 18, 1 # extract HCI
|
||||
bnez $s1, done_dcache # Skip when Hardware Cache Initialization bit set
|
||||
|
||||
li $a2, 2
|
||||
sllv $v1, $a2, $v1 # Now have true D-cache line size in bytes
|
||||
|
||||
ext $a0, $v0, CFG1_DSSHIFT, 3 # extract DS
|
||||
li $a2, 64
|
||||
sllv $a0, $a2, $a0 # D-cache sets per way
|
||||
|
||||
ext $a1, $v0, CFG1_DASHIFT, 3 # extract D-cache Assoc - 1
|
||||
add $a1, 1
|
||||
mul $a0, $a0, $a1 # Get total number of sets
|
||||
lui $a2, 0x8000 # Get a KSeg0 address for cacheops
|
||||
|
||||
mtc0 $zero, C0_ITAGLO # Clear ITagLo/DTagLo registers
|
||||
mtc0 $zero, C0_DTAGLO
|
||||
move $a3, $a0
|
||||
|
||||
next_dcache_tag:
|
||||
# Index Store Tag Cache Op
|
||||
# Will invalidate the tag entry, clear the lock bit, and clear the LRF bit
|
||||
cache 0x9, 0($a2) # DCIndexStTag
|
||||
add $a3, -1 # Decrement set counter
|
||||
bne $a3, $zero, next_dcache_tag
|
||||
add $a2, $v1 # Get next line address
|
||||
done_dcache:
|
||||
|
||||
//
|
||||
// Call main() function.
|
||||
//
|
||||
la $sp, u_end - 16 # Stack at end of U area
|
||||
la $a0, main
|
||||
jalr $a0 # Jump to main()
|
||||
lui $gp, 0x8000 # Set global pointer (delay slot)
|
||||
|
||||
la $k0, UBASE
|
||||
mtc0 $k0, $C0_EPC # Entry to user code.
|
||||
mtc0 $k0, C0_EPC # Entry to user code.
|
||||
|
||||
mfc0 $k0, $C0_STATUS
|
||||
mfc0 $k0, C0_STATUS
|
||||
ori $k0, $k0, ST_UM | ST_EXL | ST_IE # Set user mode and enable interrupts
|
||||
mtc0 $k0, $C0_STATUS # Put SR back
|
||||
mtc0 $k0, C0_STATUS # Put SR back
|
||||
ehb
|
||||
eret # PC <= EPC; EXL <= 0
|
||||
nop # just to be safe
|
||||
@@ -116,7 +381,7 @@ _entry_vector_: .globl _entry_vector_
|
||||
.type _exception_vector_, @function
|
||||
_exception_vector_: .globl _exception_vector_
|
||||
|
||||
mfc0 $k0, $C0_STATUS
|
||||
mfc0 $k0, C0_STATUS
|
||||
andi $k1, $k0, ST_UM # Check user mode
|
||||
beqz $k1, kernel_exception
|
||||
move $k1, $sp
|
||||
@@ -172,7 +437,7 @@ save_regs:
|
||||
mflo $k0
|
||||
sw $k0, (16+FRAME_LO*4) ($sp)
|
||||
|
||||
mfc0 $k0, $C0_EPC
|
||||
mfc0 $k0, C0_EPC
|
||||
sw $k0, (16+FRAME_PC*4) ($sp)
|
||||
|
||||
move $a0, $sp
|
||||
@@ -225,11 +490,11 @@ restore_regs:
|
||||
# Do not use k0/k1 here, as interrupts are still enabled
|
||||
lw $31, (16+FRAME_STATUS*4) ($sp) # K0 = saved status
|
||||
ori $31, ST_EXL # Set EXL
|
||||
mtc0 $31, $C0_STATUS # put SR back: disable interrupts
|
||||
mtc0 $31, C0_STATUS # put SR back: disable interrupts
|
||||
ehb
|
||||
|
||||
lw $k0, (16+FRAME_PC*4) ($sp) # K0 = EPC
|
||||
mtc0 $k0, $C0_EPC # put PC in EPC
|
||||
mtc0 $k0, C0_EPC # put PC in EPC
|
||||
ext $k1, $31, 27, 1 # get RP bit: single-step request
|
||||
|
||||
lw $31, (16+FRAME_RA*4) ($sp)
|
||||
@@ -249,39 +514,39 @@ debug_request:
|
||||
.type _debug_vector_, @function
|
||||
_debug_vector_: .globl _debug_vector_
|
||||
|
||||
mfc0 $k0, $C0_DEPC
|
||||
mfc0 $k0, C0_DEPC
|
||||
la $k1, debug_request
|
||||
bne $k0, $k1, single_step_done
|
||||
nop
|
||||
|
||||
# single step request
|
||||
mfc0 $k0, $C0_DEBUG
|
||||
mfc0 $k0, C0_DEBUG
|
||||
ori $k0, DB_SST # set SST bit
|
||||
mtc0 $k0, $C0_DEBUG
|
||||
mtc0 $k0, C0_DEBUG
|
||||
|
||||
mfc0 $k1, $C0_EPC
|
||||
mtc0 $k1, $C0_DEPC # DEPC <= EPC
|
||||
mfc0 $k0, $C0_STATUS
|
||||
mfc0 $k1, C0_EPC
|
||||
mtc0 $k1, C0_DEPC # DEPC <= EPC
|
||||
mfc0 $k0, C0_STATUS
|
||||
xori $k0, ST_EXL # Clear EXL
|
||||
mtc0 $k0, $C0_STATUS
|
||||
mtc0 $k0, C0_STATUS
|
||||
ehb
|
||||
deret # PC <= DEPC; DM <= 0
|
||||
|
||||
single_step_done:
|
||||
mtc0 $k0, $C0_EPC # EPC <= DEPC
|
||||
mtc0 $k0, C0_EPC # EPC <= DEPC
|
||||
|
||||
la $k1, _exception_vector_
|
||||
mtc0 $k1, $C0_DEPC # DEPC <= exception handler
|
||||
mtc0 $k1, C0_DEPC # DEPC <= exception handler
|
||||
|
||||
mfc0 $k0, $C0_DEBUG
|
||||
mfc0 $k0, C0_DEBUG
|
||||
sw $k0, c0_debug # save Debug register
|
||||
ori $k0, DB_SST
|
||||
xori $k0, DB_SST # clear SST bit
|
||||
mtc0 $k0, $C0_DEBUG
|
||||
mtc0 $k0, C0_DEBUG
|
||||
|
||||
mfc0 $k1, $C0_STATUS
|
||||
mfc0 $k1, C0_STATUS
|
||||
ori $k1, ST_EXL # Set EXL
|
||||
mtc0 $k1, $C0_STATUS
|
||||
mtc0 $k1, C0_STATUS
|
||||
ehb
|
||||
deret # PC <= DEPC; DM <= 0
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
/*--------------------------------------
|
||||
* Coprocessor 0 registers.
|
||||
*/
|
||||
#ifndef __ASSEMBLER__
|
||||
#define C0_HWRENA 7 /* Enable RDHWR in non-privileged mode */
|
||||
#define C0_BADVADDR 8 /* Virtual address of last exception */
|
||||
#define C0_COUNT 9 /* Processor cycle count */
|
||||
@@ -47,6 +48,7 @@
|
||||
#define C0_DEPC 24 /* Program counter at last debug exception */
|
||||
#define C0_ERROREPC 30 /* Program counter at last error */
|
||||
#define C0_DESAVE 31 /* Debug handler scratchpad register */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Status register.
|
||||
|
||||
@@ -1684,7 +1684,8 @@ static int rdpgpr_op (cpu_mips_t * cpu, mips_insn_t insn)
|
||||
int rt = bits (insn, 16, 20);
|
||||
int rd = bits (insn, 11, 15);
|
||||
|
||||
printf ("%08x: unsupported RDPGPR $%u,$%u instruction.\n", cpu->pc, rd, rt);
|
||||
/* Only one GPR set supported: RDPGPR works as move. */
|
||||
cpu->reg_set (cpu, rd, cpu->gpr[rt]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -1693,7 +1694,8 @@ static int wrpgpr_op (cpu_mips_t * cpu, mips_insn_t insn)
|
||||
int rt = bits (insn, 16, 20);
|
||||
int rd = bits (insn, 11, 15);
|
||||
|
||||
printf ("%08x: unsupported WRPGPR $%u,$%u instruction.\n", cpu->pc, rd, rt);
|
||||
/* Only one GPR set supported: WRPGPR works as move. */
|
||||
cpu->reg_set (cpu, rd, cpu->gpr[rt]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ unimpl: fprintf (stderr,
|
||||
return cp0->reg[cp0_reg];
|
||||
case 1: /* IntCtl */
|
||||
return cp0->intctl_reg;
|
||||
case 2: /* SRSCtl */
|
||||
return 0;
|
||||
}
|
||||
goto unimpl;
|
||||
|
||||
@@ -172,6 +174,8 @@ void mips_cp0_set_reg (cpu_mips_t * cpu, u_int cp0_reg, u_int sel,
|
||||
case 1: /* IntCtl */
|
||||
cp0->intctl_reg = val;
|
||||
break;
|
||||
case 2: /* SRSCtl */
|
||||
break;
|
||||
default:
|
||||
goto unimpl;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user